home *** CD-ROM | disk | FTP | other *** search
- ;;;
- ;;; Copyright (c) 1985 Massachusetts Institute of Technology
- ;;;
- ;;; This material was developed by the Scheme project at the
- ;;; Massachusetts Institute of Technology, Department of
- ;;; Electrical Engineering and Computer Science. Permission to
- ;;; copy this software, to redistribute it, and to use it for any
- ;;; purpose is granted, subject to the following restrictions and
- ;;; understandings.
- ;;;
- ;;; 1. Any copy made of this software must include this copyright
- ;;; notice in full.
- ;;;
- ;;; 2. Users of this software agree to make their best efforts (a)
- ;;; to return to the MIT Scheme project any improvements or
- ;;; extensions that they make, so that these may be included in
- ;;; future releases; and (b) to inform MIT of noteworthy uses of
- ;;; this software.
- ;;;
- ;;; 3. All materials developed as a consequence of the use of
- ;;; this software shall duly acknowledge such use, in accordance
- ;;; with the usual standards of acknowledging credit in academic
- ;;; research.
- ;;;
- ;;; 4. MIT has made no warrantee or representation that the
- ;;; operation of this software will be error-free, and MIT is
- ;;; under no obligation to provide any services, by way of
- ;;; maintenance, update, or otherwise.
- ;;;
- ;;; 5. In conjunction with products arising from the use of this
- ;;; material, there shall be no use of the name of the
- ;;; Massachusetts Institute of Technology nor of any adaptation
- ;;; thereof in any advertising, promotional, or sales literature
- ;;; without prior written consent from MIT in each case.
- ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;
- ;;; Modified by Texas Instruments Inc 8/15/85
- ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;;;; Region Operations
-
- ;;;; String <-> Region
-
- (define (string->region string)
- (substring->region string 0 (string-length string)))
-
- (define (substring->region string start end)
- (let ((nl (substring-find-next-char string start end #\Newline)))
- (if (not nl)
- (let ((line (make-line (substring string start end))))
- (lines->region line line))
- (let ((first-line (make-line (substring string start nl)))
- (group (make-group #F)))
- (define (loop previous-line n start)
- (let ((nl (substring-find-next-char string start end #\Newline)))
- (if (not nl)
- (let ((last-line (make-line (substring string start end))))
- (connect-lines! previous-line last-line)
- (set-line-group! last-line group)
- (set-line-number! last-line n)
- (let ((region
- (components->region first-line 0 last-line
- (line-length last-line))))
- (%set-group-region! group region)
- region))
- (let ((this-line (make-line (substring string start nl))))
- (connect-lines! previous-line this-line)
- (set-line-group! this-line group)
- (set-line-number! this-line n)
- (loop this-line (+ n line-number-increment) (1+ nl))))))
- (set-line-group! first-line group)
- (set-line-number! first-line 0)
- (loop first-line line-number-increment (1+ nl))))))
-
- (define (region->string region)
- (region-components region
- (lambda (start-line start-position end-line end-position)
- (if (eq? start-line end-line)
- (substring (line-string start-line) start-position end-position)
- (let ((result (string-allocate (region-count-chars region))))
- (define (loop target line)
- (string-set! result target #\Newline)
- (if (eq? line end-line)
- (substring-move-right! (line-string end-line) 0 end-position
- result (1+ target))
- (begin (substring-move-right! (line-string line) 0
- (line-length line)
- result (1+ target))
- (loop (+ target (line-length line) 1)
- (line-next line)))))
- (substring-move-right! (line-string start-line) start-position
- (line-length start-line) result 0)
- (loop (- (line-length start-line) start-position)
- (line-next start-line))
- result)))))
-
- ;;;; Copy Region
-
- (define (region-copy region)
- (region-components region
- (lambda (start-line start-position end-line end-position)
- (if (eq? start-line end-line)
- (let ((line (subline start-line start-position end-position)))
- (lines->region line line))
- (let ((new-start (subline start-line
- start-position
- (line-length start-line)))
- (group (make-group #F)))
- (define (loop this-line n new-previous)
- (if (eq? this-line end-line)
- (let ((new-end (subline end-line 0 end-position)))
- (connect-lines! new-previous new-end)
- (set-line-group! new-end group)
- (set-line-number! new-end n)
- (let ((region
- (components->region new-start 0
- new-end (line-length new-end))))
- (%set-group-region! group region)
- region))
- (let ((new-this (line-copy this-line)))
- (connect-lines! new-previous new-this)
- (set-line-group! new-this group)
- (set-line-number! new-this n)
- (loop (line-next this-line)
- (+ n line-number-increment)
- new-this))))
- (set-line-group! new-start group)
- (set-line-number! new-start 0)
- (loop (line-next start-line)
- line-number-increment
- new-start))))))
-
- ;;;; Extract Region
-
- (define (region-extract! region)
- (let ((sync (region-delete-starting! region)))
- (let ((extracted-region (region-components region %region-extract!)))
- (sync extracted-region)
- extracted-region)))
-
- (define %region-extract!
- (letrec
- ((%start-pos '())
- (%end-pos '())
- (%offset '())
- (%new-line '())
- (%receiver1
- (lambda (mark cursor?)
- (cond ((> (mark-position mark) %end-pos)
- (set-mark-position! mark (- (mark-position mark) %offset)))
- ((> (mark-position mark) %start-pos)
- (set-mark-position! mark %start-pos)))))
-
- (%receiver2
- (lambda (mark cursor?)
- ((if cursor? %set-mark-line! set-mark-line!) mark %new-line)
- (set-mark-position! mark
- (if (> (mark-position mark) %end-pos)
- (- (mark-position mark) %offset)
- %start-pos))))
-
- (%receiver3
- (lambda (mark cursor?)
- ((if cursor? %set-mark-line! set-mark-line!) mark %new-line)
- (set-mark-position! mark %start-pos)))
-
- (%receiver4
- (lambda (mark cursor?)
- ((if cursor? %set-mark-line! set-mark-line!) mark %new-line)
- (if (> (mark-position mark) %start-pos)
- (set-mark-position! mark %start-pos)))))
-
- (lambda (start-line start-pos end-line end-pos)
- (letrec
- ((move-marks!
- (lambda (line)
- (if (eq? line end-line)
- (for-each-mark! end-line %receiver2)
- (begin (for-each-mark! line %receiver3)
- (move-marks! (line-next line)))))))
- (set! %start-pos start-pos)
- (set! %end-pos end-pos)
- (if (eq? start-line end-line)
- (let ((offset (- end-pos start-pos)))
- (set! %offset offset)
- (for-each-mark! start-line %receiver1)
- (let ((line (subline-extract! start-line start-pos end-pos)))
- (lines->region line line)))
- (let ((new-line (line-extract! start-line start-pos end-line end-pos))
- (offset (- end-pos start-pos))
- (start-previous (line-previous start-line))
- (end-next (line-next end-line)))
- (set! %new-line new-line)
- (set! %offset offset)
- (for-each-mark! start-line %receiver4)
- (move-marks! (line-next start-line))
- (set-line-group! new-line (line-group start-line))
- (set! %new-line '())
- (disconnect-lines! start-line end-line)
- (connect-lines! start-previous new-line)
- (connect-lines! new-line end-next)
- (number-lines! new-line new-line)
- (lines->region start-line end-line)))))))
-
- ;;;; Insert Region
-
- (define (region-insert! mark region)
- (let ((sync (region-insert-starting! mark)))
- (let ((region*
- (region-components region
- (lambda (start-line start-pos end-line end-pos)
- ((lambda (line pos)
- (%region-insert! line pos
- start-line start-pos
- end-line end-pos))
- (mark-line mark) (mark-position mark) )))))
- (sync region*)
- region*)))
-
- (define %region-insert!
- (letrec
- ((%pos '())
- (%offset '())
- (%end-line '())
- (%end-pos '())
- (%receiver1
- (lambda (mark cursor?)
- (if (or (> (mark-position mark) %pos)
- (and (= (mark-position mark) %pos)
- (mark-left-inserting? mark)))
- (set-mark-position! mark (+ (mark-position mark) %offset)))))
-
- (%receiver2
- (lambda (mark cursor?)
- (cond ((> (mark-position mark) %pos)
- ((if cursor? %set-mark-line! set-mark-line!) mark %end-line)
- (set-mark-position! mark (+ (mark-position mark) %offset)))
- ((and (= (mark-position mark) %pos)
- (mark-left-inserting? mark))
- ((if cursor? %set-mark-line! set-mark-line!) mark %end-line)
- (set-mark-position! mark %end-pos))))))
-
- (lambda (line pos start-line start-pos end-line end-pos)
- (set! %pos pos)
- (if (eq? start-line end-line)
- (let ((offset (- end-pos start-pos)))
- (set! %offset offset)
- (for-each-mark! line %receiver1)
- (line-insert! line pos start-line start-pos end-pos)
- (%make-region (%make-mark line pos #F)
- (%make-mark line (+ pos offset) #T)))
- (let ((offset (- end-pos pos)))
- (set! %end-line end-line)
- (set! %offset offset)
- (set! %end-pos end-pos)
- (for-each-mark! line %receiver2)
- (line-splice! line pos start-line start-pos end-line end-pos)
- (set! %end-line '())
- (connect-lines! end-line (line-next line))
- (connect-lines! line (line-next start-line))
- (number-lines! (line-next line) end-line)
- (%make-region (%make-mark line pos #F)
- (%make-mark end-line end-pos #T)))))))
-
- ;;; These are overwritten by the routines in insertch.scm
- ;;;(define (region-insert-char! mark char)
- ;;; (if (char= char #\Newline)
- ;;; (region-insert-newline! mark)
- ;;; (let ((sync (region-insert-starting! mark)))
- ;;; (let ((region (mark-components mark
- ;;; (lambda (line pos)
- ;;; (%region-insert-char! line pos char)))))
- ;;; (sync region)
- ;;; region))))
- ;;;
- ;;;(define (%region-insert-char! line pos char)
- ;;; (for-each-mark! line
- ;;; (lambda (mark)
- ;;; (if (or (> (mark-position mark) pos)
- ;;; (and (= (mark-position mark) pos)
- ;;; (mark-left-inserting? mark)))
- ;;; (set-mark-position! mark (1+ (mark-position mark))))))
- ;;; (line-insert-char! line pos char)
- ;;; (%make-region (%make-mark line pos #F)
- ;;; (%make-mark line (1+ pos) #T)))
- ;;;
- (define (region-insert-newline! mark)
- (let ((sync (region-insert-starting! mark)))
- (let ((region
- ((lambda (line pos)
- (%region-insert-newline! line pos))
- (mark-line mark) (mark-position mark))))
- (sync region)
- region)))
-
- (define %region-insert-newline!
- (letrec
- ((%pos '())
- (%new-next '())
- (%receiver
- (lambda (mark cursor?)
- (cond ((> (mark-position mark) %pos)
- ((if cursor? %set-mark-line! set-mark-line!) mark %new-next)
- (set-mark-position! mark (- (mark-position mark) %pos)))
- ((and (= (mark-position mark) %pos)
- (mark-left-inserting? mark))
- ((if cursor? %set-mark-line! set-mark-line!) mark %new-next)
- (set-mark-position! mark 0))))))
-
- (lambda (line pos)
- (let ((new-next (subline-extract! line pos (line-length line))))
- (set! %pos pos)
- (set! %new-next new-next)
- (for-each-mark! line %receiver)
- (set! %new-next '())
- (connect-lines! new-next (line-next line))
- (connect-lines! line new-next)
- (number-lines! new-next new-next)
- (%make-region (%make-mark line (line-length line) #F)
- (%make-mark new-next 0 #T))))))
-
- ;;; This should be implemented later for speed.
- (define region-delete!
- region-extract!)
-
- (define (region-insert mark region)
- (region-insert! mark (region-copy region)))
-
- (define (region-insert-string! mark string)
- (region-insert! mark (string->region string)))
-
-
- ;;;; Line String Operations
-
- (define (subline line start end)
- (make-line (substring (line-string line) start end)))
-
- (define (line-copy line)
- (make-line (line-string line)))
-
- (define (subline-extract! line start end)
- (let ((new-line (subline line start end)))
- (set-line-string! line (string-delete (line-string line) start end))
- new-line))
-
- (define (line-extract! start-line start-pos end-line end-pos)
- (let ((start-string (line-string start-line))
- (end-string (line-string end-line)))
- (let ((AD (substring-append start-string 0 start-pos
- end-string end-pos (string-length end-string)))
- (B (substring start-string start-pos (string-length start-string)))
- (C (substring end-string 0 end-pos)))
- (set-line-string! start-line B)
- (set-line-string! end-line C)
- (make-line AD))))
-
- (define (line-insert! line1 start1 line2 start2 end2)
- (set-line-string!
- line1
- (string-insert-substring (line-string line1) start1
- (line-string line2) start2 end2)))
-
- (define (line-insert-char! line start char)
- (set-line-string!
- line
- (let ((string (line-string line)))
- (%string-append string 0 start
- char
- string start (string-length string)))))
-
- (define (line-splice! line1 position1 line2 position2 line3 position3)
- (let ((string1 (line-string line1))
- (string2 (line-string line2))
- (string3 (line-string line3)))
- (set-line-string! line1
- (substring-append string1 0 position1
- string2
- position2
- (string-length string2)))
- (set-line-string! line3
- (substring-append string3 0 position3
- string1
- position1
- (string-length string1)))))
-
- (define (mark-left-char mark)
- (cond ((group-start? mark)
- (error "No left character" mark))
- ((line-start? mark)
- #\Newline)
- (else
- (string-ref (line-string (mark-line mark))
- (-1+ (mark-position mark))))))
-
- (define (mark-right-char mark)
- (cond ((group-end? mark)
- (error "No right character" mark))
- ((line-end? mark)
- #\Newline)
- (else
- (string-ref (line-string (mark-line mark))
- (mark-position mark)))))
-