From 0dba4a16ba67b58ce4b0ba2fe630a5702f1de341 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Sun, 14 Jan 2024 15:29:47 -0500 Subject: [PATCH] allow quoted-insert into search strings; fixes for negative count arguments in rl_trim_arg_from_keyseq; fix issues if someone binds do-lowercase-version to something that's not an uppercase character; add checks for ANSI terminal; fix to history expansion to not interpret quick substitution at the start of the line if the application says it's in single quotes --- aclocal.m4 | 37 ++++++++++++++++++ bind.c | 41 +++++++++++--------- complete.c | 3 +- display.c | 2 +- doc/history.3 | 15 +++++++- doc/hsuser.texi | 10 +++++ doc/readline.3 | 23 +++++++----- doc/rltech.texi | 3 ++ doc/rluser.texi | 3 +- doc/version.texi | 8 ++-- histexpand.c | 2 +- isearch.c | 29 ++++++++++++++- readline.c | 6 ++- readline.h | 4 +- rlconf.h | 5 +++ search.c | 11 ++++++ support/shobj-conf | 2 +- terminal.c | 93 ++++++++++++++++++++++++++++++++++++++++++++-- text.c | 2 +- 19 files changed, 252 insertions(+), 47 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index 26af88a..67ffa5b 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -2188,6 +2188,43 @@ main(int c, char **v) fi ]) +AC_DEFUN([BASH_FUNC_BRK], +[ + AC_MSG_CHECKING([for brk]) + AC_CACHE_VAL(ac_cv_func_brk, + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ void *x = brk (0); ]])], + [ac_cv_func_brk=yes],[ac_cv_func_brk=no])]) + AC_MSG_RESULT($ac_cv_func_brk) + if test X$ac_cv_func_brk = Xyes; then + AC_CACHE_CHECK([for working brk], [bash_cv_func_brk], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +int +main(int c, char **v) +{ + void *x; + + x = brk (0); + exit ((x == (void *)-1) ? 1 : 0); +} +]])],[bash_cv_func_brk=yes],[bash_cv_func_brk=no],[AC_MSG_WARN([cannot check working brk if cross-compiling]) + bash_cv_func_brk=yes +])]) + if test $bash_cv_func_brk = no; then + ac_cv_func_brk=no + fi + fi + if test $ac_cv_func_brk = yes; then + AC_DEFINE(HAVE_BRK, 1, + [Define if you have a working brk function.]) + fi +]) + AC_DEFUN(BASH_FUNC_FNMATCH_EQUIV_FALLBACK, [AC_MSG_CHECKING(whether fnmatch can be used to check bracket equivalence classes) AC_CACHE_VAL(bash_cv_fnmatch_equiv_fallback, diff --git a/bind.c b/bind.c index 3a44fef..47478f0 100644 --- a/bind.c +++ b/bind.c @@ -874,21 +874,30 @@ int rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map) { register int i, j, parsing_digits; - unsigned char ic; + unsigned int ic; /* int to handle ANYOTHERKEY */ Keymap map0; if (map == 0) map = _rl_keymap; map0 = map; - /* The digits following the initial one (e.g., the binding to digit-argument) - or the optional `-' in a binding to digit-argument or universal-argument - are not added to rl_executing_keyseq. This is basically everything read by - rl_digit_loop. The parsing_digits logic is here in case they ever are. */ + /* Make sure to add the digits following the initial one (e.g., the binding + to digit-argument) and the optional `-' in a binding to digit-argument + or universal-argument to rl_executing_keyseq. This is basically + everything read by rl_digit_loop. */ for (i = j = parsing_digits = 0; keyseq && i < len; i++) { ic = keyseq[i]; + if (parsing_digits == 2) + { + if (ic == '-') /* skip over runs of minus chars */ + { + j = i + 1; + continue; + } + parsing_digits = 1; + } if (parsing_digits) { if (_rl_digit_p (ic)) @@ -901,10 +910,11 @@ rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map) if (map[ic].type == ISKMAP) { - if (i + 1 == len) - return -1; map = FUNCTION_TO_KEYMAP (map, ic); - continue; + if (i + 1 == len) + ic = ANYOTHERKEY; + else + continue; } if (map[ic].type == ISFUNC) { @@ -923,16 +933,11 @@ rl_trim_arg_from_keyseq (const char *keyseq, size_t len, Keymap map) /* This logic should be identical to rl_digit_loop */ /* We accept M-- as equivalent to M--1, C-u- as equivalent to C-u-1 - but set parsing_digits to 2 to note that we saw `-' */ - if (map[ic].function == rl_universal_argument && (i + 1 == '-')) - { - i++; - parsing_digits = 2; - } - if (map[ic].function == rl_digit_argument && ic == '-') - { - parsing_digits = 2; - } + but set parsing_digits to 2 to note that we saw `-'. See above + for the check that skips over one or more `-' characters. */ + if (map[ic].function == rl_universal_argument || + (map[ic].function == rl_digit_argument && ic == '-')) + parsing_digits = 2; map = map0; j = i + 1; diff --git a/complete.c b/complete.c index d202e08..79e37cc 100644 --- a/complete.c +++ b/complete.c @@ -2190,7 +2190,8 @@ rl_complete_internal (int what_to_do) } /*FALLTHROUGH*/ - case '%': + case '%': /* used by menu_complete */ + case '|': /* add this for unconditional display */ do_display = 1; break; diff --git a/display.c b/display.c index feb46ef..edc8726 100644 --- a/display.c +++ b/display.c @@ -999,7 +999,7 @@ rl_redisplay (void) the line breaks in the prompt string in expand_prompt, taking invisible characters into account, and if lpos exceeds the screen width, we copy the data in the loop below. */ - lpos = prompt_physical_chars + modmark; + lpos = local_prompt ? prompt_physical_chars + modmark : 0; #if defined (HANDLE_MULTIBYTE) memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int)); diff --git a/doc/history.3 b/doc/history.3 index 63a4004..76e1025 100644 --- a/doc/history.3 +++ b/doc/history.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Thu Jan 19 17:20:59 EST 2023 +.\" Last Change: Thu Dec 14 15:42:44 EST 2023 .\" -.TH HISTORY 3 "2023 January 19" "GNU History 8.2" +.TH HISTORY 3 "2023 December 14" "GNU History 8.3" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -74,10 +74,21 @@ does when reading input, so that several words that would otherwise be separated are considered one word when surrounded by quotes (see the description of \fBhistory_tokenize()\fP below). +.PP History expansions are introduced by the appearance of the history expansion character, which is \^\fB!\fP\^ by default. Only backslash (\^\fB\e\fP\^) and single quotes can quote the history expansion character. +.PP +There is a special abbreviation for substitution, active when the +\fIquick substitution\fP character (default \fB\(ha\fP) +is the first character on the line. +It selects the previous history list entry, using an event designator +equivalent to \fB!!\fP, +and substitutes one string for another in that line. +It is described below under \fBEvent Designators\fP. +This is the only history expansion that does not begin with the history +expansion character. .SS Event Designators An event designator is a reference to a command line entry in the history list. diff --git a/doc/hsuser.texi b/doc/hsuser.texi index 386d6c5..dab64a0 100644 --- a/doc/hsuser.texi +++ b/doc/hsuser.texi @@ -316,6 +316,16 @@ also treated as quoted if it immediately precedes the closing double quote in a double-quoted string. @end ifset +There is a special abbreviation for substitution, active when the +@var{quick substitution} character (default @samp{^}) +is the first character on the line. +It selects the previous history list entry, using an event designator +equivalent to @code{!!}, +and substitutes one string for another in that line. +It is described below (@pxref{Event Designators}). +This is the only history expansion that does not begin with the history +expansion character. + @ifset BashFeatures Several shell options settable with the @code{shopt} builtin (@pxref{The Shopt Builtin}) may be used to tailor diff --git a/doc/readline.3 b/doc/readline.3 index 8b0ba10..9af32f7 100644 --- a/doc/readline.3 +++ b/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Mon Jul 17 16:46:23 EDT 2023 +.\" Last Change: Fri Jan 5 11:02:00 EST 2024 .\" -.TH READLINE 3 "2023 July 17" "GNU Readline 8.3" +.TH READLINE 3 "2024 January 5" "GNU Readline 8.3" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -34,8 +34,8 @@ readline \- get a line from a user with editing \fBreadline\fP (\fIconst char *prompt\fP); .fi .SH COPYRIGHT -.if n Readline is Copyright (C) 1989\-2023 Free Software Foundation, Inc. -.if t Readline is Copyright \(co 1989\-2023 Free Software Foundation, Inc. +.if n Readline is Copyright (C) 1989\-2024 Free Software Foundation, Inc. +.if t Readline is Copyright \(co 1989\-2024 Free Software Foundation, Inc. .SH DESCRIPTION .LP .B readline @@ -50,6 +50,9 @@ The line returned is allocated with the caller must free it when finished. The line returned has the final newline removed, so only the text of the line remains. +Since it's possible to enter characters into the line while quoting +them to disable any \fBreadline\fP editing function they might normally have, +this line may include embedded newlines and other special characters. .LP .B readline offers editing capabilities while the user is entering the @@ -1464,15 +1467,17 @@ VI Insert Mode functions "C-I" complete "C-J" accept-line "C-M" accept-line +"C-N" menu-complete +"C-P" menu-complete-backward "C-R" reverse-search-history "C-S" forward-search-history "C-T" transpose-chars "C-U" unix-line-discard "C-V" quoted-insert -"C-W" unix-word-rubout +"C-W" vi-unix-word-rubout "C-Y" yank "C-[" vi-movement-mode -"C-_" undo +"C-_" vi-undo "\^ " to "\(ti" self-insert "C-?" backward-delete-char .PP @@ -1494,7 +1499,7 @@ VI Command Mode functions "C-T" transpose-chars "C-U" unix-line-discard "C-V" quoted-insert -"C-W" unix-word-rubout +"C-W" vi-unix-word-rubout "C-Y" yank "C-_" vi-undo "\^ " forward-char @@ -1528,7 +1533,7 @@ VI Command Mode functions "T" vi-char-search "U" revert-line "W" vi-next-word -"X" backward-delete-char +"X" vi-rubout "Y" vi-yank-to "\e" vi-complete "\(ha" vi-first-print @@ -1543,7 +1548,7 @@ VI Command Mode functions "h" backward-char "i" vi-insertion-mode "j" next-history -"k" prev-history +"k" previous-history "l" forward-char "m" vi-set-mark "n" vi-search-again diff --git a/doc/rltech.texi b/doc/rltech.texi index 8b9bd8c..54f68af 100644 --- a/doc/rltech.texi +++ b/doc/rltech.texi @@ -67,6 +67,9 @@ the simplest way possible, perhaps to replace calls in your code to The function @code{readline()} prints a prompt @var{prompt} and then reads and returns a single line of text from the user. +Since it's possible to enter characters into the line while quoting +them to disable any Readline editing function they might normally have, +this line may include embedded newlines and other special characters. If @var{prompt} is @code{NULL} or the empty string, no prompt is displayed. The line @code{readline} returns is allocated with @code{malloc()}; the caller should @code{free()} the line when it has finished with it. diff --git a/doc/rluser.texi b/doc/rluser.texi index 72d951a..3793d81 100644 --- a/doc/rluser.texi +++ b/doc/rluser.texi @@ -2161,7 +2161,8 @@ matches were generated. @end example Specify how arguments to each @var{name} should be completed. -If the @option{-p} option is supplied, or if no options are supplied, existing +If the @option{-p} option is supplied, or if no options or @var{name}s +are supplied, existing completion specifications are printed in a way that allows them to be reused as input. The @option{-r} option removes a completion specification for diff --git a/doc/version.texi b/doc/version.texi index aa585cd..2eed8b1 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,11 +1,11 @@ @ignore -Copyright (C) 1988-2023 Free Software Foundation, Inc. +Copyright (C) 1988-2024 Free Software Foundation, Inc. @end ignore @set EDITION 8.3 @set VERSION 8.3 -@set UPDATED 3 November 2023 -@set UPDATED-MONTH November 2023 +@set UPDATED 5 January 2024 +@set UPDATED-MONTH January 2024 -@set LASTCHANGE Fri Nov 3 12:04:26 EDT 2023 +@set LASTCHANGE Fri Jan 5 11:01:44 EST 2024 diff --git a/histexpand.c b/histexpand.c index 425ea7c..8a28cbd 100644 --- a/histexpand.c +++ b/histexpand.c @@ -950,7 +950,7 @@ history_expand (const char *hstring, char **output) /* The quick substitution character is a history expansion all right. That is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, that is the substitution that we do. */ - if (hstring[0] == history_subst_char) + if ((history_quoting_state != '\'' || history_quotes_inhibit_expansion == 0) && hstring[0] == history_subst_char) { string = (char *)xmalloc (l + 5); diff --git a/isearch.c b/isearch.c index 1cc8e80..9ddf9ce 100644 --- a/isearch.c +++ b/isearch.c @@ -430,7 +430,11 @@ add_character: { f = cxt->keymap[c].function; if (f == rl_do_lowercase_version) - f = cxt->keymap[_rl_to_lower (c)].function; + { + f = cxt->keymap[_rl_to_lower (c)].function; + if (f == rl_do_lowercase_version) + f = rl_insert; + } } if (f == rl_reverse_search_history) @@ -447,6 +451,8 @@ add_character: cxt->lastc = -6; else if (f == rl_bracketed_paste_begin) cxt->lastc = -7; + else if (c == CTRL('V') || f == rl_quoted_insert) + cxt->lastc = -8; } /* If we changed the keymap earlier while translating a key sequence into @@ -712,6 +718,27 @@ opcode_dispatch: xfree (paste); break; + case -8: /* quoted insert */ +#if defined (HANDLE_SIGNALS) + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_disable_tty_signals (); +#endif + c = _rl_search_getchar (cxt); +#if defined (HANDLE_SIGNALS) + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_restore_tty_signals (); +#endif + + if (c < 0) + { + cxt->sflags |= SF_FAILED; + cxt->history_pos = cxt->last_found_line; + return -1; + } + + _rl_add_executing_keyseq (c); + + /*FALLTHROUGH*/ /* Add character to search string and continue search. */ default: #if defined (HANDLE_MULTIBYTE) diff --git a/readline.c b/readline.c index 608c65e..dbe57ef 100644 --- a/readline.c +++ b/readline.c @@ -1124,7 +1124,11 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq) type = m[ANYOTHERKEY].type; func = m[ANYOTHERKEY].function; if (type == ISFUNC && func == rl_do_lowercase_version) - r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map); + { + int newkey = _rl_to_lower ((unsigned char)key); + /* check that there is actually a lowercase version to avoid infinite recursion */ + r = (newkey != key) ? _rl_dispatch (newkey, map) : 1; + } else if (type == ISFUNC) { /* If we shadowed a function, whatever it is, we somehow need a diff --git a/readline.h b/readline.h index d300e6a..f8c356e 100644 --- a/readline.h +++ b/readline.h @@ -39,9 +39,9 @@ extern "C" { #endif /* Hex-encoded Readline version number. */ -#define RL_READLINE_VERSION 0x0802 /* Readline 8.2 */ +#define RL_READLINE_VERSION 0x0803 /* Readline 8.3 */ #define RL_VERSION_MAJOR 8 -#define RL_VERSION_MINOR 2 +#define RL_VERSION_MINOR 3 /* Readline data structures. */ diff --git a/rlconf.h b/rlconf.h index b6d6a2f..e0fd735 100644 --- a/rlconf.h +++ b/rlconf.h @@ -76,4 +76,9 @@ #define RL_VI_CMD_MODESTR_DEFAULT "(cmd)" #define RL_VI_CMD_MODESTR_DEFLEN 5 +/* Do you want readline to assume it's running in an ANSI-compatible terminal + by default? If set to 0, readline tries to check and verify whether or not + it is. */ +#define RL_ANSI_TERM_DEFAULT 1 /* for now */ + #endif /* _RLCONF_H_ */ diff --git a/search.c b/search.c index 810ab41..37db052 100644 --- a/search.c +++ b/search.c @@ -341,6 +341,17 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c) rl_unix_line_discard (1, c); break; + case CTRL('Q'): + case CTRL('V'): + n = rl_quoted_insert (1, c); + if (n < 0) + { + _rl_nsearch_abort (cxt); + return -1; + } + cxt->lastc = (rl_point > 0) ? rl_line_buffer[rl_point - 1] : rl_line_buffer[0]; + break; + case RETURN: case NEWLINE: return 0; diff --git a/support/shobj-conf b/support/shobj-conf index cd7634d..4882a99 100644 --- a/support/shobj-conf +++ b/support/shobj-conf @@ -114,7 +114,7 @@ sunos5*-*gcc*|solaris2*-*gcc*) ;; sunos5*|solaris2*) - SHOBJ_CFLAGS='-K pic' + SHOBJ_CFLAGS='-fPIC' # was -K pic SHOBJ_LD=/usr/ccs/bin/ld SHOBJ_LDFLAGS='-G -dy -z text -i -h $@' diff --git a/terminal.c b/terminal.c index 2c13c40..7003d2a 100644 --- a/terminal.c +++ b/terminal.c @@ -1,6 +1,6 @@ /* terminal.c -- controlling the terminal with termcap. */ -/* Copyright (C) 1996-2022 Free Software Foundation, Inc. +/* Copyright (C) 1996-2023 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -113,6 +113,7 @@ char PC, *BC, *UP; char *_rl_term_clreol; char *_rl_term_clrpag; char *_rl_term_clrscroll; +char *_rl_term_ho; char *_rl_term_cr; char *_rl_term_backspace; char *_rl_term_goto; @@ -185,6 +186,12 @@ static char *_rl_term_kN; static char *_rl_term_vs; /* very visible */ static char *_rl_term_ve; /* normal */ +/* Bracketed paste */ +static char *_rl_term_BE; /* enable */ +static char *_rl_term_BD; /* disable */ +static char *_rl_term_PS; /* paste start */ +static char *_rl_term_PE; /* paste end */ + /* User-settable color sequences to begin and end the active region. Defaults are rl_term_so and rl_term_se on non-dumb terminals. */ char *_rl_active_region_start_color = NULL; @@ -214,6 +221,9 @@ int _rl_enable_keypad; /* Non-zero means the user wants to enable a meta key. */ int _rl_enable_meta = 1; +/* Non-zero means this is an ANSI-compatible terminal; assume it is. */ +int _rl_term_isansi = RL_ANSI_TERM_DEFAULT; + #if defined (__EMX__) static void _emx_get_screensize (int *swp, int *shp) @@ -415,14 +425,19 @@ struct _tc_string { static const struct _tc_string tc_strings[] = { { "@7", &_rl_term_at7 }, + { "BD", &_rl_term_BD }, + { "BE", &_rl_term_BE }, { "DC", &_rl_term_DC }, { "E3", &_rl_term_clrscroll }, { "IC", &_rl_term_IC }, + { "PE", &_rl_term_PE }, + { "PS", &_rl_term_PS }, { "ce", &_rl_term_clreol }, { "cl", &_rl_term_clrpag }, { "cr", &_rl_term_cr }, { "dc", &_rl_term_dc }, { "ei", &_rl_term_ei }, + { "ho", &_rl_term_ho }, { "ic", &_rl_term_ic }, { "im", &_rl_term_im }, { "kD", &_rl_term_kD }, /* delete */ @@ -466,6 +481,63 @@ get_term_capabilities (char **bp) tcap_initialized = 1; } +struct _term_name { + const char * const name; + size_t len; +}; + +/* Non-exhaustive list of ANSI/ECMA terminals. */ +static const struct _term_name ansiterms[] = +{ + { "xterm", 5 }, + { "rxvt", 4 }, + { "eterm", 5 }, + { "screen", 6 }, + { "tmux", 4 }, + { "vt100", 5 }, + { "vt102", 5 }, + { "vt220", 5 }, + { "vt320", 5 }, + { "ansi", 4 }, + { "scoansi", 7 }, + { "cygwin", 6 }, + { "linux", 5 }, + { "konsole", 7 }, + { "bvterm", 6 }, + { 0, 0 } +}; + +static inline int +iscsi (const char *s) +{ + return ((s[0] == ESC && s[1] == '[') ? 2 + : ((unsigned char)s[0] == 0x9b) ? 1 : 0); +} + +static int +_rl_check_ansi_terminal (const char *terminal_name) +{ + int i; + size_t len; + + for (i = 0; ansiterms[i].name; i++) + if (STREQN (terminal_name, ansiterms[i].name, ansiterms[i].len)) + return 1; + + if (_rl_term_clreol == 0 || _rl_term_forward_char == 0 || + _rl_term_ho == 0 || _rl_term_up == 0) + return 0; + + /* check some common capabilities */ + if (((len = iscsi (_rl_term_clreol)) && _rl_term_clreol[len] == 'K') && /* ce */ + ((len = iscsi (_rl_term_forward_char)) && _rl_term_forward_char[len] == 'C') && /* nd */ + ((len = iscsi (_rl_term_ho)) && _rl_term_ho[len] == 'H') && /* ho */ + ((len = iscsi (_rl_term_up)) && _rl_term_up[len] == 'A')) /* up */ + return 1; + + return 0; +} + int _rl_init_terminal_io (const char *terminal_name) { @@ -480,7 +552,10 @@ _rl_init_terminal_io (const char *terminal_name) if (term == 0) term = "dumb"; - dumbterm = STREQ (term, "dumb"); + _rl_term_isansi = RL_ANSI_TERM_DEFAULT; + dumbterm = STREQ (term, "dumb") || STREQ (term, "vt52") || STREQ (term, "adm3a"); + if (dumbterm) + _rl_term_isansi = 0; reset_region_colors = 1; @@ -492,11 +567,13 @@ _rl_init_terminal_io (const char *terminal_name) _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; _rl_term_cr = "\r"; _rl_term_backspace = (char *)NULL; + _rl_term_ho = (char *)NULL; _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; _rl_term_kN = _rl_term_kP = (char *)NULL; _rl_term_so = _rl_term_se = (char *)NULL; + _rl_term_BD = _rl_term_BE = _rl_term_PE = _rl_term_PS = (char *)NULL; #if defined(HACK_TERMCAP_MOTION) _rl_term_forward_char = (char *)NULL; #endif @@ -553,6 +630,7 @@ _rl_init_terminal_io (const char *terminal_name) /* Everything below here is used by the redisplay code (tputs). */ _rl_screenchars = _rl_screenwidth * _rl_screenheight; _rl_term_cr = "\r"; + _rl_term_ho = (char *)NULL; _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; @@ -565,8 +643,11 @@ _rl_init_terminal_io (const char *terminal_name) _rl_term_so = _rl_term_se = (char *)NULL; _rl_terminal_can_insert = term_has_meta = 0; + _rl_term_isansi = 0; /* not an ANSI terminal */ + /* Assume generic unknown terminal can't handle the enable/disable escape sequences */ + _rl_term_BD = _rl_term_BE = _rl_term_PE = _rl_term_PS = (char *)NULL; _rl_enable_bracketed_paste = 0; /* No terminal so/se capabilities. */ @@ -625,9 +706,13 @@ _rl_init_terminal_io (const char *terminal_name) bind_termcap_arrow_keys (vi_insertion_keymap); #endif /* VI_MODE */ + if (dumbterm == 0 && _rl_term_isansi == 0) + _rl_term_isansi = _rl_check_ansi_terminal (terminal_name); + /* There's no way to determine whether or not a given terminal supports - bracketed paste mode, so we assume a terminal named "dumb" does not. */ - if (dumbterm) + bracketed paste mode, so we assume a non-ANSI terminal (as best as we + can determine) does not. */ + if (_rl_term_isansi == 0) _rl_enable_bracketed_paste = _rl_enable_active_region = 0; if (reset_region_colors) diff --git a/text.c b/text.c index 933536a..25e8484 100644 --- a/text.c +++ b/text.c @@ -2089,7 +2089,7 @@ _rl_readstr_dispatch (_rl_readstr_cxt *cxt, int c) _rl_readstr_restore (cxt); return -1; } - cxt->lastc = rl_line_buffer[rl_point - 1]; /* preserve prevc */ + cxt->lastc = (rl_point > 0) ? rl_line_buffer[rl_point - 1] : rl_line_buffer[0]; /* preserve prevc */ break; case RETURN: -- 2.47.2