git: 3cf65f8a7f8e - main - sh(1): Allow non-printing characters in prompt strings
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 22 Dec 2022 18:13:05 UTC
The branch main has been updated by otis (ports committer): URL: https://cgit.FreeBSD.org/src/commit/?id=3cf65f8a7f8ee993118fe06f3c187ad30f875132 commit 3cf65f8a7f8ee993118fe06f3c187ad30f875132 Author: Juraj Lutter <otis@FreeBSD.org> AuthorDate: 2022-12-08 20:30:26 +0000 Commit: Juraj Lutter <otis@FreeBSD.org> CommitDate: 2022-12-22 18:10:48 +0000 sh(1): Allow non-printing characters in prompt strings Introduce new prompt format characters: - '\[' starts the sequence of non-printing chatacters - '\]' ends the sequence of non-printing characters Within these sequences, the following characters are now supported: - '\a' emits ASCII BEL (0x07, 007) character - '\e' emits ASCII ESC (0x1b, 033) character - '\r' emits ASCII CR (0x0d, 015) character - '\n' emits ASCII CRLF sequence These can be used to embed ANSI sequences into prompt strings. Example in .shrc: PS1="\[\e[7m\]\u@\h\[\e[0m\]:\w \\$ " This tries to maintain some degree of compatibility with GNU bash, that uses GNU readline library (which behaves slightly different from BSD editline): It has two "non-printing boundary" characters: - RL_PROMPT_START_IGNORE (\001) - RL_PROMPT_END_IGNORE (\002) while BSD editline only has one (when using EL_PROMPT_ESC setting), so for this purpose, ASCII \001 was chosen and both \[ and \] emits this character. And while here, enlarge PROMPTLEN from 128 to 192 characters. Reviewed by: jilles Approved by: jilles Differential Revision: https://reviews.freebsd.org/D37701 --- bin/sh/histedit.c | 2 +- bin/sh/parser.c | 47 +++++++++++++++++++++++++++++++++++++++-------- bin/sh/sh.1 | 20 +++++++++++++++++++- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index 8812200279f0..0eb8c6c1784f 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -190,7 +190,7 @@ histedit(void) if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); - el_set(el, EL_PROMPT, getprompt); + el_set(el, EL_PROMPT_ESC, getprompt, '\001'); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", sh_complete); diff --git a/bin/sh/parser.c b/bin/sh/parser.c index e75798800edf..7f8283ca4dff 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$"); * Shell command parser. */ -#define PROMPTLEN 128 +#define PROMPTLEN 192 /* values of checkkwd variable */ #define CHKALIAS 0x1 @@ -2060,6 +2060,44 @@ getprompt(void *unused __unused) if (*fmt == '\\') switch (*++fmt) { + /* + * Non-printing sequence begin and end. + */ + case '[': + case ']': + ps[i] = '\001'; + break; + + /* + * Literal \ and some ASCII characters: + * \a BEL + * \e ESC + * \r CR + */ + case '\\': + case 'a': + case 'e': + case 'r': + if (*fmt == 'a') + ps[i] = '\007'; + else if (*fmt == 'e') + ps[i] = '\033'; + else if (*fmt == 'r') + ps[i] = '\r'; + else + ps[i] = '\\'; + break; + + /* + * CRLF sequence + */ + case 'n': + if (i < PROMPTLEN - 3) { + ps[i++] = '\r'; + ps[i] = '\n'; + } + break; + /* * Hostname. * @@ -2136,13 +2174,6 @@ getprompt(void *unused __unused) ps[i] = (geteuid() != 0) ? '$' : '#'; break; - /* - * A literal \. - */ - case '\\': - ps[i] = '\\'; - break; - /* * Emit unrecognized formats verbatim. */ diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 7a30020f2f7f..330685a911e1 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd May 10, 2021 +.Dd December 14, 2022 .Dt SH 1 .Os .Sh NAME @@ -1446,6 +1446,24 @@ for normal users and for superusers. .It Li \e\e A literal backslash. +.It Li \e[ +Start of a sequence of non-printing characters (used, for example, +to embed ANSI CSI sequences into the prompt). +.It Li \e] +End of a sequence of non-printing characters. +.El +.Pp +The following special and non-printing characters are supported +within the sequence of non-printing characters: +.Bl -tag -width indent +.It Li \ea +Emits ASCII BEL (0x07, 007) character. +.It Li \ee +Emits ASCII ESC (0x1b, 033) character. +.It Li \er +Emits ASCII CR (0x0d, 015) character. +.It Li \en +Emits CRLF sequence. .El .It Va PS2 The secondary prompt string, which defaults to