patch to improve opthelp method

 new new list compose Reply to this message Top page
Attachments:
+ (text/plain)

Delete this message
Author: vapnik spaknik
Date:  
To: txr-users@kylheku.com
Subject: patch to improve opthelp method
Hi Kaz,
           I find the extra notes printed by opthelp about command line argument processing conventions to be superfluous. They are non-standard (at least on linux), and take up too much screen space; if your script has many options they might not all fit on screen at once.
Here's a patch that makes these extra notes optional, by adding an extra arg to opthelp. The new arg is optional and comes after other args so it should be backwards compatible.

Joe


>From b9a81e8f48df0053d375ef326cba98ca7aac0785 Mon Sep 17 00:00:00 2001

From: Joe Bloggs <vapniks@???>
Date: Fri, 4 Feb 2022 01:18:33 +0000
Subject: [PATCH] opthelp: add inchelp arg to make notes on command-line
 conventions optional

---
 stdlib/getopts.tl | 91 ++++++++++++++++++++++++-----------------------
 txr.1             | 18 ++++++----
 2 files changed, 57 insertions(+), 52 deletions(-)


diff --git a/stdlib/getopts.tl b/stdlib/getopts.tl
index 2ecad67b..1dc837d3 100644
--- a/stdlib/getopts.tl
+++ b/stdlib/getopts.tl
@@ -268,7 +268,7 @@
          (opr (new sys:opt-processor od-list opt-desc-list opts opts)))
     opr.(parse-opts args)))
 
-(defun opthelp (opt-desc-list : (stream *stdout*))
+(defun opthelp (opt-desc-list : (stream *stdout*) incnotes)
   (let ((sorted [nsort (copy-list (remove-if (op null @1.helptext)
                                              opt-desc-list)) :
                        (do if @1.long @1.long @1.short)])
@@ -305,71 +305,72 @@
         (each ((line (sys:wdwrap undoc-str 75)))
           (put-line `    @line`)))
       (put-line))
-    (put-line "Notes:\n")
-    (let* ((have-short (some sorted (usl short)))
-           (have-long (some sorted (usl long)))
-           (have-arg-p (some sorted (usl arg-p)))
-           (have-bool (some sorted (op eq @1.type :bool)))
-           (texts (list (if have-short
-                          "Short options can be invoked with long syntax: \ \
+    (when incnotes
+      (put-line "Notes:\n")
+      (let* ((have-short (some sorted (usl short)))
+         (have-long (some sorted (usl long)))
+         (have-arg-p (some sorted (usl arg-p)))
+         (have-bool (some sorted (op eq @1.type :bool)))
+         (texts (list (if have-short
+                  "Short options can be invoked with long syntax: \ \
                            for example, --a can be used when -a exists.\ \
                            Short no-argument options can be clumped into\ \
                            one argument as exemplified by -xyz.")
-                        (if have-bool
-                          (if have-arg-p
-                            "Options that take no argument are Boolean:"
-                            (if undocumented
-                              "All documented options are Boolean:"
-                              "All options are Boolean:")))
-                        (if have-bool
-                          "they are true when present, false when absent.")
-                        (if (and have-bool have-arg-p)
-                          "The --no- prefix can explicitly specify \ \
+              (if have-bool
+                  (if have-arg-p
+                  "Options that take no argument are Boolean:"
+                (if undocumented
+                    "All documented options are Boolean:"
+                  "All options are Boolean:")))
+              (if have-bool
+                  "they are true when present, false when absent.")
+              (if (and have-bool have-arg-p)
+                  "The --no- prefix can explicitly specify \ \
                            Boolean options as false: if a Boolean option\ \
                            X exists,\ \
                            --no-X specifies it as false. This is useful\ \
                            for making false those options which default\ \
                            to true. "
-                          "The --no- prefix can explicitly specify \ \
+                "The --no- prefix can explicitly specify \ \
                            options as false: if an X option exists,\ \
                            --no-X specifies it as false. This is useful\ \
                            for making false those options which default\ \
                            to true. ")
-                        (if (not have-long)
-                          "Note the double dash on --no.")
-                        (if (and have-short have-long)
-                          "The --no- prefix can be applied to a short\ \
+              (if (not have-long)
+                  "Note the double dash on --no.")
+              (if (and have-short have-long)
+                  "The --no- prefix can be applied to a short\ \
                            or long option name.")
-                        (if have-arg-p
-                          "The argument to a long option can be given in one\ \
+              (if have-arg-p
+                  "The argument to a long option can be given in one\ \
                            argument as --option=arg or as a separate\ \
                            argument using --option arg.")
-                        "The special argument -- can be used where an option\ \
+              "The special argument -- can be used where an option\ \
                         may appear. It means \"end of options\": the\ \
                         arguments which follow are not treated as options\ \
                         even if they look like options.")))
-      (mapdo (do put-line `  @1`)
-             (sys:wdwrap `@{(flatten texts)}` 77)))
-    (put-line)
-    (whenlet ((types (keep-if [andf keywordp (op neq :bool)]
-                              (uniq (mapcar (usl type) sorted)))))
-      (put-line "Type legend:\n")
-      (each ((ty types))
-        (iflet ((ln (caseql ty
-                      (:dec   "  DEC    - Decimal integer: -123, 0, 5, +73")
-                      (:hex   "  HEX    - Hexadecimal integer -EF, 2D0, +9A")
-                      (:oct   "  OCT    - Octal integer: -773, 5677, +326")
-                      (:cint  "  CINT   - C-style integer: leading 0 octal,\
+    (mapdo (do put-line `  @1`)
+           (sys:wdwrap `@{(flatten texts)}` 77)))
+      (put-line)
+      (whenlet ((types (keep-if [andf keywordp (op neq :bool)]
+                (uniq (mapcar (usl type) sorted)))))
+           (put-line "Type legend:\n")
+           (each ((ty types))
+             (iflet ((ln (caseql ty
+                     (:dec   "  DEC    - Decimal integer: -123, 0, 5, +73")
+                     (:hex   "  HEX    - Hexadecimal integer -EF, 2D0, +9A")
+                     (:oct   "  OCT    - Octal integer: -773, 5677, +326")
+                     (:cint  "  CINT   - C-style integer: leading 0 octal,\
                               \ leading 0x hex, else decimal;\n\
                               \           leading sign allowed: -0777, 0xFDC, +123")
-                      (:float "  FLOAT  - Floating-point: -1.3e+03, +5, 3.3,\
+                     (:float "  FLOAT  - Floating-point: -1.3e+03, +5, 3.3,\
                               \ 3., .5, .12e9, 53.e-3, 3e-015")
-                      (:str   "  STR    - String with embedded escapes, valid\
+                     (:str   "  STR    - String with embedded escapes, valid\
                               \ as TXR Lisp string literals\n\
                               \           syntax: foo, foo\\tbar, abc\\nxyz")
-                      (:text  "  TEXT   - Unprocessed text"))))
-           (put-line ln)))
-    (put-line))))
+                     (:text  "  TEXT   - Unprocessed text"))))
+                (put-line ln)))
+           (put-line)))))
 
 
 (defstruct sys:option-base nil
@@ -387,8 +388,8 @@
     (set me.in-args args me.out-args args)
     (let ((opr (new sys:opt-processor od-list me.opt-desc-list opts me)))
       opr.(parse-opts args)))
-  (:method opthelp (me : (stream *stdout*))
-    (opthelp me.opt-desc-list stream)))
+  (:method opthelp (me : (stream *stdout*) incnotes)
+    (opthelp me.opt-desc-list stream incnotes)))
 
 (defmacro define-option-struct (name super-spec . opts)
   (let* ((slots (mapcar (tb ((short long . rest))
diff --git a/txr.1 b/txr.1
index d6c7f39d..5630cdc8 100644
--- a/txr.1
+++ b/txr.1
@@ -68110,8 +68110,9 @@ arguments.
 
 The
 .code opthelp
-function takes a list of option descriptors and an output stream,
-and generates help text on that stream. A program supporting a
+function takes a list of option descriptors, an output stream, and an arg
+indicating whether to print extra notes on command line conventions.
+It then generates help text on that stream. A program supporting a
 .code --help
 option can use this to generate that portion of its help text which
 describes the available options, as well as the conventions that they use.
@@ -68603,7 +68604,7 @@ arguments.
 
 .coNP Function @ opthelp
 .synb
-.mets (opthelp < opt-desc-list <> [ stream ])
+.mets (opthelp < opt-desc-list <> [ stream ] <> [ inchelp ])
 .syne
 .desc
 The
@@ -68613,9 +68614,11 @@ function processes the list of
 structures
 .meta opt-desc-list
 and compiles a customized body of help text describing all of the
-options, as well as general description of the command-line option
-conventions to guide the user in in the correct use of command
-line options.
+options. If
+.meta inchelp
+is non-nil then a general description of the command-line option
+conventions will also be printed to guide the user in in the correct
+use of command line options.
 
 The text is formatted to fit within 79 columns, and begins and ends with a
 blank line. Its format consists of headings which begin in the first column,
@@ -68699,7 +68702,8 @@ When the argument list is successfully processed.
 
 The
 .code opthelp
-method takes an optional stream argument.
+method takes an optional stream argument, and an argument to indicate whether
+or not to include general notes on command line conventions.
 
 Note: to encode the option names
 .str "t"
-- 
2.17.1