--- a/lisp/clhs.lisp Tue Mar 26 22:05:13 2019 -0400
+++ b/lisp/clhs.lisp Tue Apr 02 06:16:37 2019 -0400
@@ -118,49 +118,64 @@
("Look up MAKE-ARRAY in a local copy of the HyperSpec and open it in lynx:" .
"clhs --url file:///home/sjl/doc/hyperspec/ --open lynx make-array")))
-(adopt:define-interface *ui*
- (:name "clhs"
- :usage "[OPTIONS] SYMBOL"
- :summary "Look up a symbol in the Common Lisp HyperSpec."
- :documentation *documentation*
- :examples *examples*)
- ((help)
- :documentation "display help and exit"
- :manual "Display help and exit."
- :long "help"
- :short #\h
- :reduce (constantly t))
- ((rebuild-cache)
- :documentation "rebuild the symbol cache"
- :manual "Rebuild the symbol cache, even if it already exists, instead of looking up a symbol."
- :long "rebuild-cache"
- :reduce (constantly t))
- ((open)
- :documentation (format nil "program to use to open hyperspec URLs (default ~A)" *default-open-command*)
- :manual (format nil "The program to use to open hyperspec URLs. The default is: ~A" *default-open-command*)
- :long "open"
- :short #\o
- :parameter "COMMAND"
- :initial-value *default-open-command*
- :reduce #'adopt:newest)
- ((url)
- :documentation (format nil "base HyperSpec URL (default ~A)" *default-hyperspec-url*)
- :manual (format nil
- "The base HyperSpec URL. The default is: ~A~@
- ~@
- A local copy of the HyperSpec can be used with a file:// prefix."
- *default-hyperspec-url*)
- :long "url"
- :short #\u
- :parameter "URL"
- :initial-value *default-hyperspec-url*
- :reduce #'adopt:newest))
+
+(defparameter *o-help*
+ (adopt:make-option 'help
+ :help "display help and exit"
+ :manual "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+(defparameter *o-rebuild-cache*
+ (adopt:make-option 'rebuild-cache
+ :help "rebuild the symbol cache"
+ :manual "Rebuild the symbol cache, even if it already exists, instead of looking up a symbol."
+ :long "rebuild-cache"
+ :reduce (constantly t)))
+
+(defparameter *o-open*
+ (adopt:make-option 'open
+ :help (format nil "program to use to open hyperspec URLs (default ~A)" *default-open-command*)
+ :manual (format nil "The program to use to open hyperspec URLs. The default is: ~A" *default-open-command*)
+ :long "open"
+ :short #\o
+ :parameter "COMMAND"
+ :initial-value *default-open-command*
+ :reduce #'adopt:newest))
+
+(defparameter *o-url*
+ (adopt:make-option 'url
+ :help (format nil "base HyperSpec URL (default ~A)" *default-hyperspec-url*)
+ :manual (format nil
+ "The base HyperSpec URL. The default is: ~A~@
+ ~@
+ A local copy of the HyperSpec can be used with a file:// prefix."
+ *default-hyperspec-url*)
+ :long "url"
+ :short #\u
+ :parameter "URL"
+ :initial-value *default-hyperspec-url*
+ :reduce #'adopt:newest))
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "clhs"
+ :usage "[OPTIONS] SYMBOL"
+ :summary "Look up a symbol in the Common Lisp HyperSpec."
+ :help *documentation*
+ :examples *examples*
+ :contents (list *o-help*
+ *o-rebuild-cache*
+ *o-open*
+ *o-url*)))
(defun toplevel ()
(handler-case
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
- (adopt:print-usage-and-exit *ui*))
+ (adopt:print-help-and-exit *ui*))
(let ((*open* (gethash 'open options))
(*url* (gethash 'url options))
(target (first arguments)))
--- a/lisp/example.lisp Tue Mar 26 22:05:13 2019 -0400
+++ b/lisp/example.lisp Tue Apr 02 06:16:37 2019 -0400
@@ -17,31 +17,38 @@
;;;; CLI ----------------------------------------------------------------------
-(adopt:define-interface *ui*
- (:name "example"
- :usage "[-n NAME]"
- :summary "Say Hello."
- :documentation "An example program to show how to make well-behaved CLI tools in Common Lisp."
- :examples '(("Say hello:" . "example")
- ("Say hello to Alice:" . "example --name Alice")))
- (help
- :documentation "display help and exit"
+(defparameter *help*
+ (adopt:make-option 'help
+ :help "display help and exit"
:long "help"
:short #\h
- :reduce (constantly t))
- (name
- :documentation (format nil "say hello to NAME (default ~A)" *default-name*)
+ :reduce (constantly t)))
+
+(defparameter *name*
+ (adopt:make-option 'name
+ :help (format nil "say hello to NAME (default ~A)" *default-name*)
:long "name"
:short #\n
:parameter "NAME"
:initial-value *default-name*
:reduce #'adopt:newest))
+(defparameter *ui*
+ (adopt:make-interface
+ :name "example"
+ :usage "[-n NAME]"
+ :summary "Say Hello."
+ :help "An example program to show how to make well-behaved CLI tools in Common Lisp."
+ :examples '(("Say hello:" . "example")
+ ("Say hello to Alice:" . "example --name Alice"))
+ :contents (list *help* *name*)))
+
+
(defun toplevel ()
(handler-case
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
- (adopt:print-usage-and-exit *ui*))
+ (adopt:print-help-and-exit *ui*))
(unless (null arguments)
(error "Unrecognized command-line arguments: ~S" arguments))
(run (gethash 'name options)))
--- a/lisp/genpass.lisp Tue Mar 26 22:05:13 2019 -0400
+++ b/lisp/genpass.lisp Tue Apr 02 06:16:37 2019 -0400
@@ -90,9 +90,6 @@
;;;; User Interface -----------------------------------------------------------
-(adopt:define-string *documentation*
- "Generate a random password.")
-
(defparameter *examples*
'(("Generate a random passphrase no longer than 24 characters:"
. "genpass --length 24")
@@ -101,65 +98,98 @@
("Generate a six word passphrase with no spaces:"
. "genpass --words 6 --smush")))
-(adopt:define-interface *ui*
- (:name "genpass"
- :usage "[OPTIONS]"
- :summary "Generate a random password."
- :documentation *documentation*
- :examples *examples*)
- ((help)
- :documentation "Display help and exit."
- :long "help"
- :short #\h
- :reduce (constantly t))
- ((length)
- :documentation "Ensure password is no longer than N characters (default 40)."
- :long "length"
- :short #\l
- :parameter "N"
- :initial-value 40
- :reduce #'adopt:newest
- :key #'parse-integer)
- ((words)
- :documentation "If non-zero, generate passphrases of N words instead of opaque strings (default 4)."
- :long "words"
- :short #\w
- :parameter "N"
- :initial-value 4
- :reduce #'adopt:newest
- :key #'parse-integer)
- ((no-words words)
- :documentation "Shorthand for --words=0."
- :long "no-words"
- :short #\W
- :reduce (constantly 0))
- ((smart)
- :documentation "Smart mode (the default). Generate as with --words, but add a number on the end to satisfy the red tape on many sites."
- :long "smart"
- :short #\s
- :initial-value t
- :reduce (constantly t))
- ((no-smart smart)
- :documentation "Turn off smart mode."
- :long "no-smart"
- :short #\S
- :reduce (constantly nil))
- ((smush)
- :documentation "Don't include spaces in passphrases."
- :long "smush"
- :short #\m
- :reduce (constantly t))
- ((no-smush smush)
- :documentation "Include spaces in passphrases (the default)."
- :long "no-smush"
- :short #\M
- :reduce (constantly nil)))
+
+(defparameter *help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+(defparameter *length*
+ (adopt:make-option 'length
+ :help "Ensure password is no longer than N characters (default 40)."
+ :long "length"
+ :short #\l
+ :parameter "N"
+ :initial-value 40
+ :reduce #'adopt:newest
+ :key #'parse-integer))
+
+(defparameter *words*
+ (adopt:make-option 'words
+ :help "If non-zero, generate passphrases of N words instead of opaque strings (default 4)."
+ :long "words"
+ :short #\w
+ :parameter "N"
+ :initial-value 4
+ :reduce #'adopt:newest
+ :key #'parse-integer))
+
+(defparameter *no-words*
+ (adopt:make-option 'no-words
+ :result-key 'words
+ :help "Shorthand for --words=0."
+ :long "no-words"
+ :short #\W
+ :reduce (constantly 0)))
+
+(defparameter *smart*
+ (adopt:make-option 'smart
+ :help "Smart mode (the default). Generate as with --words, but add a number on the end to satisfy the red tape on many sites."
+ :long "smart"
+ :short #\s
+ :initial-value t
+ :reduce (constantly t)))
+
+(defparameter *no-smart*
+ (adopt:make-option 'no-smart
+ :result-key 'smart
+ :help "Turn off smart mode."
+ :long "no-smart"
+ :short #\S
+ :reduce (constantly nil)))
+
+(defparameter *smush*
+ (adopt:make-option 'smush
+ :help "Don't include spaces in passphrases."
+ :long "smush"
+ :short #\m
+ :reduce (constantly t)))
+
+(defparameter *no-smush*
+ (adopt:make-option 'no-smush :result-key 'smush
+ :help "Include spaces in passphrases (the default)."
+ :long "no-smush"
+ :short #\M
+ :reduce (constantly nil)))
+
+
+(defparameter *password-options*
+ (adopt:make-group 'password-options
+ :title "Password Options"
+ :help "The format of generated passwords can be customized in a number of ways."
+ :options (list *length*
+ *words* *no-words*
+ *smart* *no-smart*
+ *smush* *no-smush*)))
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "genpass"
+ :usage "[OPTIONS]"
+ :summary "Generate a random password."
+ :help "Generate a random password."
+ :examples *examples*
+ :contents (list *help* *password-options*)))
+
(defun toplevel ()
(handler-case
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
- (adopt:print-usage-and-exit *ui*))
+ (adopt:print-help-and-exit *ui*))
(when arguments
(error "Unrecognized command line arguments: ~S" arguments))
(run (gethash 'length options)
--- a/lisp/lispindent.lisp Tue Mar 26 22:05:13 2019 -0400
+++ b/lisp/lispindent.lisp Tue Apr 02 06:16:37 2019 -0400
@@ -267,26 +267,38 @@
(indent-lines)
t)
-(adopt:define-interface *ui*
- (:name "lispindent"
- :usage ""
- :summary "Indent Common Lisp code."
- :documentation (format nil
- "Read Common Lisp code from standard input, indent ~
- it according to some simple rules and configuration, ~
- and write the result to standard output."))
- ((help)
- :documentation "display help and exit"
- :manual "Display help and exit."
- :long "help"
- :short #\h
- :reduce (constantly t)))
+
+(adopt:define-string *doc-help*
+ "Read Common Lisp code from standard input, indent it according to some ~
+ simple rules and configuration, and write the result to standard output.")
+
+(adopt:define-string *doc-manual*
+ "~A~@
+ ~@
+ Configuration is read from ~~/.lispwords and ./.lispwords"
+ *doc-help*)
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "lispindent"
+ :usage "[OPTIONS]"
+ :summary "Indent Common Lisp code."
+ :help *doc-help*
+ :manual *doc-manual*
+ :contents
+ (list (adopt:make-option 'help
+ :help "display help and exit"
+ :manual "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))))
+
(defun toplevel ()
(handler-case
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
- (adopt:print-usage-and-exit *ui*))
+ (adopt:print-help-and-exit *ui*))
(when arguments
(error "Unrecognized arguments: ~S" arguments))
(run))
--- a/lisp/search.lisp Tue Mar 26 22:05:13 2019 -0400
+++ b/lisp/search.lisp Tue Apr 02 06:16:37 2019 -0400
@@ -46,43 +46,49 @@
If no FILEs are given, standard input will be searched. Standard input can ~
also be searched by specifying - as a filename.")
-(adopt:define-interface *ui*
- (:name "search"
- :usage "PATTERN [FILE...]"
- :summary "Print lines that match a regular expression."
- :documentation *documentation*)
- (help
- :documentation "display help and exit"
- :long "help"
- :short #\h
- :reduce (constantly t))
- (literal
- :documentation "treat PATTERN as a literal string instead of a regex"
- :long "literal"
- :short #\l
- :reduce (constantly t))
- ((no-literal literal)
- :documentation "treat PATTERN as a regex (the default)"
- :long "no-literal"
- :short #\L
- :reduce (constantly nil))
- (invert
- :documentation "print non-matching lines"
- :long "invert"
- :short #\v
- :initial-value nil
- :reduce (constantly t))
- ((no-invert invert)
- :documentation "print matching lines (the default)"
- :long "no-invert"
- :short #\V
- :reduce (constantly nil)))
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "search"
+ :usage "PATTERN [FILE...]"
+ :summary "Print lines that match a regular expression."
+ :help *documentation*
+ :contents
+ (list
+ (adopt:make-option 'help
+ :help "display help and exit"
+ :long "help"
+ :short #\h
+ :reduce (constantly t))
+ (adopt:make-option 'literal
+ :help "treat PATTERN as a literal string instead of a regex"
+ :long "literal"
+ :short #\l
+ :reduce (constantly t))
+ (adopt:make-option 'no-literal
+ :result-key 'literal
+ :help "treat PATTERN as a regex (the default)"
+ :long "no-literal"
+ :short #\L
+ :reduce (constantly nil))
+ (adopt:make-option 'invert
+ :help "print non-matching lines"
+ :long "invert"
+ :short #\v
+ :initial-value nil
+ :reduce (constantly t))
+ (adopt:make-option 'no-invert
+ :result-key 'invert
+ :help "print matching lines (the default)"
+ :long "no-invert"
+ :short #\V
+ :reduce (constantly nil)))))
(defun toplevel ()
(handler-case
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
- (adopt:print-usage-and-exit *ui*))
+ (adopt:print-help-and-exit *ui*))
(when (null arguments)
(error "PATTERN is required"))
(destructuring-bind (pattern . paths) arguments
--- a/lispwords Tue Mar 26 22:05:13 2019 -0400
+++ b/lispwords Tue Apr 02 06:16:37 2019 -0400
@@ -120,3 +120,6 @@
; adopt
(2 define-interface)
+(1 make-option)
+
+