Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] print selection list with continue --print-selections



The select command only reprints the selection list when the input is
empty. There was no way to explicitly reprint the list in response to
a specific user input, such as:

    1) <m>ouse  2) <c>ow  3) <t>igger 4) <?>SHOW THIS MENU AGAIN
    ?#

This change extends the continue builtin with a new option:
--print-selections. When this option is used, the select command
reprints the menu before showing the PS3 prompt on the next iteration.

    case "$REPLY" in
    ...
        ('?') continue --print-selections;;
    ...
    esac

Signed-off-by: Masatake YAMATO <yamato@xxxxxxxxxx>
---
 Doc/Zsh/builtins.yo  |  5 ++++-
 Src/builtin.c        |  7 +++++++
 Src/loop.c           |  9 +++++++++
 Test/A07control.ztst | 16 ++++++++++++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 8fe2d8e21..108e7de9f 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -334,11 +334,14 @@ module(compvalues)(zsh/computil)
 findex(continue)
 cindex(loops, continuing)
 cindex(continuing loops)
-item(tt(continue) [ var(n) ])(
+item(tt(continue) [ tt(--print-selections) ] [ var(n) ])(
 Resume the next iteration of the enclosing
 tt(for), tt(while), tt(until), tt(select) or
 tt(repeat) loop. If an arithmetic expression var(n) is specified, break out of
 var(n)-1 loops and resume at the var(n)th enclosing loop.
+If the tt (--print-selections) option is specified and the enclosing loop is
+a tt(select) loop, the selection list will be printed at the beginning of the
+next iteration.
 )
 alias(declare)(typeset)
 findex(dirs)
diff --git a/Src/builtin.c b/Src/builtin.c
index 23067abe1..2d16f503b 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -5834,6 +5834,13 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func)
 {
     int num = lastval, nump = 0, implicit;
 
+    if (func == BIN_CONTINUE
+	&& *argv && strcmp(*argv, "--print-selections") == 0) {
+	extern int print_selectlist_requested;
+	print_selectlist_requested = 1;
+	argv++;
+    }
+
     /* handle one optional numeric argument */
     implicit = !*argv;
     if (*argv) {
diff --git a/Src/loop.c b/Src/loop.c
index ba01b1da5..9eb1c95b0 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -39,6 +39,9 @@ int loops;
  
 /**/
 mod_export int contflag;
+
+/* --print-selections option is specified in the continue buitlin. */
+int print_selectlist_requested;
  
 /* # of break levels */
  
@@ -267,8 +270,12 @@ execselect(Estate state, UNUSED(int do_exec))
     usezle = interact && SHTTY != -1 && isset(USEZLE);
     inp = fdopen(dup(usezle ? SHTTY : 0), "r");
     more = selectlist(args, 0);
+    print_selectlist_requested = 0;
     loop = state->pc;
     for (;;) {
+	if (print_selectlist_requested)
+	    goto print;
+
 	for (;;) {
 	    if (empty(bufstack)) {
 	    	if (usezle) {
@@ -303,7 +310,9 @@ execselect(Estate state, UNUSED(int do_exec))
 		*s = '\0';
 	    if (*str)
 	      break;
+	print:
 	    more = selectlist(args, more);
+	    print_selectlist_requested = 0;
 	}
 	setsparam("REPLY", ztrdup(str));
 	i = atoi(str);
diff --git a/Test/A07control.ztst b/Test/A07control.ztst
index b1a248732..fe29b7aa7 100644
--- a/Test/A07control.ztst
+++ b/Test/A07control.ztst
@@ -163,3 +163,19 @@
   done
 4:Last status from loop body is kept even with other funny business going on
 >1
+
+  PS3=
+  printf "1\n2\n3\n" | select n in a b c; do
+    echo $REPLY
+    case $REPLY in
+      (1) continue;;
+      (2) continue --print-selections;;
+      (3) break;;
+    esac
+  done 2>&1
+0:Redraw the menu of select with continue --print-selections
+>1) a  2) b  3) c  
+>1
+>2
+>1) a  2) b  3) c  
+>3
-- 
2.51.0





Messages sorted by: Reverse Date, Date, Thread, Author