Tk komfortabel
#!/usr/bin/newlisp ;; ;; file: Tk.lsp ;; provides low-level access to Tcl/Tk ;; (context 'Tk) (map set '(myin tcout) (pipe)) (map set '(tcin myout) (pipe)) (process "/usr/bin/wish" tcin tcout) (define (wish str) (write-line myout (append "if {[catch {puts [" str "]}]}" [text] { tk_messageBox -message $errorInfo } [/text])) (read-line myin)) ;; ;; usage example next line: ;; (wish " bind . <Destroy> {puts {(exit)}} ") (map constant '(myin tcout tcin myout wish)) (define (read-lines chan) (local (buf) (read chan buf (peek chan)) (string buf))) ;; ;; process incoming newLISP requests ;; (define (event-loop (bool true)) (context MAIN) (cond ((null? bool) (set 'event-loop-running nil)) ((null? event-loop-running) (set 'event-loop-running true) (while event-loop-running (local (result) (if (catch (eval-string (read-lines myin)) 'result) result (wish (append "tk_messageBox -icon error -title Error" " -message {" (string result) "}")))))))) ;; ;; file: tk-syntax.lsp ;; ;; ;; String ohne Kontext: 'Tk:a → "a" ;; (define (string1 s) (if (symbol? s) (term s) (string s))) ;; ;; eval nur, wenn nicht -width, .t, <Return> ;; (define (evalToStr e) (cond ((not (symbol? e)) (string1 (eval e))) ((member ((string1 e) 0) '("-" "." "<")) (string1 e)) ((string1 (eval e))))) ;; ;; evalToStr auf Elemente der Liste a anwenden ;; (define (argsToList a) (map evalToStr a)) ;; ;; Lisp-String zu Tcl-String, ;; Sonderzeichen mit Backslash ;; (define (escToTcl s) (join (map (lambda (c) (if (member c '(" " "\\" "\"" "{" "}")) (append "\\" c) c)) (explode s)))) ;; ;; Lisp-Liste zu Tcl-Liste zusammenfügen ;; (define (argsToTclList a) (join (map escToTcl (argsToList a)) " ")) ;; ;; Syntax-Maschine ;; Dokumentation siehe HTML ;; (define-macro (Tk:Tk cmd1 (cmd2 "")) (wish (append (string1 cmd1) " " (string1 (if (list? cmd2) (eval cmd2) cmd2)) " " (argsToTclList (args))))) ;; ;; file: rep.lsp ;; purpose: read-eval-print loop by Tk text widget ;; ;; ;; tcl script in rep.tcl provides interactive text window ;; (define (read-eval-print) (wish [text] destroy .rep toplevel .rep wm title .rep newLISP tk appname rep pack\ [text .rep.t -font {Mono -15} -undo yes -wrap char\ -width 40 -height 10 -yscrollcommand ".rep.v set"]\ -expand yes -fill both -side left pack\ [scrollbar .rep.v -orient vertical -command ".rep.t yview"]\ -side left -fill y proc newLISP line { puts "(Tk:respond $line)" } proc println result { .rep.t mark set insert end .rep.t insert insert [lindex [list $result] 0]\n after idle .rep.t see insert } bind .rep.t <Return> [list apply [list win { if {[$win tag ranges sel] eq {}} then { set line [$win get {insert linestart} {insert lineend}] } else { set line [$win get sel.first sel.last] } newLISP $line $win mark set insert end $win insert insert \n }] %W] bind .rep.t <Return> +break bind .rep.t <Shift-Return> continue [/text]) (event-loop)) ;; ;; escape double quotes the electrical way ;; avoids quoting hell by hand ;; (define (escape str) (join (map (lambda (c) (if (member c '("\"" "\\" "$")) (append "\\" c) c)) (explode str)))) ;; ;; print-form of typed Lisp data ;; (define (typedString el) (cond ((string? el) (append "\"" (escape el) "\"")) ((symbol? el) (cond ((= (prefix el) MAIN) (term el)) ((= (prefix el) Tk) (append "Tk:" (term el))) ((string el)))) ((list? el) (append {(} (join (map typedString el) { }) {)})) ((array? el) (typedString (array-list el))) (true (escape (string el))))) ;; ;; the command Tk will send on <Return> ;; "println" is a Tcl script to write in Text window ;; (define (respond expr) (let (a (typedString expr)) (wish (append "println " (typedString a))))) (if (2 (main-args)) (begin (map load (2 (main-args))) (event-loop true)) (read-eval-print)) ;; eof
19.1.2023
<< | Heimatseite | Verzeichnis | Stichworte | Autor | >>