--- a/lisp/pick.lisp Fri Dec 27 03:14:26 2019 +0000
+++ b/lisp/pick.lisp Sat Dec 28 00:40:58 2019 +0000
@@ -34,7 +34,7 @@
(defun filter (choices)
(loop
- :with width = (1+ (reduce #'max choices :key #'length))
+ :with width = (1+ (reduce #'max choices :key #'length :initial-value 0))
:for choice :in choices
:when (prompt "~A~vA[yN] " choice (- width (length choice)) #\space)
:collect choice))
@@ -90,7 +90,15 @@
(adopt:define-string *help-text*
"pick displays its arguments one-by-one on standard error and prompts you ~
interactively to choose some of them. The chosen items will be printed to ~
- standard output.")
+ standard output.~@
+ ~@
+ An argument of - will cause pick to read lines from standard input as ~
+ choices. Using an explicit - instead of reading from standard input when no ~
+ arguments are present prevents something like 'pick `ls -1 | grep foo`' from ~
+ silently hanging forever if no files match.~@
+ ~@
+ This version was inspired by the pick program described in 'The UNIX ~
+ Programming Environment'.")
(defparameter *ui*
(adopt:make-interface
@@ -113,6 +121,10 @@
(with-open-file (*interactive-input* "/dev/tty" :direction :input)
(let ((*separator* (gethash 'separator options))
(*interactive-output* *error-output*))
- (run (or arguments (read-lines *standard-input*))))))
+ (run (mapcan (lambda (arg)
+ (if (string= "-" arg)
+ (read-lines *standard-input*)
+ (list arg)))
+ arguments)))))
(error (c) (adopt:print-error-and-exit c))))