A first (buggy) version with a virtual console
This commit is contained in:
parent
8ae60787a7
commit
7d0c566c0b
|
@ -0,0 +1,91 @@
|
|||
(define-record-type console :console
|
||||
(really-make-console pty-in pty-out
|
||||
pause-channel resume-channel
|
||||
window terminal-buffer)
|
||||
console?
|
||||
(pty-in console-pty-in)
|
||||
(pty-out console-pty-out)
|
||||
(pause-channel console-pause-channel)
|
||||
(resume-channel console-resume-channel)
|
||||
(window console-window)
|
||||
(terminal-buffer console-terminal-buffer))
|
||||
|
||||
(define (make-console pty-in pty-out window terminal-buffer)
|
||||
(let ((pause-channel (make-channel))
|
||||
(resume-channel (make-channel)))
|
||||
(spawn-console-loop
|
||||
pause-channel resume-channel window terminal-buffer
|
||||
(make-channel-for-pty-out pty-in))
|
||||
(really-make-console
|
||||
pty-in pty-out pause-channel resume-channel
|
||||
window terminal-buffer)))
|
||||
|
||||
(define (make-channel-for-pty-out pty)
|
||||
(let ((channel (make-channel)))
|
||||
(spawn
|
||||
(lambda ()
|
||||
(debug-message "make-channel-for-pty-out " pty)
|
||||
(let lp ((c (read-char pty)))
|
||||
(if (not (eof-object? c))
|
||||
(begin
|
||||
(send channel c)
|
||||
(lp (read-char pty)))))))
|
||||
channel))
|
||||
|
||||
(define (spawn-console-loop
|
||||
pause-channel resume-channel
|
||||
window terminal-buffer pty-channel)
|
||||
(spawn
|
||||
(lambda ()
|
||||
(let lp ((paint? #t))
|
||||
(debug-message "spawn-console-loop " paint?)
|
||||
(select
|
||||
(wrap (receive-rv pause-channel)
|
||||
(lambda (ignore)
|
||||
(lp #f)))
|
||||
(wrap (receive-rv resume-channel)
|
||||
(lambda (ignore)
|
||||
(lp #t)))
|
||||
(wrap (receive-rv pty-channel)
|
||||
(lambda (char)
|
||||
(cond
|
||||
((eof-object? char)
|
||||
(lp paint?))
|
||||
(else
|
||||
(terminal-buffer-add-char terminal-buffer char)
|
||||
(if paint?
|
||||
(curses-paint-terminal-buffer
|
||||
terminal-buffer window))
|
||||
(lp paint?))))))))))
|
||||
|
||||
(define (pause-console-output console)
|
||||
(send (console-pause-channel console) 'ignore))
|
||||
|
||||
(define (resume-console-output console)
|
||||
(send (console-resume-channel console) 'ignore))
|
||||
|
||||
(define (view-console console)
|
||||
(debug-message "view-console " console)
|
||||
(curses-paint-terminal-buffer/complete
|
||||
(console-terminal-buffer console)
|
||||
(console-window console))
|
||||
(resume-console-output console)
|
||||
(spawn
|
||||
(lambda ()
|
||||
(sync
|
||||
(wrap (result-buffer-other-object-has-focus-rv)
|
||||
(lambda (ignore)
|
||||
(pause-console-output console)))))))
|
||||
|
||||
(define (make-console-viewer console buffer)
|
||||
(lambda (message)
|
||||
(case message
|
||||
((paint)
|
||||
(lambda (self win buffer have-focus?)
|
||||
(view-console console)))
|
||||
(else
|
||||
(lambda (self . more)
|
||||
self)))))
|
||||
|
||||
(register-plugin!
|
||||
(make-view-plugin make-console-viewer console?))
|
|
@ -105,3 +105,85 @@
|
|||
|
||||
(register-plugin!
|
||||
(make-view-plugin make-joblist-viewer list-of-jobs?))
|
||||
|
||||
;;; viewer for a single job viewer
|
||||
|
||||
(define (make-job-viewer job buffer)
|
||||
(let ((select-list #f)
|
||||
(num-cols
|
||||
(- (result-buffer-num-cols buffer) 1)))
|
||||
|
||||
(define (make-job-select-list job)
|
||||
(make-select-list
|
||||
(map
|
||||
(lambda (args)
|
||||
(make-unmarked-element
|
||||
(car args) #f
|
||||
(cut-to-size
|
||||
num-cols
|
||||
(apply string-append
|
||||
(append
|
||||
(list (fill-up-string 15 (cadr args)))
|
||||
(cddr args))))))
|
||||
(list
|
||||
(list (job-name->string (job-name job))
|
||||
"name:" (job-name->string (job-name job)))
|
||||
(list (if (job-end-time job)
|
||||
(number->string (job-status job)) #f)
|
||||
"status:"
|
||||
(if (job-end-time job)
|
||||
(number->string (job-status job))
|
||||
"-"))
|
||||
(list (job-start-time job)
|
||||
"start:"
|
||||
(short-date (job-start-time job)))
|
||||
(list (job-end-time job)
|
||||
"end:"
|
||||
(if (job-end-time job)
|
||||
(short-date (job-end-time job))
|
||||
"-"))
|
||||
(list #f "run status:"
|
||||
(symbol->string (job-run-status job)))
|
||||
(list (job-console job)
|
||||
"<View Console>" "")))
|
||||
(- (result-buffer-num-lines buffer) 1)))
|
||||
|
||||
(define (handle-key-press self key control-x-pressed?)
|
||||
(cond
|
||||
((= key (char->ascii #\g))
|
||||
(set! select-list (make-job-select-list job)))
|
||||
((= key (char->ascii #\newline))
|
||||
(select-list-selected-entry select-list))
|
||||
(else
|
||||
(set! select-list
|
||||
(select-list-handle-key-press select-list key))))
|
||||
self)
|
||||
|
||||
(set! select-list (make-job-select-list job))
|
||||
|
||||
(lambda (message)
|
||||
(case message
|
||||
|
||||
((paint)
|
||||
(lambda (self win buffer have-focus?)
|
||||
(mvwaddstr
|
||||
win 0 0
|
||||
(cut-to-size
|
||||
num-cols (string-append "Viewing job: "
|
||||
(job-name->string (job-name job)))))
|
||||
(paint-selection-list-at
|
||||
select-list 0 1 win buffer have-focus?)))
|
||||
|
||||
((key-press) handle-key-press)
|
||||
|
||||
((get-selection)
|
||||
(make-get-focus-object-method select-list))
|
||||
|
||||
((get-focus-object)
|
||||
(make-get-focus-object-method select-list))
|
||||
|
||||
(else
|
||||
(error "job viewer unknown message" message))))))
|
||||
|
||||
(register-plugin!
|
||||
(make-view-plugin make-job-viewer job?))
|
|
@ -1,12 +1,10 @@
|
|||
(define-record-type job :job
|
||||
(really-make-job name pty-in pty-out proc
|
||||
status
|
||||
start-time end-time
|
||||
run-status)
|
||||
(really-make-job name console
|
||||
proc status
|
||||
start-time end-time run-status)
|
||||
job?
|
||||
(name job-name)
|
||||
(pty-in job-pty-in)
|
||||
(pty-out job-pty-out)
|
||||
(console job-console)
|
||||
(proc job-proc)
|
||||
(status really-job-status)
|
||||
(start-time job-start-time)
|
||||
|
@ -17,9 +15,13 @@
|
|||
(lambda (r)
|
||||
`(job ,(job-name r) ,(job-run-status r))))
|
||||
|
||||
(define (make-job name pty-in pty-out proc)
|
||||
(define (make-job name pty-in pty-out terminal-buffer proc)
|
||||
(let ((job (really-make-job
|
||||
name pty-in pty-out proc (make-placeholder)
|
||||
name
|
||||
(make-console pty-in pty-out
|
||||
(app-window-curses-win (result-window))
|
||||
terminal-buffer)
|
||||
proc (make-placeholder)
|
||||
(date) #f 'running)))
|
||||
(spawn-job-status-surveillant job)
|
||||
(add-job! job)
|
||||
|
@ -62,6 +64,12 @@
|
|||
(define (continue-job job)
|
||||
(signal-process-group signal/cont job))
|
||||
|
||||
(define (pause-job-output job)
|
||||
(pause-console-output (job-console job)))
|
||||
|
||||
(define (resume-job-output job)
|
||||
(resume-console-output (job-console job)))
|
||||
|
||||
;; channels for communicating with the joblist surveillant
|
||||
|
||||
(define add-job-channel
|
||||
|
@ -70,6 +78,9 @@
|
|||
(define get-job-list-channel
|
||||
(make-channel))
|
||||
|
||||
(define clear-ready-jobs-channel
|
||||
(make-channel))
|
||||
|
||||
(define (add-job! job)
|
||||
(send add-job-channel job))
|
||||
|
||||
|
@ -83,6 +94,9 @@
|
|||
(send get-job-list-channel (cons 'ready answer-channel))
|
||||
(receive answer-channel)))
|
||||
|
||||
(define (clear-ready-jobs!)
|
||||
(send clear-ready-jobs-channel 'ignored))
|
||||
|
||||
(define (jobs-with-new-output)
|
||||
(let ((answer-channel (make-channel)))
|
||||
(send get-job-list-channel (cons 'new-output answer-channel))
|
||||
|
@ -119,6 +133,10 @@
|
|||
(lambda (new-job)
|
||||
(lp (cons new-job running)
|
||||
ready new-output waiting-for-input #t)))
|
||||
|
||||
(wrap (receive-rv clear-ready-jobs-channel)
|
||||
(lambda (ignore)
|
||||
(lp running '() new-output waiting-for-input #t)))
|
||||
|
||||
(wrap (receive-rv get-job-list-channel)
|
||||
(lambda (state.channel)
|
||||
|
@ -155,7 +173,7 @@
|
|||
(lambda args
|
||||
(display args))))
|
||||
|
||||
(define-syntax run-as-background-job
|
||||
(define-syntax run/bg
|
||||
(syntax-rules ()
|
||||
((_ epf)
|
||||
(call-with-values
|
||||
|
@ -164,6 +182,10 @@
|
|||
(lambda ()
|
||||
(exec-epf epf))))
|
||||
(lambda (proc pty-in pty-out tty-name)
|
||||
(make-job (quote epf) pty-in pty-out proc))))))
|
||||
(make-job (quote epf) pty-in pty-out
|
||||
(make-terminal-buffer
|
||||
(- (result-buffer-num-cols (result-buffer)) 1)
|
||||
(- (result-buffer-num-lines (result-buffer)) 1))
|
||||
proc))))))
|
||||
|
||||
;;; EOF
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
;; ,load /home/demattia/studium/studienarbeit/scsh-nuit/scheme/nuit-engine.scm
|
||||
|
||||
(define-syntax when
|
||||
(syntax-rules ()
|
||||
((_ ?test ?do-this ...)
|
||||
|
@ -16,83 +14,6 @@
|
|||
(release-lock lock)
|
||||
val)))))
|
||||
|
||||
;;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.
|
||||
|
||||
;;*************************************************************************
|
||||
;;State
|
||||
|
||||
(define-record-type app-window :app-window
|
||||
(make-app-window x y width height curses-win)
|
||||
app-window?
|
||||
(x app-window-x)
|
||||
(y app-window-y)
|
||||
(width app-window-width)
|
||||
(height app-window-height)
|
||||
(curses-win app-window-curses-win set-app-window-curses-win!))
|
||||
|
||||
(define-record-discloser :app-window
|
||||
(lambda (rec)
|
||||
`(app-window
|
||||
(x ,(app-window-x rec)) (y ,(app-window-y rec))
|
||||
(w ,(app-window-width rec)) (h ,(app-window-height rec)))))
|
||||
|
||||
(define bar-1 #f)
|
||||
(define active-command-window #f)
|
||||
|
||||
(define command-frame-window #f)
|
||||
(define command-window #f)
|
||||
|
||||
(define result-window #f)
|
||||
(define result-frame-window #f)
|
||||
|
||||
(define executable-completions-lock (make-lock))
|
||||
(define executable-completions #f)
|
||||
|
||||
(define paint-lock (make-lock))
|
||||
|
||||
(define key-control-x 24)
|
||||
(define key-o 111)
|
||||
(define key-tab 9)
|
||||
|
||||
;;state of the upper window (Command-Window)
|
||||
(define command-buffer
|
||||
(make-buffer '("Welcome to the scsh-ncurses-ui!" "")
|
||||
2 2 2 1 1
|
||||
0 0
|
||||
#t 1))
|
||||
|
||||
;;state of the lower window (Result-Window)
|
||||
;;----------------------------
|
||||
;;Text
|
||||
|
||||
(define result-buffer
|
||||
(make-result-buffer 0 0 0 0
|
||||
#f #f ; set in INIT-WINDOWS
|
||||
'() '()))
|
||||
|
||||
;;miscelaneous state
|
||||
;;-------------------
|
||||
|
||||
(define *focus-buffer* 'command-buffer)
|
||||
|
||||
(define (focus-on-command-buffer?)
|
||||
(eq? *focus-buffer* 'command-buffer))
|
||||
|
||||
(define (focus-command-buffer!)
|
||||
(set! *focus-buffer* 'command-buffer))
|
||||
|
||||
(define (focus-on-result-buffer?)
|
||||
(eq? *focus-buffer* 'result-buffer))
|
||||
|
||||
(define (focus-result-buffer!)
|
||||
(set! *focus-buffer* 'result-buffer))
|
||||
|
||||
;; mode of the command buffer
|
||||
(define *command-buffer-mode* 'scheme)
|
||||
|
||||
|
@ -108,6 +29,15 @@
|
|||
(define (enter-command-mode!)
|
||||
(set! *command-buffer-mode* 'command))
|
||||
|
||||
(define paint-lock (make-lock))
|
||||
|
||||
(define executable-completions-lock (make-lock))
|
||||
(define executable-completions #f)
|
||||
|
||||
(define key-control-x 24)
|
||||
(define key-o 111)
|
||||
(define key-tab 9)
|
||||
|
||||
;; History
|
||||
|
||||
(define history-pos 0)
|
||||
|
@ -214,7 +144,7 @@
|
|||
(refresh-result-window))
|
||||
(else
|
||||
(focus-command-buffer!)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window))))
|
||||
|
||||
(define (toggle-command/scheme-mode)
|
||||
|
@ -225,11 +155,11 @@
|
|||
(enter-command-mode!)))
|
||||
(paint-command-frame-window)
|
||||
(paint-command-window-contents)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window))
|
||||
|
||||
(define (handle-return-key)
|
||||
(let ((command-line (cadr (reverse (buffer-text command-buffer)))))
|
||||
(let ((command-line (cadr (reverse (buffer-text (command-buffer))))))
|
||||
(debug-message "command-line " command-line)
|
||||
(cond
|
||||
((string=? command-line "")
|
||||
|
@ -262,10 +192,11 @@
|
|||
(make-history-entry command args viewer)))
|
||||
;; FIXME, use insert here
|
||||
(append-to-history! new-entry)
|
||||
(signal-result-buffer-object-change)
|
||||
(obtain-lock paint-lock)
|
||||
(paint-result-window new-entry)
|
||||
(refresh-result-window)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(release-lock paint-lock)))
|
||||
|
||||
|
@ -280,10 +211,11 @@
|
|||
(make-history-entry command args viewer)))
|
||||
;; #### shouldn't we use some kind of insertion here?
|
||||
(append-to-history! new-entry)
|
||||
(signal-result-buffer-object-change)
|
||||
(obtain-lock paint-lock)
|
||||
(paint-result-window new-entry)
|
||||
(refresh-result-window)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(release-lock paint-lock))))
|
||||
|
||||
|
@ -295,9 +227,9 @@
|
|||
(send (current-viewer)
|
||||
'get-selection
|
||||
(command-buffer-in-scheme-mode?) (focus-table)))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window))
|
||||
|
||||
(define (paste-focus-object/refresh viewer)
|
||||
|
@ -308,15 +240,18 @@
|
|||
(command-buffer-in-scheme-mode?)
|
||||
(focus-table))
|
||||
(send (current-viewer) 'get-focus-object (focus-table))))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window))
|
||||
|
||||
;; handle input
|
||||
(define (run)
|
||||
|
||||
(init-screen)
|
||||
(init-windows!)
|
||||
(clear)
|
||||
|
||||
(init-executables-completion-set!)
|
||||
|
||||
;; init joblist
|
||||
|
@ -329,8 +264,8 @@
|
|||
(paint-command-frame-window)
|
||||
(paint-job-status-list stats)
|
||||
(paint-command-window-contents)
|
||||
(wrefresh (app-window-curses-win command-frame-window))
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(wrefresh (app-window-curses-win (command-frame-window)))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(release-lock paint-lock)
|
||||
(lp (cml-receive statistics-channel))))))
|
||||
|
@ -368,7 +303,7 @@
|
|||
((and (focus-on-command-buffer?)
|
||||
(= ch key-tab))
|
||||
(let ((maybe-selector
|
||||
(offer-completions (last (buffer-text command-buffer)))))
|
||||
(offer-completions (last (buffer-text (command-buffer))))))
|
||||
(loop (wait-for-input) #f maybe-selector)))
|
||||
|
||||
;; F7 toggle scheme-mode / command-mode (FIXME: find a better key)
|
||||
|
@ -422,6 +357,7 @@
|
|||
(obtain-lock paint-lock)
|
||||
(when (current-history-item)
|
||||
(paint-active-command-window)
|
||||
(signal-result-buffer-object-change)
|
||||
(paint-result-window (entry-data (current-history-item))))
|
||||
(refresh-result-window)
|
||||
(release-lock paint-lock)
|
||||
|
@ -433,18 +369,19 @@
|
|||
(obtain-lock paint-lock)
|
||||
(when (current-history-item)
|
||||
(paint-active-command-window)
|
||||
(signal-result-buffer-object-change)
|
||||
(paint-result-window (entry-data (current-history-item))))
|
||||
(refresh-result-window)
|
||||
(release-lock paint-lock)
|
||||
(loop (wait-for-input) c-x-pressed? #f))
|
||||
|
||||
((and (focus-on-command-buffer?) (= ch 10))
|
||||
(input command-buffer ch)
|
||||
(input (command-buffer) ch)
|
||||
(obtain-lock paint-lock)
|
||||
(werase (app-window-curses-win command-window))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(werase (app-window-curses-win (command-window)))
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(release-lock paint-lock)
|
||||
(handle-return-key)
|
||||
|
@ -459,78 +396,21 @@
|
|||
'key-press ch c-x-pressed?))
|
||||
(obtain-lock paint-lock)
|
||||
(paint-result-window (entry-data (current-history-item)))
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-result-window)
|
||||
(release-lock paint-lock))
|
||||
(loop (wait-for-input) #f #f))
|
||||
(else
|
||||
(input command-buffer ch)
|
||||
(input (command-buffer) ch)
|
||||
(obtain-lock paint-lock)
|
||||
(werase (app-window-curses-win command-window))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(werase (app-window-curses-win (command-window)))
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(release-lock paint-lock)
|
||||
(loop (wait-for-input) c-x-pressed? #f)))))))
|
||||
|
||||
(define (window-init-curses-win! window)
|
||||
(set-app-window-curses-win!
|
||||
window
|
||||
(newwin (app-window-height window) (app-window-width window)
|
||||
(app-window-y window) (app-window-x window))))
|
||||
|
||||
(define (make-inlying-app-window outer-window)
|
||||
(make-app-window (+ (app-window-x outer-window) 1)
|
||||
(+ (app-window-y outer-window) 1)
|
||||
(- (app-window-width outer-window) 2)
|
||||
(- (app-window-height outer-window) 2)
|
||||
#f))
|
||||
|
||||
(define (init-windows!)
|
||||
(init-screen)
|
||||
(set! bar-1
|
||||
(make-app-window 1 1
|
||||
(- (COLS) 2) 2
|
||||
#f))
|
||||
(set! active-command-window
|
||||
(make-app-window 1 (+ (round (/ (LINES) 3)) 2)
|
||||
(- (COLS) 2) 3
|
||||
#f))
|
||||
(set! command-frame-window
|
||||
(make-app-window 1 2
|
||||
(- (COLS) 2) (- (app-window-y active-command-window) 2)
|
||||
#f))
|
||||
(set! command-window
|
||||
(make-inlying-app-window command-frame-window))
|
||||
(set! result-frame-window
|
||||
(make-app-window 1 (+ (app-window-y active-command-window) 3)
|
||||
(- (COLS) 2)
|
||||
(- (- (LINES) 6) (app-window-height command-frame-window))
|
||||
#f))
|
||||
(set! result-window
|
||||
(make-inlying-app-window result-frame-window))
|
||||
|
||||
(let ((all-windows (list bar-1 active-command-window
|
||||
command-frame-window command-window
|
||||
result-frame-window result-window)))
|
||||
(for-each window-init-curses-win! all-windows)
|
||||
|
||||
(set-result-buffer-num-lines!
|
||||
result-buffer (- (app-window-height result-window) 2))
|
||||
(set-result-buffer-num-cols!
|
||||
result-buffer (- (app-window-width result-window) 3))
|
||||
|
||||
(debug-message "init-windows!: bar-1 " bar-1
|
||||
" active-command-window " active-command-window
|
||||
" command-frame-window " command-frame-window
|
||||
" command-window " command-window
|
||||
" result-frame-window " result-frame-window
|
||||
" result-window " result-window)
|
||||
(for-each wclear
|
||||
(map app-window-curses-win all-windows))
|
||||
(clear)))
|
||||
|
||||
(define (get-path-list)
|
||||
(cond
|
||||
((getenv "PATH")
|
||||
|
@ -548,8 +428,8 @@
|
|||
(make-completion-set-for-executables (get-path-list)))))))
|
||||
|
||||
(define (paint-bar-1)
|
||||
(mvwaddstr (app-window-curses-win bar-1) 0 1 "SCSH-NUIT")
|
||||
(wrefresh (app-window-curses-win bar-1)))
|
||||
(mvwaddstr (app-window-curses-win (bar-1)) 0 1 "SCSH-NUIT")
|
||||
(wrefresh (app-window-curses-win (bar-1))))
|
||||
|
||||
(define (paint-command-buffer-mode-indicator)
|
||||
(let ((mode-string
|
||||
|
@ -560,19 +440,19 @@
|
|||
"Scheme")
|
||||
" ]")))
|
||||
(mvwaddstr
|
||||
(app-window-curses-win command-frame-window)
|
||||
(app-window-curses-win (command-frame-window))
|
||||
0
|
||||
(- (- (app-window-width command-frame-window)
|
||||
(- (- (app-window-width (command-frame-window))
|
||||
(string-length mode-string))
|
||||
2)
|
||||
mode-string)))
|
||||
|
||||
(define (paint-command-frame-window)
|
||||
(box (app-window-curses-win command-frame-window)
|
||||
(box (app-window-curses-win (command-frame-window))
|
||||
(ascii->char 0) (ascii->char 0))
|
||||
(paint-command-buffer-mode-indicator)
|
||||
(paint-job-status-list)
|
||||
(wrefresh (app-window-curses-win command-frame-window)))
|
||||
(wrefresh (app-window-curses-win (command-frame-window))))
|
||||
|
||||
(define paint-job-status-list
|
||||
(let ((latest-statistics (initial-job-statistics)))
|
||||
|
@ -594,46 +474,46 @@
|
|||
(line (string-append "[ " stat " ]")))
|
||||
(set! latest-statistics statistics)
|
||||
(mvwaddstr
|
||||
(app-window-curses-win command-frame-window)
|
||||
(- (app-window-height command-frame-window) 1)
|
||||
(- (- (app-window-width command-frame-window)
|
||||
(app-window-curses-win (command-frame-window))
|
||||
(- (app-window-height (command-frame-window)) 1)
|
||||
(- (- (app-window-width (command-frame-window))
|
||||
(string-length line))
|
||||
2)
|
||||
line))))))
|
||||
|
||||
(define (paint-command-window-contents)
|
||||
(set-buffer-num-lines! command-buffer
|
||||
(- (app-window-height command-window) 2))
|
||||
(set-buffer-num-cols! command-buffer
|
||||
(- (app-window-width command-window) 3))
|
||||
(werase (app-window-curses-win command-window))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer))
|
||||
(set-buffer-num-lines! (command-buffer)
|
||||
(- (app-window-height (command-window)) 2))
|
||||
(set-buffer-num-cols! (command-buffer)
|
||||
(- (app-window-width (command-window)) 3))
|
||||
(werase (app-window-curses-win (command-window)))
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer)))
|
||||
|
||||
(define (refresh-command-window)
|
||||
(wrefresh (app-window-curses-win command-window)))
|
||||
(wrefresh (app-window-curses-win (command-window))))
|
||||
|
||||
(define (paint-result-frame-window)
|
||||
(let ((win (app-window-curses-win result-frame-window)))
|
||||
(let ((win (app-window-curses-win (result-frame-window))))
|
||||
(wclear win)
|
||||
(box win (ascii->char 0) (ascii->char 0))
|
||||
(wrefresh win)))
|
||||
|
||||
(define (paint-result-window entry)
|
||||
(let ((win (app-window-curses-win result-window)))
|
||||
(let ((win (app-window-curses-win (result-window))))
|
||||
(wclear win)
|
||||
(send (history-entry-viewer entry)
|
||||
'paint win result-buffer (focus-on-result-buffer?))))
|
||||
'paint win (result-buffer) (focus-on-result-buffer?))))
|
||||
|
||||
(define (refresh-result-window)
|
||||
(wrefresh (app-window-curses-win result-window)))
|
||||
(wrefresh (app-window-curses-win (result-window))))
|
||||
|
||||
(define (paint-result/command-buffer history-entry)
|
||||
(paint-result-window history-entry)
|
||||
(paint-active-command-window)
|
||||
(scroll-command-buffer)
|
||||
(paint-command-window-contents)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-result-window)
|
||||
(refresh-command-window))
|
||||
|
||||
|
@ -644,15 +524,15 @@
|
|||
(paint-active-command-window)
|
||||
(paint-result-frame-window)
|
||||
;(paint-result-window)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
(refresh-result-window))
|
||||
|
||||
(define (wait-for-input)
|
||||
(noecho)
|
||||
(keypad (app-window-curses-win bar-1) #t)
|
||||
(keypad (app-window-curses-win (bar-1)) #t)
|
||||
(set! active-keyboard-interrupt #f)
|
||||
(let ((ch (wgetch (app-window-curses-win bar-1))))
|
||||
(let ((ch (wgetch (app-window-curses-win (bar-1)))))
|
||||
(echo)
|
||||
ch))
|
||||
|
||||
|
@ -661,15 +541,15 @@
|
|||
((determine-plugin-by-type result)
|
||||
=> (lambda (view-plugin)
|
||||
((view-plugin-constructor view-plugin)
|
||||
result result-buffer)))
|
||||
result (result-buffer))))
|
||||
(else
|
||||
(make-standard-viewer result result-buffer))))
|
||||
(make-standard-viewer result (result-buffer)))))
|
||||
|
||||
;;scroll buffer after one command was entered
|
||||
(define (scroll-command-buffer)
|
||||
(set-buffer-pos-line! command-buffer
|
||||
(+ (buffer-pos-line command-buffer) 1))
|
||||
(set-buffer-pos-col! command-buffer 2))
|
||||
(set-buffer-pos-line! (command-buffer)
|
||||
(+ (buffer-pos-line (command-buffer)) 1))
|
||||
(set-buffer-pos-col! (command-buffer) 2))
|
||||
|
||||
(define (init-evaluation-environment package)
|
||||
(let ((structure (reify-structure package)))
|
||||
|
@ -685,9 +565,9 @@
|
|||
(lambda (exp)
|
||||
(with-fatal-and-capturing-error-handler
|
||||
(lambda (condition raw-continuation continuation decline)
|
||||
raw-continuation)
|
||||
raw-continuation)
|
||||
(lambda ()
|
||||
(eval (read-sexp-from-string exp) env))))))
|
||||
(eval (read-sexp-from-string exp) env))))))
|
||||
|
||||
(define (determine-plugin-by-type result)
|
||||
(find (lambda (r)
|
||||
|
@ -697,22 +577,22 @@
|
|||
;;Management of the upper buffer
|
||||
;;add a char to the buffer
|
||||
(define (add-to-command-buffer ch)
|
||||
(let* ((text (buffer-text command-buffer))
|
||||
(let* ((text (buffer-text (command-buffer)))
|
||||
(last-pos (- (length text) 1))
|
||||
(old-last-el (list-ref text last-pos))
|
||||
(old-rest (sublist text 0 last-pos))
|
||||
(before-ch (substring old-last-el 0
|
||||
(max 0 (- (buffer-pos-col command-buffer) 2))))
|
||||
(after-ch (substring old-last-el
|
||||
(max 0 (- (buffer-pos-col command-buffer) 2))
|
||||
(max 0 (- (buffer-pos-col (command-buffer)) 2))
|
||||
(string-length old-last-el)))
|
||||
(new-last-el (string-append before-ch
|
||||
(string (ascii->char ch))
|
||||
after-ch)))
|
||||
(set-buffer-text! command-buffer
|
||||
(set-buffer-text! (command-buffer)
|
||||
(append old-rest (list new-last-el)))
|
||||
(set-buffer-pos-col! command-buffer
|
||||
(+ (buffer-pos-col command-buffer) 1))))
|
||||
(set-buffer-pos-col! (command-buffer)
|
||||
(+ (buffer-pos-col (command-buffer)) 1))))
|
||||
|
||||
;;add a string to the buffer
|
||||
(define (add-string-to-command-buffer string)
|
||||
|
@ -731,8 +611,8 @@
|
|||
string))
|
||||
|
||||
(define (paint-active-command-window)
|
||||
(let ((win (app-window-curses-win active-command-window))
|
||||
(width (app-window-width active-command-window)))
|
||||
(let ((win (app-window-curses-win (active-command-window)))
|
||||
(width (app-window-width (active-command-window))))
|
||||
(wclear win)
|
||||
(box win (ascii->char 0) (ascii->char 0))
|
||||
(cond
|
||||
|
@ -749,14 +629,14 @@
|
|||
(cond
|
||||
((focus-on-command-buffer?)
|
||||
(cursor-right-pos
|
||||
(app-window-curses-win command-window)
|
||||
(app-window-curses-win (command-window))
|
||||
command-buffer))
|
||||
(else
|
||||
(compute-y-x result-buffer)
|
||||
(wmove (app-window-curses-win result-window)
|
||||
(wmove (app-window-curses-win (result-window))
|
||||
(result-buffer-y result-buffer)
|
||||
(result-buffer-x result-buffer))
|
||||
(wrefresh (app-window-curses-win result-window)))))
|
||||
(wrefresh (app-window-curses-win (result-window))))))
|
||||
|
||||
;;compue pos-x and pos-y
|
||||
(define (compute-y-x result-buffer)
|
||||
|
@ -875,26 +755,26 @@
|
|||
|
||||
(define (display-completed-line line cursor-pos)
|
||||
(debug-message "display-completed-line " line "," cursor-pos)
|
||||
(set-buffer-pos-col! command-buffer cursor-pos)
|
||||
(set-buffer-text! command-buffer
|
||||
(set-buffer-pos-col! (command-buffer) cursor-pos)
|
||||
(set-buffer-text! (command-buffer)
|
||||
(append
|
||||
(drop-right (buffer-text command-buffer) 1)
|
||||
(drop-right (buffer-text (command-buffer)) 1)
|
||||
(list line)))
|
||||
(wclrtoeol (app-window-curses-win command-window))
|
||||
(print-command-buffer (app-window-curses-win command-window)
|
||||
command-buffer)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(wclrtoeol (app-window-curses-win (command-window)))
|
||||
(print-command-buffer (app-window-curses-win (command-window))
|
||||
(command-buffer))
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window))
|
||||
|
||||
(define (paint-completion-select-list select-list command)
|
||||
(let ((win (app-window-curses-win result-window)))
|
||||
(let ((win (app-window-curses-win (result-window))))
|
||||
(wclear win)
|
||||
(wattron win (A-BOLD))
|
||||
(mvwaddstr win 0 0
|
||||
(string-append "Possible completions for " command))
|
||||
(wattrset win (A-NORMAL))
|
||||
(paint-selection-list-at select-list 0 2
|
||||
win result-buffer (focus-on-result-buffer?))
|
||||
win (result-buffer) (focus-on-result-buffer?))
|
||||
(refresh-result-window)))
|
||||
|
||||
;; #### implement me
|
||||
|
@ -923,7 +803,7 @@
|
|||
(if (not prefix)
|
||||
(error "could not determine token with cursor position"
|
||||
tokens/cursor-list command
|
||||
(- (buffer-pos-col command-buffer) 2)))
|
||||
(- (buffer-pos-col (command-buffer)) 2)))
|
||||
(let ((completions
|
||||
(call-completer command args
|
||||
prefix arg-pos)))
|
||||
|
@ -938,13 +818,13 @@
|
|||
(let* ((select-list
|
||||
(completions->select-list
|
||||
completions
|
||||
(- (result-buffer-num-lines result-buffer) 3)))
|
||||
(- (result-buffer-num-lines (result-buffer)) 3)))
|
||||
(selector
|
||||
(make-completion-selector
|
||||
select-list completions
|
||||
command args arg-pos)))
|
||||
(paint-completion-select-list select-list command)
|
||||
(move-cursor command-buffer result-buffer)
|
||||
(move-cursor (command-buffer) (result-buffer))
|
||||
(refresh-command-window)
|
||||
selector)))))))
|
||||
|
||||
|
@ -966,7 +846,7 @@
|
|||
(let ((new-select-list
|
||||
(select-list-handle-key-press select-list key)))
|
||||
(paint-completion-select-list
|
||||
new-select-list (last (buffer-text command-buffer)))
|
||||
new-select-list (last (buffer-text (command-buffer))))
|
||||
(make-completion-selector
|
||||
new-select-list completions command arg arg-pos)))
|
||||
(else
|
||||
|
@ -997,7 +877,7 @@
|
|||
(else (values chars i)))))
|
||||
|
||||
(define (tokenize-command command)
|
||||
(let ((cursor-pos (- (buffer-pos-col command-buffer) 2))) ;; don't ask
|
||||
(let ((cursor-pos (- (buffer-pos-col (command-buffer)) 2))) ;; don't ask
|
||||
(let lp ((chars (string->list command))
|
||||
(token "")
|
||||
(tokens '())
|
||||
|
|
|
@ -71,6 +71,52 @@
|
|||
ncurses)
|
||||
(files layout))
|
||||
|
||||
;;; windows and buffers
|
||||
|
||||
(define-interface app-windows-interface
|
||||
(export make-app-window
|
||||
app-window?
|
||||
app-window-x
|
||||
app-window-y
|
||||
app-window-height
|
||||
app-window-width
|
||||
app-window-curses-win))
|
||||
|
||||
(define-interface nuit-windows-interface
|
||||
(export bar-1
|
||||
active-command-window
|
||||
command-frame-window
|
||||
command-window
|
||||
result-window
|
||||
result-frame-window
|
||||
command-buffer
|
||||
result-buffer
|
||||
focus-on-command-buffer?
|
||||
focus-command-buffer!
|
||||
focus-on-result-buffer?
|
||||
focus-result-buffer!
|
||||
init-windows!))
|
||||
|
||||
(define-interface result-buffer-changes-interface
|
||||
(export result-buffer-other-object-has-focus-rv
|
||||
signal-result-buffer-object-change))
|
||||
|
||||
(define-structures
|
||||
((app-windows app-windows-interface)
|
||||
(nuit-windows nuit-windows-interface)
|
||||
(result-buffer-changes result-buffer-changes-interface))
|
||||
(open scheme
|
||||
define-record-types
|
||||
threads
|
||||
|
||||
rendezvous
|
||||
rendezvous-channels
|
||||
|
||||
ncurses
|
||||
tty-debug
|
||||
layout)
|
||||
(files win))
|
||||
|
||||
;;; process viewer plugin
|
||||
|
||||
(define-structure process-viewer
|
||||
|
@ -129,6 +175,25 @@
|
|||
tty-debug)
|
||||
(files browse-directory-list))
|
||||
|
||||
;;; terminal buffer
|
||||
|
||||
(define-interface terminal-buffer-interface
|
||||
(export make-terminal-buffer
|
||||
terminal-buffer?
|
||||
terminal-buffer-add-char
|
||||
curses-paint-terminal-buffer
|
||||
curses-paint-terminal-buffer/complete))
|
||||
|
||||
(define-structure terminal-buffer terminal-buffer-interface
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
define-record-types
|
||||
signals
|
||||
|
||||
ncurses
|
||||
tty-debug)
|
||||
(files termbuf))
|
||||
|
||||
;;; standard command plugin
|
||||
|
||||
(define-structure standard-command-plugin
|
||||
|
@ -226,6 +291,7 @@
|
|||
signals
|
||||
|
||||
objects
|
||||
console
|
||||
jobs
|
||||
ncurses
|
||||
focus-table
|
||||
|
@ -275,6 +341,7 @@
|
|||
let-opt
|
||||
srfi-1
|
||||
|
||||
terminal-buffer
|
||||
jobs
|
||||
focus-table
|
||||
fs-object
|
||||
|
@ -354,6 +421,30 @@
|
|||
thread-fluids)
|
||||
(files complete))
|
||||
|
||||
;;; console
|
||||
|
||||
(define-interface console-interface
|
||||
(export
|
||||
make-console
|
||||
console?
|
||||
view-console
|
||||
pause-console-output
|
||||
resume-console-output))
|
||||
|
||||
(define-structure console console-interface
|
||||
(open (modify scheme-with-scsh
|
||||
(hide receive select))
|
||||
define-record-types
|
||||
threads
|
||||
rendezvous
|
||||
rendezvous-channels
|
||||
|
||||
plugin
|
||||
tty-debug
|
||||
result-buffer-changes
|
||||
terminal-buffer)
|
||||
(files console))
|
||||
|
||||
;;; jobs and joblist
|
||||
|
||||
(define-interface job-interface
|
||||
|
@ -370,11 +461,19 @@
|
|||
job-end-time
|
||||
job-proc
|
||||
job-name
|
||||
job-run-status
|
||||
job-console
|
||||
|
||||
running-jobs
|
||||
ready-jobs
|
||||
clear-ready-jobs!
|
||||
jobs-with-new-output
|
||||
jobs-waiting-for-input
|
||||
|
||||
signal-job
|
||||
stop-job
|
||||
continue-job
|
||||
(run-as-background-job :syntax)))
|
||||
(run/bg :syntax)))
|
||||
|
||||
(define-interface joblist-interface
|
||||
(export running-jobs
|
||||
|
@ -395,7 +494,14 @@
|
|||
|
||||
rendezvous
|
||||
rendezvous-channels
|
||||
rendezvous-placeholders)
|
||||
rendezvous-placeholders
|
||||
|
||||
terminal-buffer
|
||||
nuit-windows
|
||||
app-windows
|
||||
layout
|
||||
|
||||
console)
|
||||
(files job))
|
||||
|
||||
;;; nuit
|
||||
|
@ -429,7 +535,11 @@
|
|||
(receive cml-receive)))
|
||||
let-opt
|
||||
|
||||
app-windows
|
||||
nuit-windows
|
||||
|
||||
focus-table
|
||||
result-buffer-changes
|
||||
nuit-eval/focus-table
|
||||
fs-object
|
||||
objects
|
||||
|
|
|
@ -146,10 +146,18 @@
|
|||
|
||||
(register-plugin!
|
||||
(make-command-plugin "jobs"
|
||||
no-completer
|
||||
(lambda (command prefix args arg-pos)
|
||||
'("running" "ready" "output" "waiting-for-input"))
|
||||
(lambda (command args)
|
||||
(append
|
||||
(running-jobs) (ready-jobs)
|
||||
(jobs-with-new-output)
|
||||
(jobs-waiting-for-input)))))
|
||||
|
||||
(append-map
|
||||
(lambda (arg)
|
||||
;; #### warn if argument is unknown
|
||||
(cond
|
||||
((assoc arg
|
||||
`(("running" . ,running-jobs)
|
||||
("ready" . ,ready-jobs)
|
||||
("output" . ,jobs-with-new-output)
|
||||
("input" . ,jobs-waiting-for-input)))
|
||||
=> (lambda (p)
|
||||
((cdr p))))))
|
||||
(delete-duplicates args)))))
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
(define-record-type terminal-buffer :terminal-buffer
|
||||
(really-make-terminal-buffer width height view-index
|
||||
x y buffer repaint?
|
||||
esc-code)
|
||||
terminal-buffer?
|
||||
(width terminal-buffer-width)
|
||||
(height terminal-buffer-height)
|
||||
(view-index terminal-buffer-view-index
|
||||
set-terminal-buffer-view-index!)
|
||||
(x terminal-buffer-x set-terminal-buffer-x!)
|
||||
(y terminal-buffer-y set-terminal-buffer-y!)
|
||||
(buffer terminal-buffer-buffer set-terminal-buffer-buffer!)
|
||||
(repaint? terminal-buffer-repaint? set-terminal-buffer-repaint?!)
|
||||
(esc-code terminal-buffer-esc-code set-terminal-buffer-esc-code!))
|
||||
|
||||
(define-record-discloser :terminal-buffer
|
||||
(lambda (tb)
|
||||
`(terminal-buffer
|
||||
(width ,(terminal-buffer-width tb))
|
||||
(height ,(terminal-buffer-height tb))
|
||||
(x ,(terminal-buffer-x tb))
|
||||
(y ,(terminal-buffer-y tb))
|
||||
(repaint? ,(terminal-buffer-repaint? tb))
|
||||
(esc-code ,(map char->ascii (string->list (terminal-buffer-esc-code tb)))))))
|
||||
|
||||
(define (make-terminal-buffer width height)
|
||||
(let ((buffer (map
|
||||
(lambda (ignore)
|
||||
(make-empty-line width))
|
||||
(iota height))))
|
||||
(really-make-terminal-buffer width height buffer
|
||||
0 0 buffer #f "")))
|
||||
|
||||
(define (line-at-cursor-position termbuf)
|
||||
(list-ref (terminal-buffer-view-index termbuf)
|
||||
(terminal-buffer-y termbuf)))
|
||||
|
||||
(define (make-empty-line width)
|
||||
(make-string width #\space))
|
||||
|
||||
(define (cursor-at-end-of-line? termbuf)
|
||||
(= (terminal-buffer-x termbuf)
|
||||
(- (terminal-buffer-width termbuf) 1)))
|
||||
|
||||
(define (cursor-on-last-line? termbuf)
|
||||
(= (terminal-buffer-y termbuf)
|
||||
(- (terminal-buffer-height termbuf) 1)))
|
||||
|
||||
(define (append-empty-line termbuf)
|
||||
(debug-message "append-empty-line")
|
||||
(append! (terminal-buffer-buffer termbuf)
|
||||
(list (make-empty-line (terminal-buffer-width termbuf)))))
|
||||
|
||||
(define (goto-next-line termbuf)
|
||||
(debug-message "goto-next-line")
|
||||
(set-terminal-buffer-y!
|
||||
termbuf (+ (terminal-buffer-y termbuf) 1))
|
||||
(maybe-scroll-terminal-buffer termbuf))
|
||||
|
||||
(define (move-cursor termbuf x-offset y-offset)
|
||||
(debug-message "move-cursor " termbuf " " x-offset " " y-offset)
|
||||
(let ((new-x (+ (terminal-buffer-x termbuf) x-offset))
|
||||
(new-y (+ (terminal-buffer-y termbuf) y-offset)))
|
||||
|
||||
(cond
|
||||
((< new-x 0)
|
||||
(set-terminal-buffer-x! termbuf 0))
|
||||
((>= new-x (terminal-buffer-width termbuf))
|
||||
(set-terminal-buffer-x!
|
||||
termbuf (- (terminal-buffer-width termbuf) 1)))
|
||||
(else
|
||||
(set-terminal-buffer-x! termbuf new-x)))
|
||||
|
||||
(cond
|
||||
((< new-y 0)
|
||||
(set-terminal-buffer-y! termbuf 0))
|
||||
((>= new-y (terminal-buffer-width termbuf))
|
||||
(set-terminal-buffer-y!
|
||||
(termbuf (- (terminal-buffer-width termbuf) 1))))
|
||||
(else
|
||||
(set-terminal-buffer-y! termbuf new-y)))))
|
||||
|
||||
(define (scroll-view-index-down termbuf)
|
||||
(set-terminal-buffer-view-index!
|
||||
termbuf (cdr (terminal-buffer-view-index termbuf)))
|
||||
(set-terminal-buffer-repaint?! termbuf #t))
|
||||
|
||||
(define (maybe-scroll-terminal-buffer termbuf)
|
||||
(debug-message "maybe-scroll-terminal-buffer")
|
||||
(and (>= (terminal-buffer-y termbuf)
|
||||
(terminal-buffer-height termbuf))
|
||||
(begin
|
||||
(scroll-view-index-down termbuf)
|
||||
(set-terminal-buffer-y!
|
||||
termbuf
|
||||
(- (terminal-buffer-y termbuf) 1)))))
|
||||
|
||||
(define (goto-beginning-of-line termbuf)
|
||||
(debug-message "goto-beginning-of-line")
|
||||
(set-terminal-buffer-x! termbuf 0))
|
||||
|
||||
(define (terminal-buffer-add-char termbuf char)
|
||||
(debug-message "add-char " termbuf)
|
||||
(cond
|
||||
((not (string=? "" (terminal-buffer-esc-code termbuf)))
|
||||
(read-escape-code termbuf char))
|
||||
((char=? char (ascii->char 27))
|
||||
(set-terminal-buffer-esc-code! termbuf (string char)))
|
||||
((char=? char #\newline)
|
||||
(if (cursor-on-last-line? termbuf)
|
||||
(append-empty-line termbuf))
|
||||
(goto-next-line termbuf)
|
||||
(goto-beginning-of-line termbuf))
|
||||
(else
|
||||
(add-normal-char termbuf char))))
|
||||
|
||||
(define (add-normal-char termbuf char)
|
||||
(cond
|
||||
((cursor-at-end-of-line? termbuf)
|
||||
(append-empty-line termbuf)
|
||||
(goto-next-line termbuf)
|
||||
(goto-beginning-of-line termbuf)
|
||||
(insert-char termbuf char))
|
||||
(else
|
||||
(insert-char termbuf char)
|
||||
(goto-next-char termbuf))))
|
||||
|
||||
(define (curses-paint-terminal-buffer termbuf win)
|
||||
(if (terminal-buffer-repaint? termbuf)
|
||||
(clear/repaint-buffer termbuf win)
|
||||
(paint-single-line termbuf win)))
|
||||
|
||||
(define (clear/repaint-buffer termbuf win)
|
||||
(debug-message "clear/repaint-buffer")
|
||||
(wclear win)
|
||||
(let lp ((i (terminal-buffer-height termbuf))
|
||||
(lines (terminal-buffer-view-index termbuf))
|
||||
(y 0))
|
||||
(if (zero? i)
|
||||
'blorf
|
||||
(begin
|
||||
(mvwaddstr win y 0 (car lines))
|
||||
(lp (- i 1) (cdr lines) (+ y 1)))))
|
||||
(position-cursor termbuf win))
|
||||
|
||||
(define curses-paint-terminal-buffer/complete
|
||||
clear/repaint-buffer)
|
||||
|
||||
(define (paint-single-line termbuf win)
|
||||
(debug-message "paint-single-line " termbuf)
|
||||
(wclrtoeol win)
|
||||
(mvwaddstr win
|
||||
(terminal-buffer-y termbuf) 0
|
||||
(line-at-cursor-position termbuf))
|
||||
(position-cursor termbuf win))
|
||||
|
||||
(define (position-cursor termbuf win)
|
||||
(wmove win
|
||||
(terminal-buffer-y termbuf)
|
||||
(terminal-buffer-x termbuf)))
|
||||
|
||||
(define (insert-char termbuf char)
|
||||
(string-set! (line-at-cursor-position termbuf)
|
||||
(terminal-buffer-x termbuf)
|
||||
char))
|
||||
|
||||
(define (goto-next-char termbuf)
|
||||
(set-terminal-buffer-x!
|
||||
termbuf (+ 1 (terminal-buffer-x termbuf))))
|
||||
|
||||
(define (read-escape-code termbuf char)
|
||||
(debug-message "read-escape-code " (char->ascii char) " " termbuf)
|
||||
(let ((code (string-append
|
||||
(terminal-buffer-esc-code termbuf)
|
||||
(string char))))
|
||||
(cond
|
||||
;; very ugly hack
|
||||
((> (string-length code) 5)
|
||||
(set-terminal-buffer-esc-code! termbuf ""))
|
||||
((recognize-simple-cursor-movement code)
|
||||
=> (lambda (lst)
|
||||
(apply move-cursor (cons termbuf lst))
|
||||
(set-terminal-buffer-esc-code! termbuf "")))
|
||||
((recognize-cursor-movement code)
|
||||
=> (lambda (lst)
|
||||
(apply move-cursor (cons termbuf lst))
|
||||
(set-terminal-buffer-esc-code! termbuf "")))
|
||||
(else
|
||||
(set-terminal-buffer-esc-code! termbuf code)))))
|
||||
|
||||
(define (recognize-cursor-movement partial-code)
|
||||
(debug-message "recognize-cursor-movement " partial-code)
|
||||
(if-match
|
||||
(regexp-search (rx (: ,(ascii->char 27)
|
||||
#\[ (submatch digit) (submatch ("ABCD"))
|
||||
eos))
|
||||
partial-code)
|
||||
(whole-code count direction)
|
||||
(cond
|
||||
((string=? direction "A")
|
||||
(list 0 (- (string->number count))))
|
||||
((string=? direction "B")
|
||||
(list 0 (string->number count)))
|
||||
((string=? direction "C")
|
||||
(list (string->number count) 0))
|
||||
((string=? direction "D")
|
||||
(list (- (string->number count)) 0))
|
||||
(else (error 'gnarf direction)))
|
||||
#f))
|
||||
|
||||
(define (recognize-simple-cursor-movement partial-code)
|
||||
(debug-message "recognize-simple-cursor-movement ")
|
||||
(if-match
|
||||
(regexp-search (rx (: ,(ascii->char 27) (? #\[) (? #\O) (submatch ("ABCD")) eos))
|
||||
partial-code)
|
||||
(whole-code direction)
|
||||
(cond
|
||||
((string=? direction "A") '( 0 -1))
|
||||
((string=? direction "B") '( 0 1))
|
||||
((string=? direction "C") '( 1 0))
|
||||
((string=? direction "D") '(-1 0))
|
||||
(else (error 'gnarf2 (string? direction) (char? direction) )))
|
||||
(begin (debug-message "does not match ") #f)))
|
|
@ -0,0 +1,147 @@
|
|||
(define-record-type app-window :app-window
|
||||
(make-app-window x y width height curses-win)
|
||||
app-window?
|
||||
(x app-window-x)
|
||||
(y app-window-y)
|
||||
(width app-window-width)
|
||||
(height app-window-height)
|
||||
(curses-win app-window-curses-win set-app-window-curses-win!))
|
||||
|
||||
(define-record-discloser :app-window
|
||||
(lambda (rec)
|
||||
`(app-window
|
||||
(x ,(app-window-x rec)) (y ,(app-window-y rec))
|
||||
(w ,(app-window-width rec)) (h ,(app-window-height rec)))))
|
||||
|
||||
(define *bar-1* #f)
|
||||
(define (bar-1) *bar-1*)
|
||||
|
||||
(define *active-command-window* #f)
|
||||
(define (active-command-window) *active-command-window*)
|
||||
|
||||
(define *command-frame-window* #f)
|
||||
(define (command-frame-window) *command-frame-window*)
|
||||
|
||||
(define *command-window* #f)
|
||||
(define (command-window) *command-window*)
|
||||
|
||||
(define *result-window* #f)
|
||||
(define (result-window) *result-window*)
|
||||
|
||||
(define *result-frame-window* #f)
|
||||
(define (result-frame-window) *result-frame-window*)
|
||||
|
||||
(define *command-buffer*
|
||||
(make-buffer '("Welcome to the scsh-ncurses-ui!" "")
|
||||
2 2 2 1 1
|
||||
0 0
|
||||
#t 1))
|
||||
|
||||
(define (command-buffer) *command-buffer*)
|
||||
|
||||
(define *result-buffer*
|
||||
(make-result-buffer 0 0 0 0
|
||||
#f #f ; set in INIT-WINDOWS
|
||||
'() '()))
|
||||
|
||||
(define (result-buffer) *result-buffer*)
|
||||
|
||||
(define *focus-buffer* 'command-buffer)
|
||||
|
||||
(define (focus-on-command-buffer?)
|
||||
(eq? *focus-buffer* 'command-buffer))
|
||||
|
||||
(define (focus-command-buffer!)
|
||||
(set! *focus-buffer* 'command-buffer))
|
||||
|
||||
(define (focus-on-result-buffer?)
|
||||
(eq? *focus-buffer* 'result-buffer))
|
||||
|
||||
(define (focus-result-buffer!)
|
||||
(set! *focus-buffer* 'result-buffer))
|
||||
|
||||
(define (make-inlying-app-window outer-window)
|
||||
(make-app-window (+ (app-window-x outer-window) 1)
|
||||
(+ (app-window-y outer-window) 1)
|
||||
(- (app-window-width outer-window) 2)
|
||||
(- (app-window-height outer-window) 2)
|
||||
#f))
|
||||
|
||||
(define (window-init-curses-win! window)
|
||||
(set-app-window-curses-win!
|
||||
window
|
||||
(newwin (app-window-height window) (app-window-width window)
|
||||
(app-window-y window) (app-window-x window))))
|
||||
|
||||
(define (init-windows!)
|
||||
(set! *bar-1*
|
||||
(make-app-window 1 1
|
||||
(- (COLS) 2) 2
|
||||
#f))
|
||||
(set! *active-command-window*
|
||||
(make-app-window 1 (+ (round (/ (LINES) 3)) 2)
|
||||
(- (COLS) 2) 3
|
||||
#f))
|
||||
(set! *command-frame-window*
|
||||
(make-app-window 1 2
|
||||
(- (COLS) 2) (- (app-window-y (active-command-window)) 2)
|
||||
#f))
|
||||
(set! *command-window*
|
||||
(make-inlying-app-window (command-frame-window)))
|
||||
(set! *result-frame-window*
|
||||
(make-app-window 1 (+ (app-window-y (active-command-window)) 3)
|
||||
(- (COLS) 2)
|
||||
(- (- (LINES) 6) (app-window-height (command-frame-window)))
|
||||
#f))
|
||||
(set! *result-window*
|
||||
(make-inlying-app-window (result-frame-window)))
|
||||
|
||||
(let ((all-windows
|
||||
(list (bar-1) (active-command-window)
|
||||
(command-frame-window) (command-window)
|
||||
(result-frame-window) (result-window))))
|
||||
(for-each window-init-curses-win! all-windows)
|
||||
|
||||
(set-result-buffer-num-lines!
|
||||
*result-buffer* (- (app-window-height (result-window)) 2))
|
||||
(set-result-buffer-num-cols!
|
||||
*result-buffer* (- (app-window-width (result-window)) 3))
|
||||
|
||||
(for-each wclear
|
||||
(map app-window-curses-win all-windows))))
|
||||
|
||||
;; result-buffer-object-change-channel
|
||||
|
||||
(define result-buffer-changed-channel
|
||||
(make-channel))
|
||||
|
||||
(define result-buffer-changes-subscribers
|
||||
(make-channel))
|
||||
|
||||
(define (signal-result-buffer-object-change)
|
||||
(debug-message "signal-result-buffer-object-change")
|
||||
(send result-buffer-changed-channel 'ignore))
|
||||
|
||||
(define (spawn-result-buffer-surveillant)
|
||||
(spawn
|
||||
(lambda ()
|
||||
(let lp ()
|
||||
(select
|
||||
(wrap (receive-rv result-buffer-changes-subscribers)
|
||||
(lambda (answer-channel)
|
||||
(debug-message "result-buffer-surveillant "
|
||||
answer-channel)
|
||||
(receive result-buffer-changed-channel)
|
||||
(send answer-channel 'ignore)
|
||||
(lp)))
|
||||
(wrap (receive-rv result-buffer-changed-channel)
|
||||
(lambda (ignore)
|
||||
(debug-message "result-buffer-surveillant")
|
||||
(lp))))))))
|
||||
|
||||
(define (result-buffer-other-object-has-focus-rv)
|
||||
(let ((answer-channel (make-channel)))
|
||||
(send result-buffer-changes-subscribers answer-channel)
|
||||
(receive-rv answer-channel)))
|
||||
|
||||
(spawn-result-buffer-surveillant)
|
Loading…
Reference in New Issue