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

[PATCH] preserve COLUMNS + LINES from the environment



zsh always resets COLUMNS and LINES on init (and afterwards) if it can,
so you can't explicitly override them when running scripts:

  % zsh -fc 'echo $COLUMNS'
  132
  % COLUMNS=80 zsh -fc 'echo $COLUMNS'
  132

you might want to do this so your script can use them for formatting, or
so it can pass them on to another tool like man or ps that does that

imo zsh should preserve these from the environment if set, at least when
it's non-interactive

there are several ways to approach this (every other shell i looked at
handles it differently), but here's my idea

dana


diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 933081b34..a4dd1a2ca 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1265,6 +1265,12 @@ vindex(COLUMNS)
 item(tt(COLUMNS) <S>)(
 The number of columns for this terminal session.
 Used for printing select lists and for the line editor.
+If the shell is non-interactive and a legal value is imported from the
+environment, it is preserved.  Otherwise, the value is reset on start-up
+and in response to certain events such as the receipt of a tt(SIGWINCH)
+signal.  Explicitly setting it to an illegal value such as tt(0) also
+resets it.  (Unsetting the parameter does not have this effect; it
+simply `hides' the value that the shell is tracking internally.)
 )
 vindex(CORRECT_IGNORE)
 item(tt(CORRECT_IGNORE))(
@@ -1471,6 +1477,7 @@ vindex(LINES)
 item(tt(LINES) <S>)(
 The number of lines for this terminal session.
 Used for printing select lists and for the line editor.
+See tt(COLUMNS).
 )
 vindex(LISTMAX)
 item(tt(LISTMAX))(
diff --git a/Src/init.c b/Src/init.c
index 89a7ff714..60156e173 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1288,6 +1288,23 @@ setupvals(char *cmd, char *runscript, char *zsh_name)
     condtab = NULL;
     wrappers = NULL;
 
+    zterm_columns_preserve = zterm_lines_preserve = 0;
+
+    // preserve COLUMNS and LINES from environment when non-interactive
+    if (!isset(INTERACTIVE)) {
+	char *e, *p;
+	zlong v;
+
+	if ((e = zgetenv("COLUMNS")) && (v = zstrtol(e, &p, 10)) > 0 && !*p) {
+	    zterm_columns = v;
+	    zterm_columns_preserve = 1;
+	}
+	if ((e = zgetenv("LINES")) && (v = zstrtol(e, &p, 10)) > 0 && !*p) {
+	    zterm_lines = v;
+	    zterm_lines_preserve = 1;
+	}
+    }
+
 #ifdef TIOCGWINSZ
     adjustwinsize(0);
 #else
diff --git a/Src/params.c b/Src/params.c
index 1620b2a11..7e98607eb 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -107,6 +107,11 @@ mod_export zlong
      ppid,		/* $PPID        */
      zsh_subshell;	/* $ZSH_SUBSHELL */
 
+// whether COLUMNS and LINES should be preserved because they were imported from
+// the environment into a non-interactive shell
+/**/
+mod_export int zterm_columns_preserve, zterm_lines_preserve;
+
 /* $FUNCNEST    */
 /**/
 mod_export
diff --git a/Src/utils.c b/Src/utils.c
index e16a9085e..ca898595a 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1836,7 +1836,7 @@ adjustlines(int signalled)
     int oldlines = zterm_lines;
 
 #ifdef TIOCGWINSZ
-    if (signalled || zterm_lines <= 0)
+    if ((signalled && !zterm_lines_preserve) || zterm_lines <= 0)
 	zterm_lines = shttyinfo.winsize.ws_row;
     else
 	shttyinfo.winsize.ws_row = zterm_lines;
@@ -1861,7 +1861,7 @@ adjustcolumns(int signalled)
     int oldcolumns = zterm_columns;
 
 #ifdef TIOCGWINSZ
-    if (signalled || zterm_columns <= 0)
+    if ((signalled && !zterm_columns_preserve) || zterm_columns <= 0)
 	zterm_columns = shttyinfo.winsize.ws_col;
     else
 	shttyinfo.winsize.ws_col = zterm_columns;
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 218bca739..022cd8a1b 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -2987,3 +2987,20 @@ F:output ignorable as long as not an error
   fi
 -:ZSH_EXEPATH
 *>match: /*
+
+  for 1 in '' -m; do
+    COLUMNS=47 LINES=47 $ZTST_testdir/../Src/zsh $1 -fc '
+      echo $COLUMNS $LINES
+      COLUMNS=74 LINES=74
+      echo $COLUMNS $LINES
+      command true
+      echo $COLUMNS $LINES
+    '
+  done
+-:COLUMNS and LINES preserved from environment when non-interactive
+>47 47
+>74 74
+>74 74
+>47 47
+>74 74
+>74 74




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