From b19658360926df6e889ca59becf2217f1c5d2e2d Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Fri, 30 Apr 2021 16:56:05 -0400 Subject: [PATCH] new "enable-active-region" readline variable --- CWRU/CWRU.chlog | 21 ++++++ arrayfunc.c | 2 +- builtins/common.c | 2 +- command.h | 2 +- doc/bash.1 | 15 ++++- lib/readline/bind.c | 1 + lib/readline/doc/readline.3 | 15 ++++- lib/readline/doc/rluser.texi | 13 ++++ lib/readline/doc/version.texi | 4 +- make_cmd.c | 5 +- subst.c | 120 ++++++++++++++++++++++++++++++++-- 11 files changed, 183 insertions(+), 17 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index bbfbd5e8..986036c2 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -10108,3 +10108,24 @@ bashline.c pattern, make sure to set rl_filename_completion_desired, so we get quoting and appending -- we are completing a filename, after all. From a report from Manuel Boni + +lib/readline/bind.c + - enable-active-region: separate control of the active region and + bracketed paste. Still set to the same default value as bracketed + paste, and enabling bracketed paste enables the active region. + Now you can enable bracketed paste and then turn off the active + region. + +doc/bash.1,lib/readline/doc/{readline.3,rltech.texi} + - enable-active-region: document new bindable readline variable and + its effects + + 4/30 + ---- +command.h + - W_ARRAYREF: new flag, meaning the word is a valid array reference + with subscript, replaces W_DOLLARSTAR, which was unused + +subst.c + - expand_subscript_string,expand_array_subscript: new functions to + parse and expand-and-quote array subscripts. For future use diff --git a/arrayfunc.c b/arrayfunc.c index f57d7837..468935a6 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -344,7 +344,7 @@ assign_array_element (name, value, flags) (ASS_ALLOWALLSUB) we allow it. */ if (((isassoc == 0 || (flags & (ASS_NOEXPAND|ASS_ALLOWALLSUB)) == 0) && (ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']')) || - (sublen <= 1)) + (sublen <= 1)) { free (vname); err_badarraysub (name); diff --git a/builtins/common.c b/builtins/common.c index 9459900e..89c94066 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -1001,7 +1001,7 @@ builtin_bind_var_to_int (name, val) { SHELL_VAR *v; - v = bind_var_to_int (name, val, ASS_ALLOWALLSUB); /* XXX */ + v = bind_var_to_int (name, val, ASS_ALLOWALLSUB); return v; } diff --git a/command.h b/command.h index 137608de..e0dc2f95 100644 --- a/command.h +++ b/command.h @@ -82,7 +82,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, #define W_NOSPLIT2 (1 << 6) /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */ #define W_TILDEEXP (1 << 7) /* Tilde expand this assignment word */ #define W_DOLLARAT (1 << 8) /* UNUSED - $@ and its special handling */ -#define W_DOLLARSTAR (1 << 9) /* UNUSED - $* and its special handling */ +#define W_ARRAYREF (1 << 9) /* word is a valid array reference */ #define W_NOCOMSUB (1 << 10) /* Don't perform command substitution on this word */ #define W_ASSIGNRHS (1 << 11) /* Word is rhs of an assignment statement */ #define W_NOTILDE (1 << 12) /* Don't perform tilde expansion on this word */ diff --git a/doc/bash.1 b/doc/bash.1 index 4dd91545..c5ccacd6 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Wed Mar 31 11:01:34 EDT 2021 +.\" Last Change: Wed Apr 28 14:35:46 EDT 2021 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2021 March 30" "GNU Bash 5.1" +.TH BASH 1 "2021 April 28" "GNU Bash 5.1" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -5865,6 +5865,17 @@ Use the \e1 and \e2 escapes to begin and end sequences of non-printing characters, which can be used to embed a terminal control sequence into the mode string. .TP +.B enable\-active\-region (On) +The \fIpoint\fP is the current cursor position, and \fImark\fP refers +to a saved cursor position. +The text between the point and mark is referred to as the \fIregion\fP. +When this variable is set to \fIOn\fP, readline allows certain commands +to designate the region as \fIactive\fP. +When the region is active, readline highlights the text in the region using +the terminal's standout mode. +The active region shows the text inserted by bracketed-paste and any +matching text found by incremental and non-incremental history searches. +.TP .B enable\-bracketed\-paste (On) When set to \fBOn\fP, readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a diff --git a/lib/readline/bind.c b/lib/readline/bind.c index fe73e3cb..f43baf45 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -1819,6 +1819,7 @@ static const struct { { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 }, { "disable-completion", &rl_inhibit_completion, 0 }, { "echo-control-characters", &_rl_echo_control_chars, 0 }, + { "enable-active-region", &_rl_enable_active_region, 0 }, { "enable-bracketed-paste", &_rl_enable_bracketed_paste, V_SPECIAL }, { "enable-keypad", &_rl_enable_keypad, 0 }, { "enable-meta-key", &_rl_enable_meta, 0 }, diff --git a/lib/readline/doc/readline.3 b/lib/readline/doc/readline.3 index 832e69ef..398c8a73 100644 --- a/lib/readline/doc/readline.3 +++ b/lib/readline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Tue Mar 24 09:27:30 EDT 2020 +.\" Last Change: Wed Apr 28 14:31:09 EDT 2021 .\" -.TH READLINE 3 "2020 October 29" "GNU Readline 8.1" +.TH READLINE 3 "2021 April 28" "GNU Readline 8.1" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -447,6 +447,17 @@ Use the \e1 and \e2 escapes to begin and end sequences of non-printing characters, which can be used to embed a terminal control sequence into the mode string. .TP +.B enable\-active\-region (On) +The \fIpoint\fP is the current cursor position, and \fImark\fP refers +to a saved cursor position. +The text between the point and mark is referred to as the \fIregion\fP. +When this variable is set to \fIOn\fP, readline allows certain commands +to designate the region as \fIactive\fP. +When the region is active, readline highlights the text in the region using +the terminal's standout mode. +The active region shows the text inserted by bracketed-paste and any +matching text found by incremental and non-incremental history searches. +.TP .B enable\-bracketed\-paste (On) When set to \fBOn\fP, readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index 70e751ca..f4d4860d 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -540,6 +540,19 @@ non-printing characters, which can be used to embed a terminal control sequence into the mode string. The default is @samp{@@}. +@item enable-active-region +@vindex enable-active-region +The @dfn{point} is the current cursor position, and @dfn{mark} refers +to a saved cursor position (@pxref{Commands For Moving}). +The text between the point and mark is referred to as the @dfn{region}. +When this variable is set to @samp{On}, Readline allows certain commands +to designate the region as @dfn{active}. +When the region is active, Readline highlights the text in the region using +the terminal's standout mode. +The active region shows the text inserted by bracketed-paste and any +matching text found by incremental and non-incremental history searches. +The default is @samp{On}. + @item enable-bracketed-paste @vindex enable-bracketed-paste When set to @samp{On}, Readline will configure the terminal in a way diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index e90db4c1..cd0998e8 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -4,7 +4,7 @@ Copyright (C) 1988-2021 Free Software Foundation, Inc. @set EDITION 8.1 @set VERSION 8.1 -@set UPDATED 16 April 2021 +@set UPDATED 28 April 2021 @set UPDATED-MONTH April 2021 -@set LASTCHANGE Fri Apr 16 14:51:06 EDT 2021 +@set LASTCHANGE Wed Apr 28 14:30:42 EDT 2021 diff --git a/make_cmd.c b/make_cmd.c index 38cc0892..86f56042 100644 --- a/make_cmd.c +++ b/make_cmd.c @@ -251,10 +251,7 @@ make_arith_for_expr (s) if (s == 0 || *s == '\0') return ((WORD_LIST *)NULL); wd = make_word (s); - wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_NOTILDE; /* no word splitting or globbing */ -#if defined (PROCESS_SUBSTITUTION) - wd->flags |= W_NOPROCSUB; /* no process substitution */ -#endif + wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_NOTILDE|W_NOPROCSUB; /* no word splitting or globbing */ result = make_word_list (wd, (WORD_LIST *)NULL); return result; } diff --git a/subst.c b/subst.c index 8fd36724..8187245d 100644 --- a/subst.c +++ b/subst.c @@ -458,10 +458,10 @@ dump_word_flags (flags) f &= ~W_NOCOMSUB; fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : ""); } - if (f & W_DOLLARSTAR) + if (f & W_ARRAYREF) { - f &= ~W_DOLLARSTAR; - fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : ""); + f &= ~W_ARRAYREF; + fprintf (stderr, "W_ARRAYREF%s", f ? "|" : ""); } if (f & W_DOLLARAT) { @@ -3278,7 +3278,7 @@ do_assignment_internal (word, expand) report_error (_("%s: cannot assign list to array member"), name); ASSIGN_RETURN (0); } - aflags |= ASS_ALLOWALLSUB; + aflags |= ASS_ALLOWALLSUB; /* allow a[@]=value for existing associative arrays */ entry = assign_array_element (name, value, aflags); if (entry == 0) ASSIGN_RETURN (0); @@ -10117,6 +10117,118 @@ return0: return ret; } +#if defined (ARRAY_VARS) +/* Characters that need to be backslash-quoted after expanding array subscripts */ +static char abstab[256] = { '\1' }; + +/* Run an array subscript through the appropriate word expansions. */ +char * +expand_subscript_string (string, quoted) + char *string; + int quoted; +{ + WORD_DESC td; + WORD_LIST *tlist; + int oe; + char *ret; + + if (string == 0 || *string == 0) + return (char *)NULL; + + oe = expand_no_split_dollar_star; + ret = (char *)NULL; + + td.flags = W_NOPROCSUB|W_NOTILDE|W_NOSPLIT2; /* XXX - W_NOCOMSUB? */ + td.word = string; + + expand_no_split_dollar_star = 1; + tlist = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); + expand_no_split_dollar_star = oe; + + if (tlist) + { + if (tlist->word) + { + remove_quoted_nulls (tlist->word->word); + tlist->word->flags &= ~W_HASQUOTEDNULL; + } + dequote_list (tlist); + ret = string_list (tlist); + dispose_words (tlist); + } + + return (ret); +} + +/* Expand the subscript in STRING, which is an array reference. To ensure we + only expand it once, we quote the characters that would start another + expansion and the bracket characters that are special to array subscripts. */ +static char * +expand_array_subscript (string, sindex, quoted, flags) + char *string; + int *sindex; + int quoted, flags; +{ + char *ret, *exp, *t; + size_t slen; + int si, ni; + + si = *sindex; + slen = STRLEN (string); + + if (abstab[0] == '\1') + { + /* These are basically the characters that start shell expansions plus + the characters that delimit subscripts. */ + memset (abstab, '\0', sizeof (abstab)); + abstab[LBRACK] = abstab[RBRACK] = 1; + abstab['$'] = abstab['`'] = abstab['~'] = 1; + abstab['\\'] = abstab['\''] = 1; + } + + /* string[si] == LBRACK */ + ni = skipsubscript (string, si, 0); + /* These checks mirror the ones in valid_array_subscript. The check for + (ni - si) == 1 checks for empty subscripts. We don't check that the + subscript is a separate word if we're parsing an arithmetic expression. */ + if (ni >= slen || string[ni] != RBRACK || (ni - si) == 1 || + (string[ni+1] != '\0' && (quoted & Q_ARITH) == 0)) + { +/* let's check and see what fails this check */ +itrace("expand_array_subscript: bad subscript string: `%s'", string+si); + ret = (char *)xmalloc (2); /* badly-formed subscript */ + ret[0] = string[si]; + ret[1] = '\0'; + *sindex = si + 1; + return ret; + } + + /* STRING[ni] == RBRACK */ + exp = substring (string, si+1, ni); + t = expand_subscript_string (exp, quoted & ~(Q_ARITH|Q_DOUBLE_QUOTES)); + free (exp); + /* Only quote `@' and `*' if they are the only character in the subscript */ + if (ALL_ELEMENT_SUB (t[0]) && t[1] == '\0') + abstab['*'] = abstab['@'] = 1; + else + abstab['*'] = abstab['@'] = 0; + exp = sh_backslash_quote (t, abstab, 0); + free (t); + + slen = STRLEN (exp); + ret = xmalloc (slen + 2 + 1); + ret[0] ='['; + strcpy (ret + 1, exp); + ret[slen + 1] = ']'; + ret[slen + 2] = '\0'; + + free (exp); + *sindex = ni + 1; + + return ret; +} +#endif + void invalidate_cached_quoted_dollar_at () {