diff --git a/scheme/nuit-engine.scm b/scheme/nuit-engine.scm index 8a03bff..57b4814 100644 --- a/scheme/nuit-engine.scm +++ b/scheme/nuit-engine.scm @@ -1,10 +1,15 @@ -;; ,load /home/demattia/studium/studienarbeit/scsh-nuit/scheme/nuit-engine.scm - +;;This is the "heart" of NUIT. +;;In a central loop the program waits for input (with wgetch). +;;In the upper buffer simply the functionalities of scsh-ncurses: +;;input-buffer are used. +;;The lower window is meant to be used more flexible. Depending on +;;the active command the key-inputs are routed to the correct receiver, +;;where one can specify how to react. ;;************************************************************************* -;;Zustand +;;State -;;Die verschiedenen Fenster +;;The different windows ;;------------------------ (define bar1) (define bar2) @@ -13,7 +18,7 @@ (define result-win) (define shortcuts '("F1:Exit" - "Ctrl+b:Switch Buffer" + "Ctrl+d:Switch Buffer" "Ctrl+s:Insert/Select" "Ctrl+u:-/Unselect" "Ctrl+p:History->prev" @@ -23,76 +28,87 @@ -;;Zustand des oberen Fensters (Command-Window) +;;state of the upper window (Command-Window) ;;--------------------------- - ;;Text (define text-command (list "Welcome in the scsh-ncurses-ui!" "")) -;;gibt an, in welcher Zeile der gesamten Command-History man sich befindet +;;position in the history of all commands (define pos-command 2) -;;in welcher Spalte + +;;col (define pos-command-col 2) -;;gibt an, in welcher Zeile des Buffers nach Zeilenumbruch man sich befindet. +;;Line after lines have been seperated to fit in the buffer (define pos-command-fin-ln 2) -;;gibt an, in welcher Zeile des Buffers man sich befindet +;;y-coordinate of the cursor (define command-buffer-pos-y 2) -;;gibt an, an welcher Position des Buffers man sich befindet. + +;;x-coordinate of the cursor (define command-buffer-pos-x 2) -;;Anzahl der Zeilen des Commando-Buffers +;;number of lines in the command-buffer (define command-lines 0) -;;Anzahl der Spalten des Commando-Buffers +;;number of columns in the command-buffer (define command-cols 0) -;;befindet sich der cursor am Ende der letzten Zeile des command-wins? +;;only true if the curser is in the last line (define can-write-command #t) +;;active entry of the "edit-history" +(define command-history-pos 1) -;;Zustand des unteren Fensters (Result-Window) +;;representation of the whole buffer +(define command-buffer) + + +;;state of the lower window (Result-Window) ;;---------------------------- - ;;Text (define text-result (list "Start entering commands.")) -;;gibt an, in welcher Zeile des Result-Buffers man sich befindet +;;line of the result-window (define pos-result 0) -;;in welcher Spalte + +;;column (define pos-result-col 0) -;;gibt an, in welcher Zeile des Buffers man sich befindet +;;y-coordinate of the cursor in the result-buffer (define result-buffer-pos-y 0) -;;gibt an, an welcher Position des Buffers man sich befindet. + +;;x-coordinate of the cursor in the result-buffer (define result-buffer-pos-x 0) -;;Anzahl der Zeilen des Buffers +;;lines of the lower window (define result-lines 0) -;;Anzahl der Spalten des Buffers + +;;columns in the lower window (define result-cols 0) -;;welche Zeilen sollen gehighlighted werden? +;;lines to be highlighted (define highlighted-lines '()) -;;welche Zeilen sollen markiert werden? +;;lines to be marked (define marked-lines '()) + + -;;allgemeiner Zustand +;;miscelaneous state ;;------------------- -;;entweder 1...oben oder 2...unten +;;1....upper;2....lower (define active-buffer 1) ;;History (define history '()) -;;Position in der History +;;Position in the "elaborated" History (define history-pos 0) -;;Datentyp für History-Einträge +;;data-type for history.entries (define-record-type history-entry history-entry (make-history-entry command result-object) @@ -100,19 +116,18 @@ (command history-entry-command) (result-object history-entry-result-object)) -;;aktiver Befehl +;;active command (define active-command "") -;;actives Result-Objekt +;;active result-object (define current-result-object) -;;Typen für Nachrichten +;;Message-Types ;;--------------------- - -;;Ein neuer Befehl wurde eingegeben -;;-> neues "Object" erzeugen anhand der Parameter in einer Liste +;;A new command was entered +;;->create a new "object" (define-record-type next-command-message next-command-message (make-next-command-message command-string parameters @@ -122,9 +137,9 @@ (parameters next-command-message-parameters) (width next-command-message-width)) -;;Es wurde eine Taste gedrückt -;;->Es wird das Objekt und die Taste an den "User-Code" weitergegeben -;; und dann kommt das veränderte Objekt zurück. +;;key pressed +;;The object and the key are send to the user-code, who returns the +;;changed object. (define-record-type key-pressed-message key-pressed-message (make-key-pressed-message command-string result-model @@ -134,7 +149,7 @@ (result-model key-pressed-message-result-model) (key key-pressed-message-key)) -;;Zeichnen +;;print (define-record-type print-message print-message (make-print-message command-string object) @@ -142,7 +157,7 @@ (command-string print-message-command-string) (object print-message-object)) -;;->solch ein Datentyp kommt zurück +;;->this sort of data-type is returned by a print-message (define-record-type print-object print-object (make-print-object pos-y pos-x @@ -155,7 +170,7 @@ (highlighted-lines print-object-highlighted-lines) (marked-lines print-object-marked-lines)) -;;Wiederherstellen (bei Seiteneffekten) +;;restore (when side-effects occur) (define-record-type restore-message restore-message (make-restore-message command-string object) @@ -163,8 +178,7 @@ (command-string restore-message-command-string) (object restore-message-object)) -;;Auswahl anfordern - +;;request the selection (define-record-type selection-message selection-message (make-selection-message command-string object) @@ -172,28 +186,24 @@ (command-string selection-message-command-string) (object selection-message-object)) - - -;;Der Benutzer muss bei Erweiterungen angeben an welche Funktion die -;;Nachrichten bei einem bestimmten Befehl auszuliefern ist - +;;The "user" (who extends the functionality of NUIT) has to inform NUIT +;;about which function is meant to be the receiver, when a certain +;;command is active (define-record-type receiver receiver (make-receiver command rec) receiver? (command receiver-command) (rec receiver-rec)) - ;;************************************************************************* -;;Verhalten +;;Actions -;;Eingabe verarbeiten +;;handle input (define run (lambda () (begin - ;;Initialisierung - ;;erfolgt nur am Anfang + ;;initialisation (init-screen) (set! bar1 (newwin 0 0 0 0)) (set! bar2 (newwin 0 0 0 0)) @@ -205,8 +215,9 @@ (let loop ((ch (paint))) (cond - ;;Das Resultat dieser TAstendrücke ist unabhängig vom activen Buffer - ;;Beenden + ;;The result of pressing these keys is independent of which + ;;Buffer is active + ;;Finish ((= ch key-f1) (begin (let ((restore-message (make-restore-message @@ -215,8 +226,8 @@ (switch restore-message)) (endwin))) - ;;Ctrl+b -> Buffer wechseln - ((= ch 2) + ;;Ctrl+f -> switch buffer + ((= ch 4) (begin (if (= active-buffer 1) (set! active-buffer 2) @@ -224,8 +235,7 @@ (loop (paint)))) - ;;Erfolgt der TAstendruck bei aktivem Ergebnis-Buffer, so wird eine - ;;entsprechende Nachricht versendet. + ;;if lower window is active a message is sent. (else (if (= active-buffer 2) (let ((key-message @@ -241,86 +251,25 @@ ;;Enter ((= ch 10) (begin - ;;Es wird die restore-Prozedur aufgerufen - ; (let ((restore-message (make-restore-message -; active-command -; current-result-object))) -; (switch restore-message)) - (execute-command) + (set! command-history-pos (- (length text-command) 1)) (loop (paint)))) - ;;Backspace - ((= ch key-backspace) - (if can-write-command - (if (< pos-command-col 3) - (loop (paint)) - (begin - (remove-from-command-buffer) - (set! pos-command-col (- pos-command-col 1)) - (loop (paint)))) - (loop (paint)))) - - ;;Navigieren - ((= ch key-up) - (if (< pos-command-fin-ln 2) - (loop (paint)) - (let ((length-prev-line - (string-length - (list-ref text-command (- pos-command 2))))) - (begin - (set! can-write-command #f) - (set! pos-command (- pos-command 1)) - (set! pos-command-col (+ length-prev-line 2)) - (loop (paint)))))) - - ((= ch key-down) - (let ((last-pos (length text-command))) - (if (>= pos-command last-pos) - (loop (paint)) - (let ((length-next-line - (string-length - (list-ref text-command pos-command)))) - (begin - (set! pos-command-col (+ length-next-line 2)) - (set! pos-command (+ pos-command 1)) - (if (= pos-command last-pos) - (set! can-write-command #t)) - (loop (paint))))))) - - - ((= ch key-left) - (if (<= pos-command-col 2) - (loop (paint)) - (begin - (set! pos-command-col (- pos-command-col 1)) - (loop (paint))))) - - - ((= ch key-right) - (let ((line-length (string-length - (list-ref text-command - (- pos-command 1))))) - (if (>= pos-command-col (+ line-length 2)) - (loop (paint)) - (begin - (set! pos-command-col (+ pos-command-col 1)) - (loop (paint)))))) - ;;Ctrl+p -> History zurück + ;;Ctrl+p -> History back ((= ch 16) (begin (history-back) (loop (paint)))) - ;;Ctrl+n -> History vor + ;;Ctrl+n -> History forward ((= ch 14) (begin (history-forward) (loop (paint)))) - ;;Ctrl+s -> Auswahl-holen + ;;Ctrl+s -> get selection ((= ch 19) (let* ((message (make-selection-message active-command current-result-object)) @@ -328,35 +277,45 @@ (begin (add-string-to-command-buffer marked-items) (loop (paint))))) - - - - ;;Ctrl+a -> Zeilenanfang - ((= ch 1) - (begin - (set! pos-command-col 2) - (loop (paint)))) - ;;Ctrl-e -> Zeilenende - ((= ch 5) - (let ((line-length (string-length - (list-ref text-command (- pos-command 1))))) - (begin - ;(set! command-buffer-pos-x (+ line-length 2)) - (set! pos-command-col (+ line-length 2)) - (loop (paint))))) - (else - (if (<= ch 255) - (if can-write-command - (begin - (add-to-command-buffer ch) - (loop (paint))) - (loop (paint))) - (loop (paint)))))))))))) + (begin + (set! command-buffer (make-buffer text-command + pos-command + pos-command-col + pos-command-fin-ln + command-buffer-pos-y + command-buffer-pos-x + command-lines + command-cols + can-write-command + command-history-pos)) + (set! command-buffer (input command-buffer ch)) + (let ((text (buffer-text command-buffer)) + (pos-line (buffer-pos-line command-buffer)) + (pos-col (buffer-pos-col command-buffer)) + (pos-fin-ln (buffer-pos-fin-ln command-buffer)) + (pos-y (buffer-pos-y command-buffer)) + (pos-x (buffer-pos-x command-buffer)) + (num-lines (buffer-num-lines command-buffer)) + (num-cols (buffer-num-cols command-buffer)) + (can-write (buffer-can-write command-buffer)) + (history-pos (buffer-history-pos command-buffer))) + (begin + (set! text-command text) + (set! pos-command pos-line) + (set! pos-command-col pos-col) + (set! pos-command-fin-ln pos-fin-ln) + (set! command-buffer-pos-y pos-y) + (set! command-buffer-pos-x pos-x) + (set! command-lines num-lines) + (set! command-cols num-cols) + (set! can-write-command can-write) + (set! command-history-pos history-pos))) + (loop (paint)))))))))))) -;;darstellen und auf Eingabe warten +;;print and wait for input (define paint (lambda () (begin @@ -406,7 +365,19 @@ (set! command-lines (- comwin-h 2)) (set! command-cols (- comwin-w 3)) - (print-command-buffer command-win) + (set! command-buffer (make-buffer text-command + pos-command + pos-command-col + pos-command-fin-ln + command-buffer-pos-y + command-buffer-pos-x + command-lines + command-cols + can-write-command + command-history-pos)) + + (set! command-buffer (print-command-buffer command-win command-buffer)) + (wrefresh command-win) (box result-win (ascii->char 0) (ascii->char 0)) (set! result-lines (- reswin-h 2)) @@ -416,30 +387,51 @@ (box bar3 (ascii->char 0) (ascii->char 0)) (wattron bar3 (A-REVERSE)) (print-bar3 (- reswin-w 3)) - ;(mvwaddstr bar3 1 1 "F1:Exit | Ctrl+b:Switch-Buffer") (wstandend bar3) (wrefresh bar3) - (cursor-right-pos command-win result-win comwin-h reswin-h) + + (set! command-buffer (cur-right-pos command-win result-win comwin-h + reswin-h command-buffer)) + + (let ((text (buffer-text command-buffer)) + (pos-line (buffer-pos-line command-buffer)) + (pos-col (buffer-pos-col command-buffer)) + (pos-fin-ln (buffer-pos-fin-ln command-buffer)) + (pos-y (buffer-pos-y command-buffer)) + (pos-x (buffer-pos-x command-buffer)) + (num-lines (buffer-num-lines command-buffer)) + (num-cols (buffer-num-cols command-buffer)) + (can-write (buffer-can-write command-buffer)) + (history-pos (buffer-history-pos command-buffer))) + (begin + (set! text-command text) + (set! pos-command pos-line) + (set! pos-command-col pos-col) + (set! pos-command-fin-ln pos-fin-ln) + (set! command-buffer-pos-y pos-y) + (set! command-buffer-pos-x pos-x) + (set! command-lines num-lines) + (set! command-cols num-cols) + (set! can-write-command can-write) + (set! command-history-pos history-pos))) + (noecho) (keypad bar1 #t) - (let ((ch (wgetch bar1))) - (echo) ch ))))) -;;Auswerten -;;Eingabe wurde durch Benutzer bestätigt -> Kommando ausfuehren +;;If the user presses enter the last line is interpreted as a command +;;which has to be executed. (define execute-command (lambda () (let* ((command (list-ref text-command (- (length text-command) 1))) - ;;Hier sollte noch die Behandlung von Parametern eingefügt werden + ;;todo: parameters (message (make-next-command-message command '() result-cols)) (model (switch message))) (begin - ;;Vorheriges Objekt in History sichern (if (not (= history-pos 0)) (let ((hist-entry (make-history-entry active-command current-result-object)) @@ -452,8 +444,6 @@ (- (length history) 1)) (list hist-entry) (list active)))) (set! history-pos (length history)))) - - ;;Dieser Fall tritt nur ganz am Anfang ein. (let ((hist-entry (make-history-entry command model))) (begin (set! history (list hist-entry)) @@ -464,15 +454,14 @@ (set! current-result-object model) (scroll-command-buffer))))) -;;Nach einer Eingabe kann es sein, dass die aktive Buffer_Zeile verschoben -;;werden muss. +;;scroll buffer after one command was entered (define scroll-command-buffer (lambda () (begin (set! pos-command (+ pos-command 1)) (set! pos-command-col 2)))) -;;Auswerten eines Ausdrucks in Form eines String +;;evaluate an expression given as a string (define evaluate (lambda (exp) (let* ((command-port (open-input-string exp)) @@ -488,8 +477,8 @@ -;;Nachrichten-Vermittlung -;;Der Switch sorgt dafür, dass die Nachrichten richtig ankommen +;;Message-Passing +;;switch manages that the messages are delivered in the correct way (define switch (lambda (message) (let ((command "")) @@ -523,8 +512,8 @@ (loop (cdr recs)))))))) -;;Steuerung der oberen Buffers -;;Ein Character zur letzten Zeile des Command-Buffers hinzufügen +;;Management of the upper buffer +;;add a char to the buffer (define add-to-command-buffer (lambda (ch) (let* ((last-pos (- (length text-command) 1)) @@ -541,8 +530,7 @@ (set! text-command (append old-rest (list new-last-el))) (set! pos-command-col (+ pos-command-col 1))))) -;;Einen ganzen String hinzufügen -;;->mehrfacher Aufruf von add-to-command-string +;;add a string to the buffer (define add-string-to-command-buffer (lambda (string) (let loop ((str string)) @@ -554,135 +542,20 @@ (loop (substring str 1 (string-length str))))))))) -;;Ein Character aus der letzten Zeile entfernen (backspace) -(define remove-from-command-buffer - (lambda () - (let* ((last-pos (- (length text-command) 1)) - (old-last-el (list-ref text-command last-pos)) - (old-rest (sublist text-command 0 last-pos)) - (before-ch (substring old-last-el 0 - (max 0 (- pos-command-col 3)))) - (after-ch (if (= pos-command-col - (+ (string-length old-last-el) 2)) - "" - (substring old-last-el - (max 0 (- pos-command-col 2)) - (string-length old-last-el)))) - (new-last-el (if (= pos-command-col - (+ (string-length old-last-el) 2)) - before-ch - (string-append before-ch after-ch)))) - (set! text-command (append old-rest (list new-last-el)))))) - - - -;;Es wird der sichtbare Teil der bisherigen Eingaben in den Command- -;;Buffer angezeigt. -(define print-command-buffer - (lambda (comwin) - (let ((lines (get-right-command-lines))) - (let loop ((pos 1)) - (if (> pos command-lines) - values - (let ((line (list-ref lines (- pos 1)))) - (begin - (mvwaddstr comwin pos 1 line) - (wrefresh comwin) - (loop (+ pos 1))))))))) - - -;;Es werden die anzuzeigenden Zeilen erzeugt. -;;nötig, damit auch Befehle über mehrere Zeilen möglich sind: -(define get-right-command-lines - (lambda () - (let* ((all-lines-seperated (all-commands-seperated text-command)) - (num-all-lines (length all-lines-seperated))) - (if (>= pos-command-fin-ln command-lines) - ;;aktive Zeile ist die unterste - (sublist all-lines-seperated - (- pos-command-fin-ln command-lines) - command-lines) - (if (<= num-all-lines command-lines) - ;;noch keine ganze Seite im Buffer - (prepare-lines all-lines-seperated - command-lines (- pos-command-fin-ln 1)) - ;;scrollen auf der ersten Seite - (sublist all-lines-seperated 0 command-lines)))))) - -;;alle Statements zerlegen -(define all-commands-seperated - (lambda (commands) - (let loop ((act-pos 1) - (new '())) - (begin - (if (= act-pos pos-command) - (let* ((length-new (length new)) - (first-el-old (list-ref commands (- act-pos 1))) - (seperated-act (seperate-line-com - first-el-old command-cols)) - (length-act (length seperated-act))) - (set! pos-command-fin-ln (+ length-new length-act)))) - - (if (> act-pos (length commands)) - (reverse new) - (let* ((first-el-old (list-ref commands (- act-pos 1))) - (seperated-fst-el-old - (seperate-line-com first-el-old command-cols))) - (loop (+ act-pos 1) (append seperated-fst-el-old new)))))))) - -;;Ein Statement wird in Stücke zerlegt, so dass dann jedes Stück in eine -;;Zeile passt. -(define seperate-line-com - (lambda (line width) - (let loop ((new '()) - (old line)) - (if (> width (string-length old)) - (if (= 0 (string-length old)) - (if (equal? new '()) - (add-prompts '("")) - (add-prompts new)) - ;new - (add-prompts (append (list old) new))) - ;(append (list old) new)) - (let ((next-line (substring old 0 width)) - (rest-old (substring old width (string-length old)))) - (loop (cons next-line new) rest-old)))))) - -;;> hinzufügen -(define add-prompts - (lambda (l) - (let* ((lr (reverse l)) - (old-first-el (list-ref lr 0)) - (new-first-el (string-append ">" old-first-el)) - (old-rest (list-tail lr 1))) - (let loop ((old old-rest) - (new (list new-first-el))) - (if (> (length old) 0) - (let* ((old-first-el (list-ref old 0)) - (new-first-el (string-append " " old-first-el))) - (loop (list-tail old 1) (append new (list new-first-el)))) - (reverse new)))))) - - -;;Es wird in einer Liste der zu druckende Berecih ausgewählt: +;;selection of the visible area of the buffer (define prepare-lines (lambda (l height pos) (if (< (length l) height) - ;; Liste zu kurz -> ""s hinzufügen (let loop ((tmp-list l)) (if (= height (length tmp-list)) tmp-list (loop (append tmp-list (list ""))))) - ;; Teilliste holen (if (< pos height) - ;;pos nicht ganz unten (sublist l 0 height) - ;;standard-Fall (sublist l (- pos height) height))))) -;;Darstellen des unteren Buffers -;;Anzeigen des sichtbaren Teils des Result-Buffers +;;print the lower window (define print-result-buffer (lambda (reswin) (let* ((print-message (make-print-message active-command @@ -726,12 +599,12 @@ (wrefresh reswin) (loop (+ pos 1))))))))))))) -;;anzuzeigende Zeilen im Result-Buffer +;;visible lines (define get-right-result-lines (lambda () (prepare-lines text-result result-lines pos-result))) -;;Markierte und gehighlightete Zeilen berechnen: +;;marked and highlighted lines (define right-highlighted-lines (lambda () (let loop ((old highlighted-lines) @@ -765,43 +638,37 @@ ;;Cursor -;;Cursor an die richtige Stelle bewegen: -(define cursor-right-pos - (lambda (comwin reswin comwin-h reswin-h) +;;move cursor to the corrct position +(define cur-right-pos + (lambda (comwin reswin comwin-h reswin-h buffer) (begin - (compute-y-x) (if (= active-buffer 1) + (cursor-right-pos comwin buffer) (begin - (wmove comwin command-buffer-pos-y command-buffer-pos-x) - (wrefresh comwin)) - (begin + (compute-y-x) (wmove reswin result-buffer-pos-y result-buffer-pos-x) - (wrefresh reswin)))))) + (wrefresh reswin) + buffer))))) -;;pos-y und pos-x berechnen +;;compue pos-x and pos-y (define compute-y-x (lambda () (if (= active-buffer 1) (begin - ;;zuerst mal y (if (>= pos-command-fin-ln command-lines) - ;;unterste Zeile (set! command-buffer-pos-y command-lines) - ;;sonst (set! command-buffer-pos-y pos-command-fin-ln)) - ;;jetzt x (let ((posx (modulo pos-command-col command-cols))) (set! command-buffer-pos-x posx))) (begin - ;;zuerst y (if (>= pos-result result-lines) (set! result-buffer-pos-y result-lines) (set! result-buffer-pos-y pos-result)) (set! result-buffer-pos-x pos-result-col))))) -;;Unterstes Fenster +;;index of shortcuts at the bottom (define print-bar3 (lambda (width) (let loop ((pos 0) @@ -849,8 +716,7 @@ -;; Ein Schritt zurück in der History. Im unteren Buffer wird jeweils das -;; Ergebnis angezeigt +;; one step back in the history (define history-back (lambda () (if (<= history-pos 0) @@ -869,7 +735,7 @@ (set! history-pos (- history-pos 1)))))))) -;;Ein Schritt nach vorne in der History. Analog zu history-back +;;one step forward (define history-forward (lambda () (if (= history-pos (length history) ) @@ -891,24 +757,17 @@ (set! current-result-object entry-res-obj) (set! history-pos (+ history-pos 1)))))))) - - -;;Teilliste (define sublist (lambda (l pos k) (let ((tmp (list-tail l pos))) (reverse (list-tail (reverse tmp) (- (length tmp) k)))))) -;;************************************************************************* -;;Die folgenden Funktionen sollten später in eine eigene Datei kommen. -;;Sie sind abhängig vom jeweiligen Befehl. +;;Standard-Receiver +;;----------------- -;;Standardfall -;;------------ - -;;Datentyp, der das Resultat einer "Standard-Auswertung" repräsentiert +;;Datatype representing the "standard-result-objects" (define-record-type standard-result-obj standard-result-obj (make-standard-result-obj cursor-pos-y cursor-pos-x @@ -950,328 +809,13 @@ ((selection-message? message) "")))) -;;Im Standardfall wird einfach als Ergebnis die Rückgabe der scsh ausgegeben. +;;the result is the "answer" of scsh (define layout-result-standard (lambda (result-str result width) (reverse (seperate-line result-str width)))) -;;directory-files -;;--------------- - - -(define initial-working-directory (cwd)) - -;;Result-Object für "directory-files" -(define-record-type dirfiles-result-object dirfiles-result-object - (make-dirfiles-result-object pos-y - pos-x - file-list - result-text - working-directory - width - initial-wd - marked-items - res-marked-items) - dirfiles-result-object? - (pos-y dirfiles-result-object-pos-y) - (pos-x dirfiles-result-object-pos-x) - (file-list dirfiles-result-object-file-list) - (result-text dirfiles-result-object-result-text) - (working-directory dirfiles-result-object-working-directory) - (width dirfiles-result-object-width) - (initial-wd dirfiles-result-object-initial-wd) - (marked-items dirfiles-result-object-marked-items) - (res-marked-items dirfiles-result-object-res-marked-items)) - -;;Darstellung, falls die Eingabe ist: "(directory-files)" -(define layout-result-dirfiles - (lambda (result-str result width) - (begin - (let ((printed-file-list (print-file-list result)) - (directory (cwd)) - (heading "")) - (begin - (if (<= (string-length directory) (- width 27)) - (set! heading (string-append "Directory-Content of " - directory " :")) - (let ((dir-string (substring directory - (- (string-length directory) - (- width 27)) - (string-length directory)))) - (set! heading (string-append "Directory-Content of ..." - dir-string)))) - (append (list heading) (list " <-") - printed-file-list)))))) - - -;;Eine Datei pro Zeile -;;Falls es sich um ein Verzeichnis handelt wird "/" hinzugefügt -(define print-file-list - (lambda (file-list) - (let loop ((old file-list) - (new '())) - (if (equal? '() old) - new - (let ((hd (list-ref old 0)) - (tl (cdr old))) - (if (file-directory? hd) - (let ((new-str (string-append " " hd "/"))) - (loop tl (append new (list new-str)))) - (loop tl (append new (list (string-append " " hd)))))))))) - -;;Auswahl->absteigen -(define selected-dirfiles - (lambda (model) - (let ((ln (dirfiles-result-object-pos-y model))) - (if (or (>= ln (+ (length (dirfiles-result-object-result-text model)) 1)) - (<= ln 1)) - model - (if (= ln 2) - (if (not (equal? "/" (cwd))) - (begin - (chdir "..") - (let* ((new-result (evaluate "(directory-files)")) - (new-result-string (exp->string new-result)) - (width (dirfiles-result-object-width model)) - (new-text (layout-result-dirfiles - new-result-string new-result width)) - (new-model (make-dirfiles-result-object - 2 - 1 - new-result - new-text - (cwd) - width - (dirfiles-result-object-initial-wd - model) - (dirfiles-result-object-marked-items - model) - (dirfiles-result-object-res-marked-items - model)))) - new-model)) - model) - (let* ((text (dirfiles-result-object-result-text model)) - (ent (list-ref text (- ln 1))) - (len (string-length ent)) - (last-char (substring ent (- len 1) len)) - (rest (substring ent 1 (- len 1)))) - (if (equal? last-char "/") - (begin - (chdir rest) - (let* ((new-result (evaluate "(directory-files)")) - (new-result-string (exp->string new-result)) - (width (dirfiles-result-object-width model)) - (new-text (layout-result-dirfiles - new-result-string new-result width)) - (new-model (make-dirfiles-result-object - 2 - 1 - new-result - new-text - (cwd) - width - (dirfiles-result-object-initial-wd - model) - (dirfiles-result-object-marked-items - model) - (dirfiles-result-object-res-marked-items - model)))) - new-model)) - model))))))) - - -;;Receiver für directory-files -(define dir-files-receiver - (lambda (message) - (cond - - ((next-command-message? message) - (let* ((command (next-command-string message)) - (result (evaluate command)) - (result-string (exp->string result)) - (width (next-command-message-width message)) - (text (layout-result-dirfiles result-string result width)) - (model (make-dirfiles-result-object 2 1 result text (cwd) - width (cwd) '() '()))) - model)) - - ((print-message? message) - (let* ((model (print-message-object message)) - (posy (dirfiles-result-object-pos-y model)) - (posx (dirfiles-result-object-pos-x model)) - (text (dirfiles-result-object-result-text model)) - (marked-pos (get-marked-positions - (dirfiles-result-object-file-list model) - (dirfiles-result-object-marked-items model)))) - (make-print-object posy posx text (list posy) marked-pos))) - - ((key-pressed-message? message) - (let* ((model (key-pressed-message-result-model message)) - (key (key-pressed-message-key message))) - (cond - - ((= key key-up) - (let ((posy (dirfiles-result-object-pos-y model))) - (if (<= posy 2) - model - (let* ((new-posy (- posy 1)) - (new-model (make-dirfiles-result-object - new-posy - (dirfiles-result-object-pos-x model) - (dirfiles-result-object-file-list model) - (dirfiles-result-object-result-text - model) - (dirfiles-result-object-working-directory - model) - (dirfiles-result-object-width model) - (dirfiles-result-object-initial-wd model) - (dirfiles-result-object-marked-items - model) - (dirfiles-result-object-res-marked-items - model)))) - new-model)))) - - ((= key key-down) - (let ((posy (dirfiles-result-object-pos-y model)) - (num-lines (length - (dirfiles-result-object-result-text model)))) - (if (>= posy num-lines) - model - (let* ((new-posy (+ posy 1)) - (new-model (make-dirfiles-result-object - new-posy - (dirfiles-result-object-pos-x model) - (dirfiles-result-object-file-list model) - (dirfiles-result-object-result-text - model) - (dirfiles-result-object-working-directory - model) - (dirfiles-result-object-width model) - (dirfiles-result-object-initial-wd - model) - (dirfiles-result-object-marked-items - model) - (dirfiles-result-object-res-marked-items - model)))) - new-model)))) - - ((= key 10) - (selected-dirfiles model)) - - ;;Ctrl+s -> Auswahl - ((= key 19) - (let* ((marked-items (dirfiles-result-object-marked-items model)) - (res-marked-items (dirfiles-result-object-res-marked-items - model)) - (actual-pos (dirfiles-result-object-pos-y model)) - (all-items (dirfiles-result-object-file-list model))) - (if (<= actual-pos 2) - model - (let* ((actual-item (list-ref all-items (- actual-pos 3))) - (actual-res-item (string-append (cwd) "/" actual-item))) - (if (member actual-res-item marked-items) - model - (let* ((new-res-marked-items (append res-marked-items - (list - actual-res-item))) - (new-marked-items (append marked-items - (list actual-item))) - (new-model (make-dirfiles-result-object - (dirfiles-result-object-pos-y model) - (dirfiles-result-object-pos-x model) - (dirfiles-result-object-file-list - model) - (dirfiles-result-object-result-text - model) - (dirfiles-result-object-working-directory - model) - (dirfiles-result-object-width model) - (dirfiles-result-object-initial-wd - model) - new-marked-items - new-res-marked-items))) - new-model)))))) - - ;;Ctrl+u -> aus Auswahl rausnehmen - ((= key 21) - (let* ((marked-items (dirfiles-result-object-marked-items model)) - (res-marked-items (dirfiles-result-object-res-marked-items - model)) - (actual-pos (dirfiles-result-object-pos-y model)) - (all-items (dirfiles-result-object-file-list model))) - (if (<= actual-pos 2) - model - (let* ((actual-item (list-ref all-items (- actual-pos 3))) - (actual-res-item (string-append (cwd) "/" actual-item)) - (rest (member actual-item marked-items)) - (res-rest (member actual-res-item res-marked-items))) - (if (not res-rest) - model - (let* ((after-item (length rest)) - (all-items (length marked-items)) - (before-item (sublist marked-items - 0 - (- all-items - after-item ))) - (new-marked-items (append before-item - (list-tail rest 1))) - (after-res-item (length res-rest)) - (all-res-items (length res-marked-items)) - (before-res-item (sublist res-marked-items - 0 - (- all-res-items - after-res-item))) - (new-res-marked-items (append before-res-item - (list-tail res-rest - 1))) - (new-model (make-dirfiles-result-object - (dirfiles-result-object-pos-y model) - (dirfiles-result-object-pos-x model) - (dirfiles-result-object-file-list - model) - (dirfiles-result-object-result-text - model) - (dirfiles-result-object-working-directory - model) - (dirfiles-result-object-width model) - (dirfiles-result-object-initial-wd - model) - new-marked-items - new-res-marked-items))) - new-model)))))) - - - - - (else model)))) - - ((restore-message? message) - ;(let ((model (restore-message-object message))) - ;(chdir (dirfiles-result-object-initial-wd model)))) - (chdir initial-working-directory)) - - ((selection-message? message) - (let* ((model (selection-message-object message)) - (marked-items (dirfiles-result-object-res-marked-items model))) - (string-append "'" (exp->string marked-items)))) - - - - (else values)))) - - -(define dir-files-rec - (make-receiver "(directory-files)" dir-files-receiver)) - -(define receivers (cons dir-files-rec '())) - - - - - -;;nützliche Hilfsfunktionen: - +;useful helpers (define get-marked-positions (lambda (all-items marked-items) (let loop ((count 0) @@ -1285,7 +829,7 @@ (loop (+ count 1) result))))))) -;;Ein Ausdruck als String +;;expression as string (define exp->string (lambda (exp) (let ((exp-port (open-output-string))) @@ -1296,8 +840,7 @@ -;;Ein Statement wird in Stücke zerlegt, so dass dann jedes Stück in eine -;;Zeile passt. +;;seperate a long line into pieces, each fitting into a smaller line. (define seperate-line (lambda (line width) (let loop ((new '()) @@ -1307,32 +850,9 @@ (if (equal? new '()) '("") new) - ;new (append (list old) new)) - ;(append (list old) new)) (let ((next-line (substring old 0 width)) (rest-old (substring old width (string-length old)))) (loop (cons next-line new) rest-old)))))) -; (define (with-fatal-error-handler* handler thunk) -; (call-with-current-continuation -; (lambda (accept) -; ((call-with-current-continuation -; (lambda (k) -; (with-handler (lambda (condition more) -; (if (error? condition) -; (call-with-current-continuation -; (lambda (decline) -; (k (lambda () (handler condition decline)))))) -; (more)) ; Keep looking for a handler. -; (lambda () (call-with-values thunk accept))))))))) - -; (define-syntax with-fatal-error-handler -; (syntax-rules () -; ((with-fatal-error-handler handler body ...) -; (with-fatal-error-handler* handler -; (lambda () body ...))))) - -; (run) - \ No newline at end of file