bug-bash
[Top][All Lists]
Advanced

[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
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]