Ping On Fri, Mar 9, 2018 at 11:50 PM, Daniel Colascione <dan...@google.com> wrote:
> This patch teaches readline about two concepts from Emacs: 1) faces, > and 2) the mark being "active". Both exist in rudimentary form: we > support exactly two faces, normal and "standout", and use standout to > highlight the contents of the region when the mark is active. Readline > redisplay is now smart enough to consider not only text content, but > also face differences when computing how to refresh the screen. > > The immediate motivation for this patch is to provide visual feedback > to users after a bracketed paste operation, but an active region > concept could be useful for all kinds of things, including shift-arrow > selection or integration with xterm mouse facilities. > > The mark automatically deactivates after most commands, including C-g > and cursor motion. We do keep any active mark active across screen > refresh operations, however. > > exchange-point-and-mark activates the mark just like in Emacs. > --- > lib/readline/display.c | 478 +++++++++++++++++++++++---------------- > lib/readline/kill.c | 6 +- > lib/readline/readline.c | 19 ++ > lib/readline/readline.h | 4 + > lib/readline/rlprivate.h | 5 +- > lib/readline/terminal.c | 43 ++++ > lib/readline/text.c | 55 +++-- > lib/readline/util.c | 1 + > 8 files changed, 398 insertions(+), 213 deletions(-) > > diff --git a/lib/readline/display.c b/lib/readline/display.c > index 2d2e768a..f228a39e 100644 > --- a/lib/readline/display.c > +++ b/lib/readline/display.c > @@ -63,13 +63,13 @@ > extern char *strchr (), *strrchr (); > #endif /* !strchr && !__STDC__ */ > > -static void update_line PARAMS((char *, char *, int, int, int, int)); > +static void update_line PARAMS((char *, char *, char *, char *, int, int, > int, int)); > static void space_to_eol PARAMS((int)); > static void delete_chars PARAMS((int)); > -static void insert_some_chars PARAMS((char *, int, int)); > static void open_some_spaces PARAMS((int)); > static void cr PARAMS((void)); > static void redraw_prompt PARAMS((char *)); > +static void _rl_move_cursor_relative PARAMS((int, const char *, const > char *)); > > /* Values for FLAGS */ > #define PMT_MULTILINE 0x01 > @@ -80,6 +80,7 @@ static char *expand_prompt PARAMS((char *, int, int *, > int *, int *, int *)); > struct line_state > { > char *line; > + char *line_face; > int *lbreaks; > int lbsize; > #if defined (HANDLE_MULTIBYTE) > @@ -102,7 +103,9 @@ static int line_structures_initialized = 0; > #define vis_lbsize (line_state_visible->lbsize) > > #define visible_line (line_state_visible->line) > +#define visible_face (line_state_visible->line_face) > #define invisible_line (line_state_invisible->line) > +#define invisible_face (line_state_invisible->line_face) > > #if defined (HANDLE_MULTIBYTE) > static int _rl_col_width PARAMS((const char *, int, int, int)); > @@ -123,7 +126,10 @@ static int _rl_col_width PARAMS((const char *, int, > int, int)); > to use prompt_last_invisible directly. */ > #define PROMPT_ENDING_INDEX \ > ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : > prompt_last_invisible+1) > - > + > +#define FACE_NORMAL '0' > +#define FACE_STANDOUT '1' > +#define FACE_INVALID ((char)1) > > /* **************************************************************** */ > /* */ > @@ -208,8 +214,8 @@ static int msg_bufsiz = 0; > /* Non-zero forces the redisplay even if we thought it was unnecessary. */ > static int forced_display; > > -/* Default and initial buffer size. Can grow. */ > -static int line_size = 1024; > +/* Line buffer size. */ > +static int line_size; > > /* Variables to keep track of the expanded prompt string, which may > include invisible characters. */ > @@ -521,6 +527,64 @@ rl_expand_prompt (prompt) > } > } > > +static void > +ensure_line_size (minsize) > + int minsize; > +{ > + int minimum_size = 1024; > + int new_line_size, delta; > + if (minsize < minimum_size) > + minsize = minimum_size; > + if (line_size >= minsize) > + return; > + if (!new_line_size) > + new_line_size = minimum_size; > + while (new_line_size < minsize) > + new_line_size *= 2; > + visible_line = (char *)xrealloc (visible_line, new_line_size); > + visible_face = (char *)xrealloc (visible_face, new_line_size); > + invisible_line = (char *)xrealloc (invisible_line, new_line_size); > + invisible_face = (char *)xrealloc (invisible_face, new_line_size); > + delta = new_line_size - line_size; > + memset (visible_line + line_size, 0, delta); > + memset (visible_face + line_size, FACE_NORMAL, delta); > + memset (invisible_line + line_size, 1, delta); > + memset (invisible_face + line_size, FACE_INVALID, delta); > + line_size = new_line_size; > +} > + > +static void > +invis_add (outp, c, face) > + int *outp; > + char c; > + char face; > +{ > + ensure_line_size (*outp + 1); > + invisible_line[*outp] = c; > + invisible_face[*outp] = face; > + *outp += 1; > +} > + > +static void > +invis_add_n (outp, str, n, face) > + int *outp; > + const char *str; > + int n; > + char face; > +{ > + int i; > + for (i = 0; i < n; ++i) > + invis_add (outp, str[i], face); > +} > + > +static void > +invis_nul_term (outp) > + int *outp; > +{ > + invis_add (outp, '\0', 0); > + *outp -= 1; > +} > + > /* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their > associated > arrays of line break markers. MINSIZE is the minimum size of > VISIBLE_LINE > and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is > @@ -530,29 +594,12 @@ static void > init_line_structures (minsize) > int minsize; > { > - register int n; > - > if (invisible_line == 0) /* initialize it */ > { > - if (line_size < minsize) > - line_size = minsize; > - visible_line = (char *)xmalloc (line_size); > - invisible_line = (char *)xmalloc (line_size); > - } > - else if (line_size < minsize) /* ensure it can hold MINSIZE > chars */ > - { > - line_size *= 2; > - if (line_size < minsize) > - line_size = minsize; > - visible_line = (char *)xrealloc (visible_line, line_size); > - invisible_line = (char *)xrealloc (invisible_line, line_size); > - } > - > - for (n = minsize; n < line_size; n++) > - { > - visible_line[n] = 0; > - invisible_line[n] = 1; > + if (line_size > minsize) > + minsize = line_size; > } > + ensure_line_size (minsize); > > if (vis_lbreaks == 0) > { > @@ -574,17 +621,19 @@ init_line_structures (minsize) > > line_structures_initialized = 1; > } > - > + > /* Basic redisplay algorithm. */ > void > rl_redisplay () > { > - register int in, out, c, linenum, cursor_linenum; > - register char *line; > + int in, out, c, linenum, cursor_linenum; > int inv_botlin, lb_botlin, lb_linenum, o_cpos; > int newlines, lpos, temp, n0, num, prompt_lines_estimate; > char *prompt_this_line; > int mb_cur_max = MB_CUR_MAX; > + char cur_face = FACE_NORMAL; > + int hl_begin = -1; > + int hl_end = -1; > #if defined (HANDLE_MULTIBYTE) > wchar_t wc; > size_t wc_bytes; > @@ -601,6 +650,22 @@ rl_redisplay () > _rl_block_sigint (); > RL_SETSTATE (RL_STATE_REDISPLAYING); > > + if (rl_mark_active_p () && > + 0 <= rl_point && rl_point <= rl_end && > + 0 <= rl_mark && rl_mark <= rl_end) > + { > + if (rl_mark < rl_point) > + { > + hl_begin = rl_mark; > + hl_end = rl_point; > + } > + else > + { > + hl_begin = rl_point; > + hl_end = rl_mark; > + } > + } > + > if (!rl_display_prompt) > rl_display_prompt = ""; > > @@ -615,7 +680,6 @@ rl_redisplay () > > prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars; > > - line = invisible_line; > out = inv_botlin = 0; > > /* Mark the line as modified or not. We only do this for history > @@ -623,8 +687,8 @@ rl_redisplay () > modmark = 0; > if (_rl_mark_modified_lines && current_history () && rl_undo_list) > { > - line[out++] = '*'; > - line[out] = '\0'; > + invis_add (&out, '*', cur_face); > + invis_nul_term (&out); > modmark = 1; > } > > @@ -644,18 +708,8 @@ rl_redisplay () > _rl_output_some_chars (local_prompt_prefix, strlen > (local_prompt_prefix)); > > if (local_prompt_len > 0) > - { > - temp = local_prompt_len + out + 2; > - if (temp >= line_size) > - { > - line_size = (temp + 1024) - (temp % 1024); > - visible_line = (char *)xrealloc (visible_line, line_size); > - line = invisible_line = (char *)xrealloc (invisible_line, > line_size); > - } > - strncpy (line + out, local_prompt, local_prompt_len); > - out += local_prompt_len; > - } > - line[out] = '\0'; > + invis_add_n (&out, local_prompt, local_prompt_len, cur_face); > + invis_nul_term (&out); > wrap_offset = local_prompt_len - prompt_visible_length; > } > else > @@ -679,16 +733,8 @@ rl_redisplay () > } > > prompt_physical_chars = pmtlen = strlen (prompt_this_line); > - temp = pmtlen + out + 2; > - if (temp >= line_size) > - { > - line_size = (temp + 1024) - (temp % 1024); > - visible_line = (char *)xrealloc (visible_line, line_size); > - line = invisible_line = (char *)xrealloc (invisible_line, > line_size); > - } > - strncpy (line + out, prompt_this_line, pmtlen); > - out += pmtlen; > - line[out] = '\0'; > + invis_add_n (&out, prompt_this_line, pmtlen, cur_face); > + invis_nul_term (&out); > wrap_offset = prompt_invis_chars_first_line = 0; > } > > @@ -856,6 +902,11 @@ rl_redisplay () > for (in = 0; in < rl_end; in++) > #endif > { > + if (in == hl_begin) > + cur_face = FACE_STANDOUT; > + if (in == hl_end) > + cur_face = FACE_NORMAL; > + > c = (unsigned char)rl_line_buffer[in]; > > #if defined (HANDLE_MULTIBYTE) > @@ -880,14 +931,6 @@ rl_redisplay () > } > #endif > > - if (out + 8 >= line_size) /* XXX - 8 for \t */ > - { > - line_size *= 2; > - visible_line = (char *)xrealloc (visible_line, line_size); > - invisible_line = (char *)xrealloc (invisible_line, line_size); > - line = invisible_line; > - } > - > if (in == rl_point) > { > cpos_buffer_position = out; > @@ -902,23 +945,17 @@ rl_redisplay () > { > if (_rl_output_meta_chars == 0) > { > - sprintf (line + out, "\\%o", c); > - > - if (lpos + 4 >= _rl_screenwidth) > - { > - temp = _rl_screenwidth - lpos; > - CHECK_INV_LBREAKS (); > - inv_lbreaks[++newlines] = out + temp; > - lpos = 4 - temp; > - } > - else > - lpos += 4; > - > - out += 4; > + char buf[5]; > + sprintf (buf, "\\%o", c); > + for (temp = 0; temp < strlen (buf); ++temp) > + { > + invis_add (&out, buf[temp], cur_face); > + CHECK_LPOS (); > + } > } > else > { > - line[out++] = c; > + invis_add (&out, c, cur_face); > CHECK_LPOS(); > } > } > @@ -941,28 +978,28 @@ rl_redisplay () > inv_lbreaks[++newlines] = out + temp2; > lpos = temp - temp2; > while (out < newout) > - line[out++] = ' '; > + invis_add (&out, ' ', cur_face); > } > else > { > while (out < newout) > - line[out++] = ' '; > + invis_add (&out, ' ', cur_face); > lpos += temp; > } > } > #endif > else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && > _rl_term_up && *_rl_term_up) > { > - line[out++] = '\0'; /* XXX - sentinel */ > + invis_add (&out, '\0', cur_face); /* XXX - sentinel */ > CHECK_INV_LBREAKS (); > inv_lbreaks[++newlines] = out; > lpos = 0; > } > else if (CTRL_CHAR (c) || c == RUBOUT) > { > - line[out++] = '^'; > + invis_add (&out, '^', cur_face); > CHECK_LPOS(); > - line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; > + invis_add (&out, CTRL_CHAR (c) ? UNCTRL (c) : '?', cur_face); > CHECK_LPOS(); > } > else > @@ -978,7 +1015,7 @@ rl_redisplay () > for (i = lpos; i < _rl_screenwidth; i++) > { > /* The space will be removed in update_line() */ > - line[out++] = ' '; > + invis_add (&out, ' ', cur_face); > _rl_wrapped_multicolumn++; > CHECK_LPOS(); > } > @@ -988,17 +1025,17 @@ rl_redisplay () > lb_linenum = newlines; > } > for (i = in; i < in+wc_bytes; i++) > - line[out++] = rl_line_buffer[i]; > + invis_add (&out, rl_line_buffer[i], cur_face); > for (i = 0; i < wc_width; i++) > CHECK_LPOS(); > } > else > { > - line[out++] = c; > + invis_add (&out, c, cur_face); > CHECK_LPOS(); > } > #else > - line[out++] = c; > + invis_add (&out, c, cur_face); > CHECK_LPOS(); > #endif > } > @@ -1015,7 +1052,8 @@ rl_redisplay () > #endif > > } > - line[out] = '\0'; > + > + invis_nul_term (&out); > if (cpos_buffer_position < 0) > { > cpos_buffer_position = out; > @@ -1054,7 +1092,8 @@ rl_redisplay () > { > #if defined (HANDLE_MULTIBYTE) > if (mb_cur_max > 1 && rl_byte_oriented == 0) > - out = _rl_find_prev_mbchar (line, _rl_screenchars, > MB_FIND_ANY); > + out = _rl_find_prev_mbchar ( > + invisible_line, _rl_screenchars, MB_FIND_ANY); > else > #endif > out = _rl_screenchars - 1; > @@ -1065,15 +1104,19 @@ rl_redisplay () > OFFSET (which has already been calculated above). */ > > #define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? > prompt_invis_chars_first_line : wrap_offset) > -#define WRAP_OFFSET(line, offset) ((line == 0) \ > - ? (offset ? INVIS_FIRST() : 0) \ > - : ((line == > prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0)) > -#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) > +#define WRAP_OFFSET(_lineno, _offset) \ > + ((_lineno == 0) \ > + ? (_offset ? INVIS_FIRST() : 0) \ > + : ((_lineno == prompt_last_screen_line) ? > wrap_offset-prompt_invis_chars_first_line : 0)) > +#define W_OFFSET(_lineno, _offset) ((_lineno) == 0 ? _offset : 0) > #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - > vis_lbreaks[l])) > #define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) > -#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) > -#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) > -#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) > +#define VIS_CHARS(_lineno) (visible_line + vis_lbreaks[_lineno]) > +#define VIS_FACE(_lineno) (visible_face + vis_lbreaks[_lineno]) > +#define VIS_LINE(_lineno) ((_lineno) > _rl_vis_botlin) ? "" : > VIS_CHARS(_lineno) > +#define VIS_LINE_FACE(_lineno) ((_lineno) > _rl_vis_botlin) ? "" : > VIS_FACE(_lineno) > +#define INV_LINE(_lineno) (invisible_line + inv_lbreaks[_lineno]) > +#define INV_LINE_FACE(_lineno) (invisible_face + inv_lbreaks[_lineno]) > > #define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ > _rl_last_c_pos != o_cpos && \ > @@ -1087,7 +1130,11 @@ rl_redisplay () > the locale from a non-multibyte to a multibyte one. */ > o_cpos = _rl_last_c_pos; > cpos_adjusted = 0; > - update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, > + update_line (VIS_LINE(linenum), > + VIS_LINE_FACE(linenum), > + INV_LINE(linenum), > + INV_LINE_FACE(linenum), > + linenum, > VIS_LLEN(linenum), INV_LLEN(linenum), > inv_botlin); > > /* update_line potentially changes _rl_last_c_pos, but > doesn't > @@ -1157,7 +1204,7 @@ rl_redisplay () > { > tt = VIS_CHARS (linenum); > _rl_move_vert (linenum); > - _rl_move_cursor_relative (0, tt); > + _rl_move_cursor_relative (0, tt, VIS_FACE (linenum)); > _rl_clear_to_eol > ((linenum == _rl_vis_botlin) ? strlen (tt) : > _rl_screenwidth); > } > @@ -1191,12 +1238,7 @@ rl_redisplay () > _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) > #endif > { > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - if (_rl_term_cr) > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > if (modmark) > _rl_output_some_chars ("*", 1); > > @@ -1241,9 +1283,9 @@ rl_redisplay () > point specified by a buffer position (NLEFT) that doesn't take > invisible characters into account. */ > if (mb_cur_max > 1 && rl_byte_oriented == 0) > - _rl_move_cursor_relative (nleft, &invisible_line[pos]); > + _rl_move_cursor_relative (nleft, &invisible_line[pos], > &invisible_face[pos]); > else if (nleft != _rl_last_c_pos) > - _rl_move_cursor_relative (nleft, &invisible_line[pos]); > + _rl_move_cursor_relative (nleft, &invisible_line[pos], > &invisible_face[pos]); > } > } > else /* Do horizontal scrolling. */ > @@ -1299,7 +1341,7 @@ rl_redisplay () > /* If the first character on the screen isn't the first character > in the display line, indicate this with a special character. */ > if (lmargin > 0) > - line[lmargin] = '<'; > + invisible_line[lmargin] = '<'; > > /* If SCREENWIDTH characters starting at LMARGIN do not encompass > the whole line, indicate that with a special character at the > @@ -1307,7 +1349,7 @@ rl_redisplay () > wrap offset into account. */ > t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; > if (t < out) > - line[t - 1] = '>'; > + invisible_line[t - 1] = '>'; > > if (rl_display_fixed == 0 || forced_display || lmargin != > last_lmargin) > { > @@ -1315,7 +1357,9 @@ rl_redisplay () > o_cpos = _rl_last_c_pos; > cpos_adjusted = 0; > update_line (&visible_line[last_lmargin], > + &visible_face[last_lmargin], > &invisible_line[lmargin], > + &invisible_face[lmargin], > 0, > _rl_screenwidth + visible_wrap_offset, > _rl_screenwidth + (lmargin ? 0 : wrap_offset), > @@ -1340,7 +1384,9 @@ rl_redisplay () > if (visible_first_line_len > _rl_screenwidth) > visible_first_line_len = _rl_screenwidth; > > - _rl_move_cursor_relative (cpos_buffer_position - lmargin, > &invisible_line[lmargin]); > + _rl_move_cursor_relative (cpos_buffer_position - lmargin, > + &invisible_line[lmargin], > + &invisible_face[lmargin]); > last_lmargin = lmargin; > } > } > @@ -1367,6 +1413,40 @@ rl_redisplay () > _rl_release_sigint (); > } > > +static void > +putc_face (c, face, cur_face) > + int c, face; > + char *cur_face; > +{ > + char cf = *cur_face; > + if (cf != face) > + { > + if (cf != FACE_NORMAL && cf != FACE_STANDOUT) > + abort (); > + if (face != FACE_NORMAL && face != FACE_STANDOUT) > + abort (); > + if (face == FACE_STANDOUT && cf == FACE_NORMAL) > + _rl_standout_on (); > + if (face == FACE_NORMAL && cf == FACE_STANDOUT) > + _rl_standout_off (); > + *cur_face = face; > + } > + if (c != EOF) > + putc (c, rl_outstream); > +} > + > +static void > +puts_face (str, face, n) > + char *str; char *face; int n; > +{ > + int i; > + char cur_face = FACE_NORMAL; > + for (i = 0; i < n; ++i) > + putc_face (str[i], face[i], &cur_face); > + putc_face (EOF, FACE_NORMAL, &cur_face); > +} > + > + > /* PWP: update_line() is based on finding the middle difference of each > line on the screen; vis: > > @@ -1384,11 +1464,14 @@ new: eddie> Oh, my little buggy says to me, as > lurgid as > > Could be made even smarter, but this works well enough */ > static void > -update_line (old, new, current_line, omax, nmax, inv_botlin) > - register char *old, *new; > +update_line (old, old_face, new, new_face, > + current_line, omax, nmax, inv_botlin) > + char *old, *old_face; > + char *new, *new_face; > int current_line, omax, nmax, inv_botlin; > { > - register char *ofd, *ols, *oe, *nfd, *nls, *ne; > + char *ofd, *ols, *olsf, *oe, *nfd, *nls, *nlsf, *ne; > + char *ofdf, *nfdf; > int temp, lendiff, wsatend, od, nd, twidth, o_cpos; > int current_invis_chars; > int col_lendiff, col_temp; > @@ -1439,10 +1522,9 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > > if (tempwidth > 0) > { > - int count, i; > + int i; > bytes = ret; > - for (count = 0; count < bytes; count++) > - putc (new[count], rl_outstream); > + puts_face (new, new_face, bytes); > _rl_last_c_pos = tempwidth; > _rl_last_v_pos++; > memset (&ps, 0, sizeof (mbstate_t)); > @@ -1452,7 +1534,9 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > if (MB_INVALIDCH (ret)) > ret = 1; > memmove (old+bytes, old+ret, strlen (old+ret)); > + memmove (old_face+bytes, old_face+ret, strlen (old+ret)); > memcpy (old, new, bytes); > + memcpy (old_face, new_face, bytes); > /* Fix up indices if we copy data from one line to > another */ > omax += bytes - ret; > for (i = current_line+1; i <= inv_botlin+1; i++) > @@ -1465,20 +1549,26 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > _rl_last_c_pos = 1; > _rl_last_v_pos++; > if (old[0] && new[0]) > - old[0] = new[0]; > + { > + old[0] = new[0]; > + old_face[0] = new_face[0]; > + } > } > } > else > #endif > { > if (new[0]) > - putc (new[0], rl_outstream); > + puts_face (new, new_face, 1); > else > putc (' ', rl_outstream); > _rl_last_c_pos = 1; > _rl_last_v_pos++; > if (old[0] && new[0]) > - old[0] = new[0]; > + { > + old[0] = new[0]; > + old_face[0] = new_face[0]; > + } > } > } > > @@ -1490,46 +1580,60 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > /* See if the old line is a subset of the new line, so that the > only change is adding characters. */ > temp = (omax < nmax) ? omax : nmax; > - if (memcmp (old, new, temp) == 0) /* adding at the > end */ > + > + if (memcmp (old, new, temp) == 0 && > + memcmp (old_face, new_face, temp) == 0) > { > + /* adding at the end */ > new_offset = old_offset = temp; > ofd = old + temp; > + ofdf = old_face + temp; > nfd = new + temp; > + nfdf = new_face + temp; > } > else > { > memset (&ps_new, 0, sizeof(mbstate_t)); > memset (&ps_old, 0, sizeof(mbstate_t)); > > - if (omax == nmax && STREQN (new, old, omax)) > + if (omax == nmax && > + STREQN (new, old, omax) && > + memcmp (new_face, old_face, omax) == 0) > { > old_offset = omax; > new_offset = nmax; > ofd = old + omax; > + ofdf = old_face + omax; > nfd = new + nmax; > + nfdf = new_face + nmax; > } > else > { > + /* Here, we assume that faces only change at code-point > + boundaries. */ > new_offset = old_offset = 0; > - for (ofd = old, nfd = new; > - (ofd - old < omax) && *ofd && > - _rl_compare_chars(old, old_offset, &ps_old, new, > new_offset, &ps_new); ) > + for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; > + (ofd - old < omax) && *ofd && > + _rl_compare_chars(old, old_offset, &ps_old, new, > new_offset, &ps_new) && > + *ofdf == *nfdf; ) > { > old_offset = _rl_find_next_mbchar (old, old_offset, 1, > MB_FIND_ANY); > new_offset = _rl_find_next_mbchar (new, new_offset, 1, > MB_FIND_ANY); > > ofd = old + old_offset; > + ofdf = old_face + old_offset; > nfd = new + new_offset; > + nfdf = new_face + new_offset; > } > } > } > } > else > #endif > - for (ofd = old, nfd = new; > - (ofd - old < omax) && *ofd && (*ofd == *nfd); > - ofd++, nfd++) > - ; > + for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; > + (ofd - old < omax) && *ofd && (*ofd == *nfd) && (*ofdf == *nfdf); > + ofd++, nfd++, ofdf++, nfdf++) > + ; > > /* Move to the end of the screen line. ND and OD are used to keep track > of the distance between ne and new and oe and old, respectively, to > @@ -1557,7 +1661,9 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY); > new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY); > ofd = old + old_offset; /* equal by definition */ > - nfd = new + new_offset; > + ofdf = old_face + old_offset; > + nfd = new + new_offset; > + nfdf = new_face + new_offset; > } > } > #endif > @@ -1568,7 +1674,9 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > if (mb_cur_max > 1 && rl_byte_oriented == 0) > { > ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); > + olsf = old_face + (ols - old); > nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); > + nlsf = new_face + (nls - new); > > while ((ols > ofd) && (nls > nfd)) > { > @@ -1581,27 +1689,34 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > _rl_adjust_point (new, nls - new, &ps_new); > #endif > > - if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, > &ps_new) == 0) > + if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, > &ps_new) == 0 || > + *olsf != *nlsf) > break; > > if (*ols == ' ') > wsatend = 0; > > ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); > + olsf = old_face + (ols - old); > nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); > + nlsf = new_face + (nls - new); > } > } > else > { > #endif /* HANDLE_MULTIBYTE */ > ols = oe - 1; /* find last same */ > + olsf = old_face + (ols - old); > nls = ne - 1; > - while ((ols > ofd) && (nls > nfd) && (*ols == *nls)) > + nlsf = new_face + (nls - new); > + while ((ols > ofd) && (nls > nfd) && (*ols == *nls) && (*olsf == *nlsf)) > { > if (*ols != ' ') > wsatend = 0; > ols--; > + olsf--; > nls--; > + nlsf--; > } > #if defined (HANDLE_MULTIBYTE) > } > @@ -1610,15 +1725,18 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > if (wsatend) > { > ols = oe; > + olsf = old_face + (ols - old); > nls = ne; > + nlsf = new_face + (nls - new); > } > #if defined (HANDLE_MULTIBYTE) > /* This may not work for stateful encoding, but who cares? To handle > stateful encoding properly, we have to scan each string from the > beginning and compare. */ > - else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0) > + else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0 || > + *olsf != *nlsf) > #else > - else if (*ols != *nls) > + else if (*ols != *nls || *olsf != *nlsf) > #endif > { > if (*ols) /* don't step past the NUL */ > @@ -1635,6 +1753,8 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > else > nls++; > } > + olsf = old_face + (ols - old); > + nlsf = new_face + (nls - new); > } > > /* count of invisible characters in the current invisible line. */ > @@ -1684,11 +1804,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= > prompt_last_invisible)) || > ((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX))) > { > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > if (modmark) > _rl_output_some_chars ("*", 1); > _rl_output_some_chars (local_prompt, lendiff); > @@ -1721,13 +1837,14 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > if ((od <= prompt_last_invisible || nd <= prompt_last_invisible)) > { > nfd = new + lendiff; /* number of characters we output above */ > + nfdf = new_face + lendiff; > nd = lendiff; > > /* Do a dumb update and return */ > temp = ne - nfd; > if (temp > 0) > { > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > if (mb_cur_max > 1 && rl_byte_oriented == 0) > _rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1); > else > @@ -1745,7 +1862,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > /* When this function returns, _rl_last_c_pos is correct, and an > absolute > cursor position in multibyte mode, but a buffer index when not in a > multibyte locale. */ > - _rl_move_cursor_relative (od, old); > + _rl_move_cursor_relative (od, old, old_face); > > #if defined (HANDLE_MULTIBYTE) > /* We need to indicate that the cursor position is correct in the > presence of > @@ -1812,7 +1929,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > only happen in a multibyte environment. */ > if (lendiff < 0) > { > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > _rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, > 0, temp, 1); */ > /* If nfd begins before any invisible characters in the prompt, > adjust _rl_last_c_pos to account for wrap_offset and set > @@ -1849,7 +1966,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > (visible_wrap_offset >= current_invis_chars)) > { > open_some_spaces (col_lendiff); > - _rl_output_some_chars (nfd, bytes_to_insert); > + puts_face (nfd, nfdf, bytes_to_insert); > if (mb_cur_max > 1 && rl_byte_oriented == 0) > _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, > 1); > else > @@ -1859,13 +1976,13 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > { > /* At the end of a line the characters do not have to > be "inserted". They can just be placed on the screen. */ > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > _rl_last_c_pos += col_temp; > return; > } > else /* just write from first difference to end of new line */ > { > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > _rl_last_c_pos += col_temp; > /* If nfd begins before the last invisible character in the > prompt, adjust _rl_last_c_pos to account for wrap_offset > @@ -1893,7 +2010,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > else > { > /* cannot insert chars, write to EOL */ > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > _rl_last_c_pos += col_temp; > /* If we're in a multibyte locale and were before the last > invisible > char in the current line (which implies we just output some > invisible > @@ -1946,7 +2063,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > characters in the prompt, we need to adjust _rl_last_c_pos > in a multibyte locale to account for the wrap offset and > set cpos_adjusted accordingly. */ > - _rl_output_some_chars (nfd, bytes_to_insert); > + puts_face (nfd, nfdf, bytes_to_insert); > if (mb_cur_max > 1 && rl_byte_oriented == 0) > { > _rl_last_c_pos += _rl_col_width (nfd, 0, > bytes_to_insert, 1); > @@ -1966,7 +2083,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > so we move there with _rl_move_cursor_relative */ > if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new))) > { > - _rl_move_cursor_relative (ne-new, new); > + _rl_move_cursor_relative (ne-new, new, new_face); > goto clear_rest_of_line; > } > } > @@ -1980,7 +2097,7 @@ update_line (old, new, current_line, omax, nmax, > inv_botlin) > characters in the prompt, we need to adjust _rl_last_c_pos > in a multibyte locale to account for the wrap offset and > set cpos_adjusted accordingly. */ > - _rl_output_some_chars (nfd, temp); > + puts_face (nfd, nfdf, temp); > _rl_last_c_pos += col_temp; /* XXX */ > if (mb_cur_max > 1 && rl_byte_oriented == 0) > { > @@ -2040,11 +2157,7 @@ rl_clear_visible_line () > int curr_line; > > /* Make sure we move to column 0 so we clear the entire line */ > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > _rl_last_c_pos = 0; > > /* Move to the last screen line of the current visible line */ > @@ -2156,10 +2269,11 @@ rl_redraw_prompt_last_line () > DATA is the contents of the screen line of interest; i.e., where > the movement is being done. > DATA is always the visible line or the invisible line */ > -void > -_rl_move_cursor_relative (new, data) > +static void > +_rl_move_cursor_relative (new, data, dataf) > int new; > const char *data; > + const char *dataf; > { > register int i; > int woff; /* number of invisible chars on current > line */ > @@ -2256,11 +2370,7 @@ _rl_move_cursor_relative (new, data) > if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || > (_rl_term_autowrap && i == _rl_screenwidth)) > { > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif /* !__MSDOS__ */ > + _rl_cr (); > cpos = _rl_last_c_pos = 0; > } > > @@ -2293,13 +2403,11 @@ _rl_move_cursor_relative (new, data) > else > { > tputs (_rl_term_cr, 1, _rl_output_character_function); > - for (i = 0; i < new; i++) > - putc (data[i], rl_outstream); > + puts_face (data, dataf, new); > } > } > else > - for (i = cpos; i < new; i++) > - putc (data[i], rl_outstream); > + puts_face (data + cpos, dataf + cpos, new - cpos); > } > > #if defined (HANDLE_MULTIBYTE) > @@ -2328,11 +2436,7 @@ _rl_move_vert (to) > { > for (i = 0; i < delta; i++) > putc ('\n', rl_outstream); > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > _rl_last_c_pos = 0; > } > else > @@ -2680,16 +2784,6 @@ _rl_clear_screen () > #endif /* __DJGPP__ */ > } > > -/* Insert COUNT characters from STRING to the output stream at column > COL. */ > -static void > -insert_some_chars (string, count, col) > - char *string; > - int count, col; > -{ > - open_some_spaces (col); > - _rl_output_some_chars (string, count); > -} > - > /* Insert COL spaces, keeping the cursor at the same position. We follow > the > ncurses documentation and use either im/ei with explicit spaces, or > IC/ic > by itself. We assume there will either be ei or we don't need to use > it. */ > @@ -2772,12 +2866,16 @@ _rl_update_final () > if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == > _rl_screenwidth)) > { > char *last_line; > + char *last_face; > > last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; > + last_face = &visible_face[vis_lbreaks[_rl_vis_botlin]]; > cpos_buffer_position = -1; /* don't know where we are in > buffer */ > - _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* > XXX */ > + _rl_move_cursor_relative (_rl_screenwidth - 1, last_line, > last_face); > _rl_clear_to_eol (0); > - putc (last_line[_rl_screenwidth - 1], rl_outstream); > + puts_face (&last_line[_rl_screenwidth - 1], > + &last_face[_rl_screenwidth - 1], > + 1); > } > _rl_vis_botlin = 0; > rl_crlf (); > @@ -2791,11 +2889,7 @@ cr () > { > if (_rl_term_cr) > { > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > _rl_last_c_pos = 0; > } > } > @@ -2840,12 +2934,7 @@ _rl_redisplay_after_sigwinch () > if (_rl_term_cr) > { > _rl_move_vert (_rl_vis_botlin); > - > -#if defined (__MSDOS__) > - putc ('\r', rl_outstream); > -#else > - tputs (_rl_term_cr, 1, _rl_output_character_function); > -#endif > + _rl_cr (); > _rl_last_c_pos = 0; > #if defined (__MSDOS__) > space_to_eol (_rl_screenwidth); > @@ -2903,7 +2992,7 @@ _rl_ttyflush () > > /* return the `current display line' of the cursor -- the number of lines > to > move up to get to the first screen line of the current readline line. > */ > -int > +static int > _rl_current_display_line () > { > int ret, nleft; > @@ -2923,6 +3012,17 @@ _rl_current_display_line () > return ret; > } > > +/* Clear the current line. Numeric argument to C-l does this. */ > +int > +rl_refresh_line (ignore1, ignore2) > + int ignore1, ignore2; > +{ > + rl_clear_visible_line (); > + rl_redraw_prompt_last_line (); > + rl_keep_mark_active (); > + return 0; > +} > + > #if defined (HANDLE_MULTIBYTE) > /* Calculate the number of screen columns occupied by STR from START to > END. > In the case of multibyte characters with stateful encoding, we have to > diff --git a/lib/readline/kill.c b/lib/readline/kill.c > index 696f1938..e99b286b 100644 > --- a/lib/readline/kill.c > +++ b/lib/readline/kill.c > @@ -693,7 +693,7 @@ rl_yank_last_arg (count, key) > /* Having read the special escape sequence denoting the beginning of a > `bracketed paste' sequence, read the rest of the pasted input until the > closing sequence and insert the pasted text as a single unit without > - interpretation. */ > + interpretation. Temporarily highlight the inserted text. */ > int > rl_bracketed_paste_begin (count, key) > int count, key; > @@ -730,13 +730,17 @@ rl_bracketed_paste_begin (count, key) > > if (c >= 0) > { > + int old_point; > if (len == cap) > buf = xrealloc (buf, cap + 1); > buf[len] = '\0'; > + rl_mark = rl_point; > retval = rl_insert_text (buf); > + rl_activate_mark (); > } > > xfree (buf); > + > return (retval); > } > > diff --git a/lib/readline/readline.c b/lib/readline/readline.c > index e51df4f0..edccf323 100644 > --- a/lib/readline/readline.c > +++ b/lib/readline/readline.c > @@ -259,6 +259,10 @@ int _rl_executing_keyseq_size = 0; > ambiguous multiple-key sequence */ > int _rl_keyseq_timeout = 500; > > +/* Indicates that a command wants to keep the mark active after > + running. */ > +static int _rl_keep_mark_active = 0; > + > #define RESIZE_KEYSEQ_BUFFER() \ > do \ > { \ > @@ -416,6 +420,8 @@ readline_internal_setup () > if (rl_startup_hook) > (*rl_startup_hook) (); > > + rl_deactivate_mark (); > + > #if defined (VI_MODE) > if (rl_editing_mode == vi_mode) > rl_vi_insertion_mode (1, 'i'); /* don't want to reset last */ > @@ -635,6 +641,11 @@ readline_internal_charloop () > if (rl_pending_input == 0 && lk == _rl_last_command_was_kill) > _rl_last_command_was_kill = 0; > > + if (_rl_keep_mark_active) > + _rl_keep_mark_active = 0; > + else if (rl_mark_active_p ()) > + rl_deactivate_mark (); > + > _rl_internal_char_cleanup (); > > #if defined (READLINE_CALLBACKS) > @@ -646,6 +657,12 @@ readline_internal_charloop () > #endif > } > > +void > +rl_keep_mark_active () > +{ > + _rl_keep_mark_active++; > +} > + > #if defined (READLINE_CALLBACKS) > static int > readline_internal_charloop () > @@ -1439,5 +1456,7 @@ rl_restore_state (sp) > rl_attempted_completion_function = sp->attemptfunc; > rl_completer_word_break_characters = sp->wordbreakchars; > > + rl_deactivate_mark (); > + > return (0); > } > diff --git a/lib/readline/readline.h b/lib/readline/readline.h > index 924bbfb0..f1fc6b76 100644 > --- a/lib/readline/readline.h > +++ b/lib/readline/readline.h > @@ -133,6 +133,10 @@ extern int rl_get_previous_history PARAMS((int, int)); > /* Bindable commands for managing the mark and region. */ > extern int rl_set_mark PARAMS((int, int)); > extern int rl_exchange_point_and_mark PARAMS((int, int)); > +extern void rl_activate_mark PARAMS((void)); > +extern void rl_deactivate_mark PARAMS((void)); > +extern int rl_mark_active_p PARAMS((void)); > +extern void rl_keep_mark_active PARAMS((void)); > > /* Bindable commands to set the editing mode (emacs or vi). */ > extern int rl_vi_editing_mode PARAMS((int, int)); > diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h > index fc3856a1..63bc1737 100644 > --- a/lib/readline/rlprivate.h > +++ b/lib/readline/rlprivate.h > @@ -265,7 +265,6 @@ extern void _rl_free_match_list PARAMS((char **)); > /* display.c */ > extern char *_rl_strip_prompt PARAMS((char *)); > extern void _rl_reset_prompt PARAMS((void)); > -extern void _rl_move_cursor_relative PARAMS((int, const char *)); > extern void _rl_move_vert PARAMS((int)); > extern void _rl_save_prompt PARAMS((void)); > extern void _rl_restore_prompt PARAMS((void)); > @@ -277,7 +276,6 @@ extern void _rl_update_final PARAMS((void)); > extern void _rl_redisplay_after_sigwinch PARAMS((void)); > extern void _rl_clean_up_for_exit PARAMS((void)); > extern void _rl_erase_entire_line PARAMS((void)); > -extern int _rl_current_display_line PARAMS((void)); > > /* input.c */ > extern int _rl_any_typein PARAMS((void)); > @@ -373,6 +371,9 @@ extern void _rl_enable_meta_key PARAMS((void)); > extern void _rl_disable_meta_key PARAMS((void)); > extern void _rl_control_keypad PARAMS((int)); > extern void _rl_set_cursor PARAMS((int, int)); > +extern void _rl_standout_on PARAMS((void)); > +extern void _rl_standout_off PARAMS((void)); > +extern void _rl_cr PARAMS((void)); > > /* text.c */ > extern void _rl_fix_point PARAMS((int)); > diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c > index ef2884e0..c1df30e1 100644 > --- a/lib/readline/terminal.c > +++ b/lib/readline/terminal.c > @@ -150,6 +150,10 @@ static int term_has_meta; > static char *_rl_term_mm; > static char *_rl_term_mo; > > +/* Enter and exit standout mode. */ > +char *_rl_term_so; > +char *_rl_term_se; > + > /* The key sequences output by the arrow keys, if this terminal has any. > */ > static char *_rl_term_ku; > static char *_rl_term_kd; > @@ -413,6 +417,8 @@ static const struct _tc_string tc_strings[] = > { "mo", &_rl_term_mo }, > { "nd", &_rl_term_forward_char }, > { "pc", &_rl_term_pc }, > + { "se", &_rl_term_se }, > + { "so", &_rl_term_so }, > { "up", &_rl_term_up }, > { "vb", &_rl_visible_bell }, > { "vs", &_rl_term_vs }, > @@ -462,6 +468,7 @@ _rl_init_terminal_io (terminal_name) > _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_so = _rl_term_se = (char *)NULL; > #if defined(HACK_TERMCAP_MOTION) > _rl_term_forward_char = (char *)NULL; > #endif > @@ -526,6 +533,7 @@ _rl_init_terminal_io (terminal_name) > _rl_term_mm = _rl_term_mo = (char *)NULL; > _rl_term_ve = _rl_term_vs = (char *)NULL; > _rl_term_forward_char = (char *)NULL; > + _rl_term_so = _rl_term_se = (char *)NULL; > _rl_terminal_can_insert = term_has_meta = 0; > > /* Reasonable defaults for tgoto(). Readline currently only uses > @@ -688,6 +696,17 @@ rl_crlf () > return 0; > } > > +/* Move to start of current line. */ > +void > +_rl_cr () > +{ > +#if defined (__MSDOS__) > + putc ('\r', rl_outstream); > +#else > + tputs (_rl_term_cr, 1, _rl_output_character_function); > +#endif > +} > + > /* Ring the terminal bell. */ > int > rl_ding () > @@ -791,3 +810,27 @@ _rl_set_cursor (im, force) > } > #endif > } > + > +/* **************************************************************** */ > +/* */ > +/* Entering and leaving standout */ > +/* */ > +/* **************************************************************** */ > + > +void > +_rl_standout_on() > +{ > +#ifndef __MSDOS__ > + if (_rl_term_so && _rl_term_se) > + tputs (_rl_term_so, 1, _rl_output_character_function); > +#endif > +} > + > +void > +_rl_standout_off() > +{ > +#ifndef __MSDOS__ > + if (_rl_term_so && _rl_term_se) > + tputs (_rl_term_se, 1, _rl_output_character_function); > +#endif > +} > diff --git a/lib/readline/text.c b/lib/readline/text.c > index c353252b..87eccd92 100644 > --- a/lib/readline/text.c > +++ b/lib/readline/text.c > @@ -558,26 +558,6 @@ rl_backward_word (count, key) > return 0; > } > > -/* Clear the current line. Numeric argument to C-l does this. */ > -int > -rl_refresh_line (ignore1, ignore2) > - int ignore1, ignore2; > -{ > - int curr_line; > - > - curr_line = _rl_current_display_line (); > - > - _rl_move_vert (curr_line); > - _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */ > - > - _rl_clear_to_eol (0); /* arg of 0 means to not use > spaces */ > - > - rl_redraw_prompt_last_line (); > - rl_display_fixed = 1; > - > - return 0; > -} > - > /* C-l typed to a line without quoting clears the screen, and then > reprints > the prompt and the current input line. Given a numeric arg, redraw > only > the current line. */ > @@ -592,6 +572,7 @@ rl_clear_screen (count, key) > } > > _rl_clear_screen (); /* calls termcap function to clear screen > */ > + rl_keep_mark_active (); > rl_forced_update_display (); > rl_display_fixed = 1; > > @@ -1018,6 +999,13 @@ int > rl_newline (count, key) > int count, key; > { > + if (rl_mark_active_p ()) > + { > + rl_deactivate_mark (); > + (*rl_redisplay_function) (); > + _rl_want_redisplay = 0; > + } > + > rl_done = 1; > > if (_rl_history_preserve_point) > @@ -1744,7 +1732,32 @@ rl_exchange_point_and_mark (count, key) > return 1; > } > else > - SWAP (rl_point, rl_mark); > + { > + SWAP (rl_point, rl_mark); > + rl_activate_mark (); > + } > > return 0; > } > + > +static int mark_active = 0; > + > +void > +rl_activate_mark () > +{ > + if (!mark_active) > + mark_active++; > + rl_keep_mark_active (); > +} > + > +void > +rl_deactivate_mark () > +{ > + mark_active = 0; > +} > + > +int > +rl_mark_active_p () > +{ > + return mark_active; > +} > diff --git a/lib/readline/util.c b/lib/readline/util.c > index 4589c61f..922f09a2 100644 > --- a/lib/readline/util.c > +++ b/lib/readline/util.c > @@ -103,6 +103,7 @@ _rl_abort_internal () > rl_clear_message (); > _rl_reset_argument (); > rl_clear_pending_input (); > + rl_deactivate_mark(); > > RL_UNSETSTATE (RL_STATE_MACRODEF); > while (rl_executing_macro) > -- > 2.16.2.660.g709887971b-goog > >