(module mred-callback mzscheme
(require (lib "etc.ss")
(lib "class.ss")
(lib "mred.ss" "mred")
(lib "pregexp.ss")
"utilities.ss"
"long-prefix.ss")
(provide voice-mred-text-callback-mixin
voice-mred-interactions-text-callback-mixin)
(define diva-debug false)
(define (diva-printf text . args)
(when diva-debug
(apply printf text args)))
(define ((a title) a)
(diva-printf "A: ~a: ~a~n" title a)
a)
(define (b b)
(diva-printf "B: `~a' ~n" b)
b)
(define (voice-mred-text-callback-mixin super%)
(class super%
(super-instantiate ())
(define insertion-after-set-position-callback-default (lambda () ()))
(define insertion-after-set-position-callback insertion-after-set-position-callback-default)
(define/public (diva:-insertion-after-set-position-callback-set callback)
(set! insertion-after-set-position-callback callback))
(define/public (diva:-insertion-after-set-position-callback-reset)
(diva:-insertion-after-set-position-callback-set insertion-after-set-position-callback-default))
(define/augment (after-set-position)
(diva-printf "AFTER-SET-POSITION called.~n")
(insertion-after-set-position-callback))
(define/augment (after-insert start len)
(diva-printf "AFTER INSERT called with start: ~a len: ~a~n" start len)
(inner void after-insert start len)
(preserve-mark start len))
(define/augment (after-delete start len)
(diva-printf "AFTER DELETE called with start: ~a len: ~a~n" start len)
(inner void after-delete start len)
(preserve-mark start (- len)))
(inherit get-text can-insert? can-delete? delete insert freeze-colorer thaw-colorer
begin-edit-sequence end-edit-sequence)
(define/public (diva:-get-text)
(get-text))
(define (update-text to-text)
(let ([from-text (send this diva:-get-text)])
(unless (string=? to-text from-text)
(let*-values
([(start-length end-length)
(common-prefix&suffix-lengths
from-text to-text string-length string-ref char=?)]
[(from-end)
(- (string-length from-text) end-length)]
[(to-end)
(- (string-length to-text) end-length)]
[(insert-text) (substring to-text start-length to-end)])
(cond
[(string=? (substring from-text start-length from-end)
insert-text)
(void)]
[(can-insert? start-length from-end)
(begin-edit-sequence)
(insert insert-text start-length from-end false)
(end-edit-sequence)]
[else
(raise (make-voice-exn "I cannot edit the text. Text is read-only."))])))))
(define/public (diva:-update-text text)
(dynamic-wind
(lambda () (begin-edit-sequence))
(lambda () (update-text text))
(lambda () (end-edit-sequence))))
(define mark-start-position 0)
(define mark-end-position 0)
(define/public (diva:-get-mark-start-position)
mark-start-position)
(define/public (diva:-get-mark-end-position)
mark-end-position)
(define/public (diva:-set-mark start-pos end-pos)
(hide-mark)
(set! mark-start-position start-pos)
(set! mark-end-position end-pos)
(show-mark))
(inherit highlight-range)
(define mark-color (send the-color-database find-color "Orange"))
(define (show-mark)
(unless (= mark-start-position mark-end-position)
(set! hide-mark (highlight-range mark-start-position mark-end-position mark-color false false 'low))))
(define hide-mark (lambda () ()))
(define (preserve-mark start delta)
(hide-mark)
(when (<= start mark-start-position)
(set! mark-start-position (+ mark-start-position delta))
(set! mark-end-position (+ mark-end-position delta)))
(unless (and (legal-mark-pos? mark-start-position)
(legal-mark-pos? mark-end-position))
(set! mark-start-position 0)
(set! mark-end-position 0))
(show-mark))
(define (legal-mark-pos? pos)
(<= 0 pos (string-length (get-text))))))
(define (voice-mred-interactions-text-callback-mixin super%)
(class (voice-mred-text-callback-mixin super%)
(super-instantiate ())
(inherit get-text
get-unread-start-point)
(define/override (diva:-update-text text)
(define (rehydrate-prompts-in-text text)
(regexp-replace* "(^|\n)>($|\n)" text "\\1> \\2"))
(super diva:-update-text (rehydrate-prompts-in-text text)))
(define/override (diva:-get-text)
(define hide-character "X")
(define non-control (pregexp "[^[:cntrl:]]"))
(define (all-but-last text)
(substring text 0 (sub1 (string-length text))))
(define (last-char text)
(string-ref text (sub1 (string-length text))))
(define (hide-annotations annotated-text)
(cond
[(and (> (string-length annotated-text) 0)
(char-whitespace? (last-char annotated-text)))
(string-append
(pregexp-replace* non-control (all-but-last annotated-text) hide-character)
(string (last-char annotated-text)))]
[else
(pregexp-replace* non-control annotated-text hide-character)]))
(let ([text (get-text)])
(string-append
(hide-annotations (substring text 0 (get-unread-start-point)))
(substring text (get-unread-start-point))))))))