(module dracula-tab-mixin (lib "a-unit.ss")
(require (lib "class.ss")
(lib "mred.ss" "mred")
(lib "framework.ss" "framework")
(lib "tool.ss" "drscheme")
(lib "unit.ss")
"acl2-controller.scm")
(require "dracula-tab-mixin-sig.scm"
"../language/acl2-settings.scm"
)
(require "../language/find-acl2.scm")
(require "../language/dracula-language.scm")
(import drscheme:tool^)
(export dracula-tab-mixin^)
(define dracula:unit:tab<%>
(interface (drscheme:unit:tab<%>)
admit-before-run
admit-next admit-all undo-last undo-all
start-acl2 interrupt-acl2 shutdown-acl2
new-settings-set
activate))
(define (admit-before-run? lang-settings)
(let ([settings (drscheme:language-configuration:language-settings-settings lang-settings)])
(and (pair? settings)
(acl2-settings? (car settings))
(acl2-settings-admit-before-run? (car settings)))))
(define-struct (exn:not-saved exn:fail) ())
(define dracula-tab-mixin
(mixin (drscheme:unit:tab<%>) (dracula:unit:tab<%>)
(inherit get-frame get-defs
get-directory)
(define-syntax (with-disabled-buttons stx)
(syntax-case stx ()
[(_ form ...)
#'(begin (send (get-frame) disable-buttons)
(let ([x (begin form ...)])
(send (get-frame) enable-buttons)
x))]))
(field [acl2-controller (new acl2-controller%)])
(field [active-acl2-session? #f])
(define/private (dracula-language-selected?)
(let* ([settings (send (get-defs) get-next-settings)]
[language (drscheme:language-configuration:language-settings-language settings)])
(send language dracula-language?)))
(define/public (activate)
(if active-acl2-session?
(send (get-frame) show-proof-buttons)
(send (get-frame) hide-proof-buttons (dracula-language-selected?))))
(define/private (show-start-failure-message msg)
(message-box "Failed to start ACL2"
msg
(get-frame)
'(ok stop)))
(define/private (show-save-first-message)
(message-box "Save before starting ACL2"
"Please save your code before starting ACL2"
(get-frame)
'(ok stop)))
(define/private (show-book-name-message)
(message-box "Filename extension for certified books"
"ACL2 books must have the .lisp file extension."
(get-frame)
'(ok stop)))
(define/private (show-certify-success-message file)
(message-box "Certification Success"
(format
"File ~s has been successfully certified as an ACL2 book."
file)))
(define/private (show-certify-failure-message file)
(message-box "Certification Failure"
(format
"File ~s could not be certified as an ACL2 book."
file)))
(define/public (start-acl2)
(with-handlers ([exn:fail:user? (lambda (e) (show-start-failure-message
(exn-message e)))]
[exn:not-saved? (lambda (_) (show-save-first-message))])
(let ([path (find-acl2)]
[dir (or (get-directory)
(raise (make-exn:not-saved
"Save your work before starting ACL2"
(current-continuation-marks))))])
(when path
(parameterize ([current-directory dir])
(send acl2-controller start-acl2 path)
(set! active-acl2-session? #t)
(send (get-frame) show-proof-buttons))))))
(define/public (admit-before-run)
(let ([settings (send (get-defs) get-next-settings)])
(if (admit-before-run? settings)
(with-disabled-buttons
(send acl2-controller admit-definitions-window
(get-defs) (get-frame)))
#t)))
(define/public (admit-next)
(with-disabled-buttons (send acl2-controller admit-next (get-defs))))
(define/public (admit-all)
(with-disabled-buttons (send acl2-controller admit-all (get-defs))))
(define/public (undo-last)
(with-disabled-buttons (send acl2-controller undo-last (get-defs))))
(define/public (undo-all)
(with-disabled-buttons
(send (get-defs) unhighlight-all)
(send acl2-controller undo-all)))
(define book-re (regexp "\\.lisp$"))
(define/private (get-book-name path)
(let* ([str (path->string path)])
(and (regexp-match? book-re str)
(regexp-replace book-re str ""))))
(define/public (certify-as-book)
(with-disabled-buttons
(if (send (get-frame) save)
(cond
[(get-book-name (send (get-frame) get-filename))
=>
(lambda (filename)
(send (get-defs) unhighlight-all)
(if (send acl2-controller certify-book filename)
(show-certify-success-message filename)
(show-certify-failure-message filename)))]
[else (show-book-name-message)])
(show-save-first-message))))
(define/public (interrupt-acl2)
(with-disabled-buttons
(send acl2-controller interrupt-acl2)))
(define/public (shutdown-acl2)
(with-disabled-buttons
(send (get-defs) unhighlight-all)
(send acl2-controller shutdown-acl2)
(set! active-acl2-session? #f)
(send (get-frame) hide-proof-buttons (dracula-language-selected?))))
(define/augment (on-close)
(shutdown-acl2)
(inner (void) on-close))
(define/public (new-settings-set)
(unless active-acl2-session?
(send (get-frame) hide-proof-buttons (dracula-language-selected?))))
(super-new))))