[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Add active mark, face support; activate mark on paste
From: |
Daniel Colascione |
Subject: |
Re: [PATCH] Add active mark, face support; activate mark on paste |
Date: |
Mon, 19 Mar 2018 10:25:12 -0700 |
Ping
On Fri, Mar 9, 2018 at 11:50 PM, Daniel Colascione <dancol@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
>
>