(module dracula-defns-text-mixin (lib "a-unit.ss")
(require (lib "class.ss")
(lib "mred.ss" "mred")
(lib "framework.ss" "framework")
(lib "tool.ss" "drscheme")
(lib "unit.ss")
(prefix acl2: "../language/acl2-reader.scm")
(lib "list.ss"))
(require "../language/event-form.scm")
(require "dracula-defns-text-mixin-sig.scm")
(import drscheme:tool^)
(export dracula-defns-text-mixin^)
(define color:admit (make-object color% "PaleGreen"))
(define color:reject (make-object color% "MistyRose"))
(define highlight-bitmap (make-object bitmap% 10 10 #t))
(define-struct admit (start end event? unhighlight))
(define dracula-defns-text-mixin
(mixin (editor:basic<%>
text:basic<%>
scheme:text<%>
(class->interface text%)
drscheme:unit:definitions-text<%>) (drscheme:unit:definitions-text<%>)
(inherit get-top-level-window
get-next-settings
get-forward-sexp
get-backward-sexp
get-text
get-tab
highlight-range)
(field [admit-stack null])
(field [admit-error #f])
(define/public (get-s-expressions)
(let ([text-port (open-input-string (get-text 0 'eof #t))])
(let loop ([expr (acl2:read text-port)]
[answer '()])
(if (eof-object? expr)
(reverse answer)
(loop (acl2:read text-port) (cons expr answer))))))
(define/private (find-admit-frontier)
(if (pair? admit-stack)
(admit-end (car admit-stack))
0))
(define/private (find-next-unadmitted-sexp)
(let* ([frontier (find-admit-frontier)]
[end-of-next (get-forward-sexp frontier)]
[start-of-next (if end-of-next (get-backward-sexp end-of-next) #f)])
(if (and end-of-next
start-of-next
(<= frontier start-of-next)
(< start-of-next end-of-next))
(values start-of-next end-of-next)
(values #f #f))))
(define/private (find-next-unadmitted-sexp/text)
(let*-values ([(start end) (find-next-unadmitted-sexp)])
(values start
end
(if (and start end) (get-text start end #t #f) #f))))
(define/public (get-next-unadmitted-sexp)
(let*-values ([(start end text) (find-next-unadmitted-sexp/text)])
text))
(define/public (highlight-next-unadmitted-sexp admitted?)
(unhighlight-error)
(let*-values ([(start end text) (find-next-unadmitted-sexp/text)])
(when (and start end text)
(let* ([event? (event-form? (read (open-input-string text)))]
[color (if admitted? color:admit color:reject)]
[unhighlight (highlight-range start end color #f 'high)]
[admission (make-admit start end event? unhighlight)])
(if admitted?
(set! admit-stack (cons admission admit-stack))
(set! admit-error admission))))))
(define/public (unhighlight-last-admitted)
(if (pair? admit-stack)
(let* ([admission (car admit-stack)]
[rest (cdr admit-stack)]
[unhighlight (admit-unhighlight admission)]
[event? (admit-event? admission)])
(set! admit-stack rest)
(unhighlight)
event?)
#f))
(define/public (unhighlight-all)
(unhighlight-error)
(for-each (lambda (admission)
(apply (admit-unhighlight admission) null))
admit-stack)
(set! admit-stack null))
(define/private (unhighlight-error)
(when admit-error
(apply (admit-unhighlight admit-error) null)
(set! admit-error #f)))
(define/augment (can-insert? start len)
(and (>= start (find-admit-frontier))
(inner #t can-insert? start len)))
(define/augment (can-delete? start len)
(and (>= start (find-admit-frontier))
(inner #t can-delete? start len)))
(define/augment (after-insert start len)
(unhighlight-error)
(inner (void) after-insert start len))
(define/augment (after-delete start len)
(unhighlight-error)
(inner (void) after-insert start len))
(define/augment (after-set-next-settings language-settings)
(send (get-tab) new-settings-set)
(inner (void) after-set-next-settings language-settings))
(super-new)))
)