2005-05-17 05:56:11 -04:00
|
|
|
(define key-m 109)
|
|
|
|
(define key-u 117)
|
2005-05-26 07:35:17 -04:00
|
|
|
(define key-return 10)
|
|
|
|
|
|
|
|
(define-record-type filelist-state :filelist-state
|
2005-05-27 17:32:21 -04:00
|
|
|
(make-filelist-state files select-list working-dir)
|
2005-05-26 07:35:17 -04:00
|
|
|
filelist-state?
|
|
|
|
(files filelist-state-files)
|
|
|
|
(select-list filelist-state-select-list)
|
2005-05-27 17:32:21 -04:00
|
|
|
(working-dir filelist-state-working-dir))
|
2005-05-26 07:35:17 -04:00
|
|
|
|
|
|
|
(define-record-discloser :filelist-state
|
|
|
|
(lambda (r)
|
|
|
|
`(filelist-state ,(filelist-state-working-dir r)
|
|
|
|
,(filelist-state-files r))))
|
|
|
|
|
2005-05-27 17:32:21 -04:00
|
|
|
(define (add-marks-to-special-file file-name fs-object)
|
|
|
|
(let ((info (fs-object-info fs-object)))
|
2005-05-26 07:35:17 -04:00
|
|
|
(cond
|
2005-05-27 05:53:06 -04:00
|
|
|
((not info)
|
2005-05-27 17:32:21 -04:00
|
|
|
(string-append " " file-name ": error during file-info!"))
|
2005-05-26 07:35:17 -04:00
|
|
|
((file-info-directory? info)
|
2005-05-27 17:32:21 -04:00
|
|
|
(string-append " " file-name "/"))
|
2005-05-26 07:35:17 -04:00
|
|
|
((file-info-executable? info)
|
2005-05-27 17:32:21 -04:00
|
|
|
(string-append "*" file-name))
|
2005-05-26 07:35:17 -04:00
|
|
|
((file-info-symlink? info)
|
2005-05-27 17:32:21 -04:00
|
|
|
(string-append "@" file-name))
|
2005-05-26 07:35:17 -04:00
|
|
|
(else
|
2005-05-27 17:32:21 -04:00
|
|
|
(string-append " " file-name)))))
|
2005-05-26 07:35:17 -04:00
|
|
|
|
|
|
|
;; leave one line for the heading
|
|
|
|
(define (calculate-number-of-lines result-buffer)
|
|
|
|
(- (result-buffer-num-lines result-buffer)
|
|
|
|
1))
|
|
|
|
|
2005-05-27 17:32:21 -04:00
|
|
|
(define (layout-fsobject parent-dir-len fsobject)
|
|
|
|
(let ((file-name (combine-path (string-drop
|
|
|
|
(fs-object-path fsobject)
|
|
|
|
parent-dir-len)
|
|
|
|
(fs-object-name fsobject))))
|
|
|
|
(add-marks-to-special-file file-name fsobject)))
|
|
|
|
|
|
|
|
(define (make-file-select-list fsobjects parent-dir num-lines)
|
|
|
|
(let ((parent-dir-len (string-length parent-dir)))
|
|
|
|
(make-select-list
|
|
|
|
(cons (make-unmarked-element 'parent-dir #f " ..")
|
|
|
|
(map (lambda (fs-object)
|
|
|
|
(make-unmarked-element
|
|
|
|
fs-object #t (layout-fsobject parent-dir-len fs-object)))
|
|
|
|
fsobjects))
|
|
|
|
num-lines)))
|
2005-05-26 07:35:17 -04:00
|
|
|
|
|
|
|
;;; lacks some coolness
|
|
|
|
(define (abbrev-path path length)
|
|
|
|
(if (< (string-length path) length)
|
|
|
|
path
|
|
|
|
(string-copy path
|
|
|
|
(- (string-length path) length))))
|
|
|
|
|
|
|
|
(define header-line-path
|
|
|
|
"Paths relative to ")
|
|
|
|
|
|
|
|
(define (make-header-line state width)
|
|
|
|
(let ((dir (filelist-state-working-dir state)))
|
|
|
|
(string-append
|
|
|
|
header-line-path
|
|
|
|
(if dir
|
|
|
|
(abbrev-path
|
|
|
|
dir (- width (string-length header-line-path)))
|
|
|
|
"<unknown>"))))
|
|
|
|
|
|
|
|
(define (paint-browser state)
|
|
|
|
(lambda (win result-buffer have-focus?)
|
|
|
|
(wattron win (A-BOLD))
|
|
|
|
(mvwaddstr win 0 0
|
|
|
|
(make-header-line
|
|
|
|
state (result-buffer-num-cols result-buffer)))
|
|
|
|
(wattrset win (A-NORMAL))
|
|
|
|
((paint-selection-list-at
|
|
|
|
(filelist-state-select-list state) 1 2)
|
|
|
|
win result-buffer have-focus?)))
|
|
|
|
|
|
|
|
(define (make-browser-for-dir dir num-lines)
|
|
|
|
(with-cwd dir
|
|
|
|
(let ((fs-objects (directory-files)))
|
|
|
|
(make-filelist-state
|
2005-05-27 17:32:21 -04:00
|
|
|
fs-objects (make-file-select-list fs-objects (cwd) num-lines)
|
|
|
|
(cwd)))))
|
|
|
|
|
|
|
|
(define (make-browser-for-fs-objects fs-objects num-lines)
|
|
|
|
(let ((parent-dir (find-common-parent (map fs-object-path fs-objects))))
|
|
|
|
(make-filelist-state
|
|
|
|
fs-objects
|
|
|
|
(make-file-select-list fs-objects parent-dir num-lines)
|
|
|
|
parent-dir)))
|
|
|
|
|
|
|
|
(define (find-common-parent paths)
|
|
|
|
(if (null? paths)
|
|
|
|
""
|
|
|
|
(let lp ((paths (cdr paths))
|
|
|
|
(common (car paths))
|
|
|
|
(common-len (string-length (car paths))))
|
|
|
|
(if (null? paths)
|
|
|
|
common
|
|
|
|
(let ((prefix-len (string-prefix-length common (car paths))))
|
|
|
|
(cond
|
|
|
|
((= 0 prefix-len) (error "no prefix??" common (car paths)))
|
|
|
|
((= 1 prefix-len) "/") ; search ends here
|
|
|
|
((= prefix-len common-len) ; short cut
|
|
|
|
(lp (cdr paths)
|
|
|
|
common
|
|
|
|
common-len))
|
|
|
|
(else
|
|
|
|
(lp (cdr paths)
|
|
|
|
(substring common
|
|
|
|
0
|
|
|
|
prefix-len)
|
|
|
|
prefix-len))))))))
|
2005-05-26 07:35:17 -04:00
|
|
|
|
|
|
|
(define (handle-return-key state selected-entry num-lines)
|
|
|
|
(cond
|
|
|
|
((eq? selected-entry 'parent-dir)
|
|
|
|
(let* ((maybe-parent
|
|
|
|
(file-name-directory (filelist-state-working-dir state)))
|
|
|
|
(parent (if (string=? maybe-parent "") "/" maybe-parent)))
|
|
|
|
(make-browser-for-dir parent num-lines)))
|
|
|
|
(else
|
|
|
|
(let ((fi (fs-object-info selected-entry)))
|
2005-05-27 05:53:06 -04:00
|
|
|
(if (and fi (file-info-directory? fi))
|
2005-05-27 17:32:21 -04:00
|
|
|
(with-errno-handler
|
|
|
|
((errno packet)
|
|
|
|
(else
|
|
|
|
(display packet)
|
|
|
|
(newline)
|
|
|
|
state))
|
|
|
|
(make-browser-for-dir (fs-object-complete-path selected-entry)
|
|
|
|
num-lines))
|
2005-05-26 07:35:17 -04:00
|
|
|
state)))))
|
|
|
|
|
|
|
|
(define (handle-key-press message)
|
|
|
|
(let* ((state (message-result-object message))
|
|
|
|
(select-list (filelist-state-select-list state))
|
|
|
|
(key (key-pressed-message-key message)))
|
|
|
|
(cond
|
|
|
|
((= key key-return)
|
|
|
|
(handle-return-key
|
|
|
|
state (select-list-selected-entry select-list)
|
|
|
|
(calculate-number-of-lines
|
|
|
|
(key-pressed-message-result-buffer message))))
|
|
|
|
(else
|
|
|
|
(make-filelist-state
|
|
|
|
(filelist-state-files state)
|
|
|
|
(select-list-handle-key-press
|
|
|
|
(filelist-state-select-list state) message)
|
2005-05-27 17:32:21 -04:00
|
|
|
(filelist-state-working-dir state))))))
|
2005-05-26 07:35:17 -04:00
|
|
|
|
|
|
|
(define (filelist-browser message)
|
|
|
|
(cond
|
|
|
|
|
|
|
|
((init-with-result-message? message)
|
|
|
|
(let ((fsobjects (init-with-result-message-result message))
|
|
|
|
(num-lines (calculate-number-of-lines
|
|
|
|
(init-with-result-message-buffer message))))
|
2005-05-27 17:32:21 -04:00
|
|
|
(make-browser-for-fs-objects fsobjects num-lines)))
|
2004-10-14 07:58:20 -04:00
|
|
|
|
2005-05-26 07:35:17 -04:00
|
|
|
((print-message? message)
|
|
|
|
(paint-browser (message-result-object message)))
|
2005-05-17 05:56:11 -04:00
|
|
|
|
2005-05-26 07:35:17 -04:00
|
|
|
((key-pressed-message? message)
|
|
|
|
(handle-key-press message))
|
|
|
|
|
|
|
|
(else
|
|
|
|
(values))))
|
2004-10-14 07:58:20 -04:00
|
|
|
|
2005-05-22 11:05:25 -04:00
|
|
|
(define (list-of-fs-objects? thing)
|
|
|
|
(and (proper-list? thing)
|
|
|
|
(every fs-object? thing)))
|
2004-10-14 07:58:20 -04:00
|
|
|
|
2005-05-23 08:47:41 -04:00
|
|
|
(register-plugin!
|
2005-05-26 07:35:17 -04:00
|
|
|
(make-view-plugin filelist-browser
|
2005-05-23 08:47:41 -04:00
|
|
|
list-of-fs-objects?))
|