Hi,
bash has a PROMPT_COMMAND that allows a command to be executed before
each PS1 prompt is displayed. I've found this useful on occasion, so
this is the same thing for ksh(1).
In particular, this allows PROMPT_COMMAND to be set to a user-defined
shell function that can modify PS1, though it could also produce its
own output directly.
Is anyone other than me interested in this? If so, review by someone
familiar with ksh's guts would be welcome.
-d
Index: ksh.1
===
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.216
diff -u -p -r1.216 ksh.1
--- ksh.1 31 Mar 2022 17:27:14 - 1.216
+++ ksh.1 2 Aug 2022 09:07:43 -
@@ -1520,6 +1520,15 @@ See
below.
.It Ev PPID
The process ID of the shell's parent (read-only).
+.It Ev PROMPT_COMMAND
+Used to specify a shell command that is executed before
+.Ev PS1
+is displayed.
+.Ev PROMPT_COMMAND
+may be a normal environment variable, in which case it is executed directly,
+or may be an array of commands that will be executed in order.
+Commands may be functions that modify or replace
+.Ev PS1 .
.It Ev PS1
The primary prompt for interactive shells.
Parameter, command, and arithmetic
Index: lex.c
===
RCS file: /cvs/src/bin/ksh/lex.c,v
retrieving revision 1.78
diff -u -p -r1.78 lex.c
--- lex.c 15 Jan 2018 14:58:05 - 1.78
+++ lex.c 2 Aug 2022 09:07:43 -
@@ -1173,6 +1173,37 @@ special_prompt_expand(char *str)
return str;
}
+static void
+prompt_command(char *str)
+{
+ struct op *t;
+ Source *s;
+
+ s = pushs(SSTRING, ATEMP);
+ s->start = s->str = str;
+ t = compile(s);
+ if (t == NULL || t->type == TEOF)
+ return;
+ exstat = execute(t, XERROK, NULL);
+}
+
+/* If $PROMPT_COMMAND is set, then try to execute it before expanding $PS1 */
+static void
+try_prompt_command(void)
+{
+ struct tbl *e;
+
+ e = global("PROMPT_COMMAND");
+ /* Handle regular variables and arrays */
+ for (; e; e = e->u.array) {
+ if (!(e->flag & ISSET))
+ continue;
+ prompt_command(str_val(e));
+ if (!(e->flag & ARRAY))
+ return;
+ }
+}
+
void
set_prompt(int to)
{
@@ -1183,6 +1214,7 @@ set_prompt(int to)
switch (to) {
case PS1: /* command */
+ try_prompt_command();
ps1 = str_save(str_val(global("PS1")), ATEMP);
saved_atemp = ATEMP;/* ps1 is freed by substitute() */
newenv(E_ERRH);