Diff for /embedaddon/readline/vi_mode.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2014/07/30 08:16:45 version 1.1.1.2, 2021/03/17 01:01:01
Line 1 Line 1
 /* vi_mode.c -- A vi emulation mode for Bash.  /* vi_mode.c -- A vi emulation mode for Bash.
    Derived from code written by Jeff Sparkes (jsparkes@bnr.ca).  */     Derived from code written by Jeff Sparkes (jsparkes@bnr.ca).  */
   
/* Copyright (C) 1987-2012 Free Software Foundation, Inc./* Copyright (C) 1987-2020 Free Software Foundation, Inc.
   
    This file is part of the GNU Readline Library (Readline), a library     This file is part of the GNU Readline Library (Readline), a library
    for reading lines of text with interactive input and history editing.           for reading lines of text with interactive input and history editing.      
Line 63 Line 63
 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)  #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
 #endif  #endif
   
   /* Increment START to the next character in RL_LINE_BUFFER, handling multibyte chars */
   #if defined (HANDLE_MULTIBYTE)
   #define INCREMENT_POS(start) \
     do { \
           if (MB_CUR_MAX == 1 || rl_byte_oriented) \
             start++; \
           else \
             start = _rl_find_next_mbchar (rl_line_buffer, start, 1, MB_FIND_ANY); \
     } while (0)
   #else /* !HANDLE_MULTIBYTE */
   #define INCREMENT_POS(start)    (start)++
   #endif /* !HANDLE_MULTIBYTE */
   
   /* This is global so other parts of the code can check whether the last
      command was a text modification command. */
 int _rl_vi_last_command = 'i';  /* default `.' puts you in insert mode */  int _rl_vi_last_command = 'i';  /* default `.' puts you in insert mode */
   
 _rl_vimotion_cxt *_rl_vimvcxt = 0;  _rl_vimotion_cxt *_rl_vimvcxt = 0;
   
   /* Non-zero indicates we are redoing a vi-mode command with `.' */
   int _rl_vi_redoing;
   
 /* Non-zero means enter insertion mode. */  /* Non-zero means enter insertion mode. */
 static int _rl_vi_doing_insert;  static int _rl_vi_doing_insert;
   
Line 96  static int _rl_vi_last_search_mblen; Line 114  static int _rl_vi_last_search_mblen;
 #else  #else
 static int _rl_vi_last_search_char;  static int _rl_vi_last_search_char;
 #endif  #endif
static int _rl_vi_last_replacement;static char _rl_vi_last_replacement[MB_LEN_MAX+1]; /* reserve for trailing NULL */
   
 static int _rl_vi_last_key_before_insert;  static int _rl_vi_last_key_before_insert;
   
 static int vi_redoing;  
   
 /* Text modification commands.  These are the `redoable' commands. */  /* Text modification commands.  These are the `redoable' commands. */
 static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";  static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
   
Line 115  static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); Line 131  static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
   
 static void vi_save_insert_buffer PARAMS ((int, int));  static void vi_save_insert_buffer PARAMS ((int, int));
   
static void _rl_vi_backup PARAMS((void));static inline void _rl_vi_backup PARAMS((void));
   
 static int _rl_vi_arg_dispatch PARAMS((int));  static int _rl_vi_arg_dispatch PARAMS((int));
 static int rl_digit_loop1 PARAMS((void));  static int rl_digit_loop1 PARAMS((void));
Line 123  static int rl_digit_loop1 PARAMS((void)); Line 139  static int rl_digit_loop1 PARAMS((void));
 static int _rl_vi_set_mark PARAMS((void));  static int _rl_vi_set_mark PARAMS((void));
 static int _rl_vi_goto_mark PARAMS((void));  static int _rl_vi_goto_mark PARAMS((void));
   
   static inline int _rl_vi_advance_point PARAMS((void));
   static inline int _rl_vi_backup_point PARAMS((void));
   
 static void _rl_vi_append_forward PARAMS((int));  static void _rl_vi_append_forward PARAMS((int));
   
 static int _rl_vi_callback_getchar PARAMS((char *, int));  static int _rl_vi_callback_getchar PARAMS((char *, int));
Line 145  static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt * Line 164  static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *
 static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));  static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
   
 void  void
_rl_vi_initialize_line ()_rl_vi_initialize_line (void)
 {  {
   register int i, n;    register int i, n;
   
Line 157  _rl_vi_initialize_line () Line 176  _rl_vi_initialize_line ()
 }  }
   
 void  void
_rl_vi_reset_last ()_rl_vi_reset_last (void)
 {  {
   _rl_vi_last_command = 'i';    _rl_vi_last_command = 'i';
   _rl_vi_last_repeat = 1;    _rl_vi_last_repeat = 1;
Line 166  _rl_vi_reset_last () Line 185  _rl_vi_reset_last ()
 }  }
   
 void  void
_rl_vi_set_last (key, repeat, sign)_rl_vi_set_last (int key, int repeat, int sign)
     int key, repeat, sign; 
 {  {
   _rl_vi_last_command = key;    _rl_vi_last_command = key;
   _rl_vi_last_repeat = repeat;    _rl_vi_last_repeat = repeat;
Line 177  _rl_vi_set_last (key, repeat, sign) Line 195  _rl_vi_set_last (key, repeat, sign)
 /* A convenience function that calls _rl_vi_set_last to save the last command  /* A convenience function that calls _rl_vi_set_last to save the last command
    information and enters insertion mode. */     information and enters insertion mode. */
 void  void
rl_vi_start_inserting (key, repeat, sign)rl_vi_start_inserting (int key, int repeat, int sign)
     int key, repeat, sign; 
 {  {
   _rl_vi_set_last (key, repeat, sign);    _rl_vi_set_last (key, repeat, sign);
     rl_begin_undo_group ();               /* ensure inserts aren't concatenated */
   rl_vi_insertion_mode (1, key);    rl_vi_insertion_mode (1, key);
 }  }
   
 /* Is the command C a VI mode text modification command? */  /* Is the command C a VI mode text modification command? */
 int  int
_rl_vi_textmod_command (c)_rl_vi_textmod_command (int c)
     int c; 
 {  {
   return (member (c, vi_textmod));    return (member (c, vi_textmod));
 }  }
   
   int
   _rl_vi_motion_command (int c)
   {
     return (member (c, vi_motion));
   }
   
 static void  static void
_rl_vi_replace_insert (count)_rl_vi_replace_insert (int count)
     int count; 
 {  {
   int nchars;    int nchars;
   
Line 209  _rl_vi_replace_insert (count) Line 231  _rl_vi_replace_insert (count)
 }  }
   
 static void  static void
_rl_vi_stuff_insert (count)_rl_vi_stuff_insert (int count)
     int count; 
 {  {
   rl_begin_undo_group ();    rl_begin_undo_group ();
   while (count--)    while (count--)
Line 222  _rl_vi_stuff_insert (count) Line 243  _rl_vi_stuff_insert (count)
    redo a text modification command.  The default for _rl_vi_last_command     redo a text modification command.  The default for _rl_vi_last_command
    puts you back into insert mode. */     puts you back into insert mode. */
 int  int
rl_vi_redo (count, c)rl_vi_redo (int count, int c)
     int count, c; 
 {  {
   int r;    int r;
   
Line 234  rl_vi_redo (count, c) Line 254  rl_vi_redo (count, c)
     }      }
   
   r = 0;    r = 0;
  vi_redoing = 1;  _rl_vi_redoing = 1;
   /* If we're redoing an insert with `i', stuff in the inserted text    /* If we're redoing an insert with `i', stuff in the inserted text
      and do not go into insertion mode. */       and do not go into insertion mode. */
   if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)    if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
Line 278  rl_vi_redo (count, c) Line 298  rl_vi_redo (count, c)
       if (rl_point > 0)        if (rl_point > 0)
         _rl_vi_backup ();          _rl_vi_backup ();
     }      }
     else if (_rl_vi_last_command == '.' && _rl_keymap == vi_movement_keymap)
       {
         rl_ding ();
         r = 0;
       }
   else    else
     r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);      r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
   vi_redoing = 0;  
   
     _rl_vi_redoing = 0;
   
   return (r);    return (r);
 }  }
   
 /* A placeholder for further expansion. */  /* A placeholder for further expansion. */
 int  int
rl_vi_undo (count, key)rl_vi_undo (int count, int key)
     int count, key; 
 {  {
   return (rl_undo_command (count, key));    return (rl_undo_command (count, key));
 }  }
           
 /* Yank the nth arg from the previous line into this line at point. */  /* Yank the nth arg from the previous line into this line at point. */
 int  int
rl_vi_yank_arg (count, key)rl_vi_yank_arg (int count, int key)
     int count, key; 
 {  {
   /* Readline thinks that the first word on a line is the 0th, while vi    /* Readline thinks that the first word on a line is the 0th, while vi
      thinks the first word on a line is the 1st.  Compensate. */       thinks the first word on a line is the 1st.  Compensate. */
   if (rl_explicit_arg)    if (rl_explicit_arg)
    rl_yank_nth_arg (count - 1, 0);    rl_yank_nth_arg (count - 1, key);
   else    else
    rl_yank_nth_arg ('$', 0);    rl_yank_nth_arg ('$', key);
   
   return (0);    return (0);
 }  }
Line 311  rl_vi_yank_arg (count, key) Line 335  rl_vi_yank_arg (count, key)
 /* With an argument, move back that many history lines, else move to the  /* With an argument, move back that many history lines, else move to the
    beginning of history. */     beginning of history. */
 int  int
rl_vi_fetch_history (count, c)rl_vi_fetch_history (int count, int c)
     int count, c; 
 {  {
   int wanted;    int wanted;
   
Line 336  rl_vi_fetch_history (count, c) Line 359  rl_vi_fetch_history (count, c)
   
 /* Search again for the last thing searched for. */  /* Search again for the last thing searched for. */
 int  int
rl_vi_search_again (count, key)rl_vi_search_again (int count, int key)
     int count, key; 
 {  {
   switch (key)    switch (key)
     {      {
Line 354  rl_vi_search_again (count, key) Line 376  rl_vi_search_again (count, key)
   
 /* Do a vi style search. */  /* Do a vi style search. */
 int  int
rl_vi_search (count, key)rl_vi_search (int count, int key)
     int count, key; 
 {  {
   switch (key)    switch (key)
     {      {
Line 378  rl_vi_search (count, key) Line 399  rl_vi_search (count, key)
   
 /* Completion, from vi's point of view. */  /* Completion, from vi's point of view. */
 int  int
rl_vi_complete (ignore, key)rl_vi_complete (int ignore, int key)
     int ignore, key; 
 {  {
   if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))    if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
     {      {
       if (!whitespace (rl_line_buffer[rl_point + 1]))        if (!whitespace (rl_line_buffer[rl_point + 1]))
         rl_vi_end_word (1, 'E');          rl_vi_end_word (1, 'E');
      rl_point++;      _rl_vi_advance_point ();
     }      }
   
   if (key == '*')    if (key == '*')
Line 405  rl_vi_complete (ignore, key) Line 425  rl_vi_complete (ignore, key)
   
 /* Tilde expansion for vi mode. */  /* Tilde expansion for vi mode. */
 int  int
rl_vi_tilde_expand (ignore, key)rl_vi_tilde_expand (int ignore, int key)
     int ignore, key; 
 {  {
   rl_tilde_expand (0, key);    rl_tilde_expand (0, key);
   rl_vi_start_inserting (key, 1, rl_arg_sign);    rl_vi_start_inserting (key, 1, rl_arg_sign);
Line 415  rl_vi_tilde_expand (ignore, key) Line 434  rl_vi_tilde_expand (ignore, key)
   
 /* Previous word in vi mode. */  /* Previous word in vi mode. */
 int  int
rl_vi_prev_word (count, key)rl_vi_prev_word (int count, int key)
     int count, key; 
 {  {
   if (count < 0)    if (count < 0)
     return (rl_vi_next_word (-count, key));      return (rl_vi_next_word (-count, key));
Line 437  rl_vi_prev_word (count, key) Line 455  rl_vi_prev_word (count, key)
   
 /* Next word in vi mode. */  /* Next word in vi mode. */
 int  int
rl_vi_next_word (count, key)rl_vi_next_word (int count, int key)
     int count, key; 
 {  {
   if (count < 0)    if (count < 0)
     return (rl_vi_prev_word (-count, key));      return (rl_vi_prev_word (-count, key));
Line 456  rl_vi_next_word (count, key) Line 473  rl_vi_next_word (count, key)
   return (0);    return (0);
 }  }
   
   static inline int
   _rl_vi_advance_point (void)
   {
     int point;
   
     point = rl_point;
     if (rl_point < rl_end)
   #if defined (HANDLE_MULTIBYTE)
       {
         if (MB_CUR_MAX == 1 || rl_byte_oriented)
           rl_point++;
         else
           {
             point = rl_point;
             rl_point = _rl_forward_char_internal (1);
             if (point == rl_point || rl_point > rl_end)
               rl_point = rl_end;
           }
       }
   #else
       rl_point++;
   #endif
   
     return point;
   }
   
   /* Move the cursor back one character. */
   static inline void
   _rl_vi_backup (void)
   {
     if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
       rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
     else
       rl_point--;
   }
   
   /* Move the point back one character, returning the starting value and not
      doing anything at the beginning of the line */
   static inline int
   _rl_vi_backup_point (void)
   {
     int point;
   
     point = rl_point;
     if (rl_point > 0)
   #if defined (HANDLE_MULTIBYTE)
       {
         if (MB_CUR_MAX == 1 || rl_byte_oriented)
           rl_point--;
         else
           {
             point = rl_point;
             rl_point = _rl_backward_char_internal (1);
             if (rl_point < 0)
               rl_point = 0;               /* XXX - not really necessary */
           }
       }
   #else
       rl_point--;
   #endif
     return point;
   }
   
 /* Move to the end of the ?next? word. */  /* Move to the end of the ?next? word. */
 int  int
rl_vi_end_word (count, key)rl_vi_end_word (int count, int key)
     int count, key; 
 {  {
   if (count < 0)    if (count < 0)
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   
   if (_rl_uppercase_p (key))    if (_rl_uppercase_p (key))
Line 476  rl_vi_end_word (count, key) Line 555  rl_vi_end_word (count, key)
   
 /* Move forward a word the way that 'W' does. */  /* Move forward a word the way that 'W' does. */
 int  int
rl_vi_fWord (count, ignore)rl_vi_fWord (int count, int ignore)
     int count, ignore; 
 {  {
   while (count-- && rl_point < (rl_end - 1))    while (count-- && rl_point < (rl_end - 1))
     {      {
       /* Skip until whitespace. */        /* Skip until whitespace. */
       while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)        while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
        rl_point++;        _rl_vi_advance_point ();
   
       /* Now skip whitespace. */        /* Now skip whitespace. */
       while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)        while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
        rl_point++;        _rl_vi_advance_point ();
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_bWord (count, ignore)rl_vi_bWord (int count, int ignore)
     int count, ignore; 
 {  {
   while (count-- && rl_point > 0)    while (count-- && rl_point > 0)
     {      {
Line 505  rl_vi_bWord (count, ignore) Line 582  rl_vi_bWord (count, ignore)
         rl_point--;          rl_point--;
   
       while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))        while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
        rl_point--;        _rl_vi_backup_point ();
   
       if (rl_point > 0)        if (rl_point > 0)
         {          {
          while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));          do
          rl_point++;            _rl_vi_backup_point ();
           while (rl_point > 0 && !whitespace (rl_line_buffer[rl_point]));
           if (rl_point > 0)       /* hit whitespace */
             rl_point++;         
 
           if (rl_point < 0)
             rl_point = 0;
         }          }
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_eWord (count, ignore)rl_vi_eWord (int count, int ignore)
     int count, ignore; 
 {  {
     int opoint;
   
   while (count-- && rl_point < (rl_end - 1))    while (count-- && rl_point < (rl_end - 1))
     {      {
      if (!whitespace (rl_line_buffer[rl_point]))      if (whitespace (rl_line_buffer[rl_point]) == 0)
        rl_point++;        _rl_vi_advance_point ();
   
       /* Move to the next non-whitespace character (to the start of the        /* Move to the next non-whitespace character (to the start of the
          next word). */           next word). */
       while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))        while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
        rl_point++;        _rl_vi_advance_point ();
   
       if (rl_point && rl_point < rl_end)        if (rl_point && rl_point < rl_end)
         {          {
             opoint = rl_point;
   
           /* Skip whitespace. */            /* Skip whitespace. */
           while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))            while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
            rl_point++;            opoint = _rl_vi_advance_point ();     /* XXX - why? */
   
           /* Skip until whitespace. */            /* Skip until whitespace. */
           while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))            while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
            rl_point++;            opoint = _rl_vi_advance_point ();
   
           /* Move back to the last character of the word. */            /* Move back to the last character of the word. */
          rl_point--;          rl_point = opoint;
         }          }
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_fword (count, ignore)rl_vi_fword (int count, int ignore)
     int count, ignore; 
 {  {
     int opoint;
   
   while (count-- && rl_point < (rl_end - 1))    while (count-- && rl_point < (rl_end - 1))
     {      {
       /* Move to white space (really non-identifer). */        /* Move to white space (really non-identifer). */
       if (_rl_isident (rl_line_buffer[rl_point]))        if (_rl_isident (rl_line_buffer[rl_point]))
         {          {
           while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)            while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
            rl_point++;            _rl_vi_advance_point ();
         }          }
       else /* if (!whitespace (rl_line_buffer[rl_point])) */        else /* if (!whitespace (rl_line_buffer[rl_point])) */
         {          {
           while (!_rl_isident (rl_line_buffer[rl_point]) &&            while (!_rl_isident (rl_line_buffer[rl_point]) &&
                  !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)                   !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
            rl_point++;            _rl_vi_advance_point ();
         }          }
   
         opoint = rl_point;
   
       /* Move past whitespace. */        /* Move past whitespace. */
       while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)        while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
        rl_point++;        opoint = _rl_vi_advance_point ();
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_bword (count, ignore)rl_vi_bword (int count, int ignore)
     int count, ignore; 
 {  {
     int opoint;
   
   while (count-- && rl_point > 0)    while (count-- && rl_point > 0)
     {      {
      int last_is_ident;      int prev_is_ident, cur_is_ident;
   
       /* If we are at the start of a word, move back to whitespace        /* If we are at the start of a word, move back to whitespace
          so we will go back to the start of the previous word. */           so we will go back to the start of the previous word. */
       if (!whitespace (rl_line_buffer[rl_point]) &&        if (!whitespace (rl_line_buffer[rl_point]) &&
           whitespace (rl_line_buffer[rl_point - 1]))            whitespace (rl_line_buffer[rl_point - 1]))
        rl_point--;        if (--rl_point == 0)
           break;
   
       /* If this character and the previous character are `opposite', move        /* If this character and the previous character are `opposite', move
          back so we don't get messed up by the rl_point++ down there in           back so we don't get messed up by the rl_point++ down there in
          the while loop.  Without this code, words like `l;' screw up the           the while loop.  Without this code, words like `l;' screw up the
          function. */           function. */
      last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);      cur_is_ident = _rl_isident (rl_line_buffer[rl_point]);
      if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||      opoint = _rl_vi_backup_point ();
          (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))      prev_is_ident = _rl_isident (rl_line_buffer[rl_point]);
        rl_point--;      if ((cur_is_ident && !prev_is_ident) || (!cur_is_ident && prev_is_ident))
         ;       /* leave point alone, we backed it up one character */
       else
         rl_point = opoint;
   
       while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))        while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
        rl_point--;        _rl_vi_backup_point ();
   
       if (rl_point > 0)        if (rl_point > 0)
         {          {
             opoint = rl_point;
           if (_rl_isident (rl_line_buffer[rl_point]))            if (_rl_isident (rl_line_buffer[rl_point]))
            while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));            do
               opoint = _rl_vi_backup_point ();
             while (rl_point > 0 && _rl_isident (rl_line_buffer[rl_point]));
           else            else
            while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&            do
               opoint = _rl_vi_backup_point ();
             while (rl_point > 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
                    !whitespace (rl_line_buffer[rl_point]));                     !whitespace (rl_line_buffer[rl_point]));
          rl_point++;
           if (rl_point > 0)
             rl_point = opoint;
 
           if (rl_point < 0)
             rl_point = 0;
         }          }
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_eword (count, ignore)rl_vi_eword (int count, int ignore)
     int count, ignore; 
 {  {
  while (count-- && rl_point < rl_end - 1)  int opoint;
 
   while (count-- && rl_point < (rl_end - 1))
     {      {
      if (!whitespace (rl_line_buffer[rl_point]))      if (whitespace (rl_line_buffer[rl_point]) == 0)
        rl_point++;        _rl_vi_advance_point ();
   
       while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))        while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
        rl_point++;        _rl_vi_advance_point ();
   
         opoint = rl_point;
       if (rl_point < rl_end)        if (rl_point < rl_end)
         {          {
           if (_rl_isident (rl_line_buffer[rl_point]))            if (_rl_isident (rl_line_buffer[rl_point]))
            while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));            do
               {
                 opoint = _rl_vi_advance_point ();
               }
             while (rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
           else            else
            while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])            do
               {
                 opoint = _rl_vi_advance_point ();
               }
             while (rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
                    && !whitespace (rl_line_buffer[rl_point]));                     && !whitespace (rl_line_buffer[rl_point]));
         }          }
      rl_point--;      rl_point = opoint;
     }      }
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_insert_beg (count, key)rl_vi_insert_beg (int count, int key)
     int count, key; 
 {  {
   rl_beg_of_line (1, key);    rl_beg_of_line (1, key);
   rl_vi_insert_mode (1, key);    rl_vi_insert_mode (1, key);
Line 647  rl_vi_insert_beg (count, key) Line 760  rl_vi_insert_beg (count, key)
 }  }
   
 static void  static void
_rl_vi_append_forward (key)_rl_vi_append_forward (int key)
     int key; 
 {  {
  int point;  _rl_vi_advance_point ();
 
  if (rl_point < rl_end) 
    { 
      if (MB_CUR_MAX == 1 || rl_byte_oriented) 
        rl_point++; 
      else 
        { 
          point = rl_point; 
#if 0 
          rl_forward_char (1, key); 
#else 
          rl_point = _rl_forward_char_internal (1); 
#endif 
          if (point == rl_point) 
            rl_point = rl_end; 
        } 
    } 
 }  }
   
 int  int
rl_vi_append_mode (count, key)rl_vi_append_mode (int count, int key)
     int count, key; 
 {  {
   _rl_vi_append_forward (key);    _rl_vi_append_forward (key);
   rl_vi_start_inserting (key, 1, rl_arg_sign);    rl_vi_start_inserting (key, 1, rl_arg_sign);
Line 680  rl_vi_append_mode (count, key) Line 774  rl_vi_append_mode (count, key)
 }  }
   
 int  int
rl_vi_append_eol (count, key)rl_vi_append_eol (int count, int key)
     int count, key; 
 {  {
   rl_end_of_line (1, key);    rl_end_of_line (1, key);
   rl_vi_append_mode (1, key);    rl_vi_append_mode (1, key);
Line 690  rl_vi_append_eol (count, key) Line 783  rl_vi_append_eol (count, key)
   
 /* What to do in the case of C-d. */  /* What to do in the case of C-d. */
 int  int
rl_vi_eof_maybe (count, c)rl_vi_eof_maybe (int count, int c)
     int count, c; 
 {  {
   return (rl_newline (1, '\n'));    return (rl_newline (1, '\n'));
 }  }
Line 701  rl_vi_eof_maybe (count, c) Line 793  rl_vi_eof_maybe (count, c)
 /* Switching from one mode to the other really just involves  /* Switching from one mode to the other really just involves
    switching keymaps. */     switching keymaps. */
 int  int
rl_vi_insertion_mode (count, key)rl_vi_insertion_mode (int count, int key)
     int count, key; 
 {  {
   _rl_keymap = vi_insertion_keymap;    _rl_keymap = vi_insertion_keymap;
   _rl_vi_last_key_before_insert = key;    _rl_vi_last_key_before_insert = key;
Line 712  rl_vi_insertion_mode (count, key) Line 803  rl_vi_insertion_mode (count, key)
 }  }
   
 int  int
rl_vi_insert_mode (count, key)rl_vi_insert_mode (int count, int key)
     int count, key; 
 {  {
   rl_vi_start_inserting (key, 1, rl_arg_sign);    rl_vi_start_inserting (key, 1, rl_arg_sign);
   return (0);    return (0);
 }  }
   
 static void  static void
vi_save_insert_buffer (start, len)vi_save_insert_buffer (int start, int len)
     int start, len; 
 {  {
   /* Same code as _rl_vi_save_insert below */    /* Same code as _rl_vi_save_insert below */
   if (len >= vi_insert_buffer_size)    if (len >= vi_insert_buffer_size)
Line 734  vi_save_insert_buffer (start, len) Line 823  vi_save_insert_buffer (start, len)
 }  }
   
 static void  static void
_rl_vi_save_replace ()_rl_vi_save_replace (void)
 {  {
   int len, start, end;    int len, start, end;
   UNDO_LIST *up;    UNDO_LIST *up;
Line 753  _rl_vi_save_replace () Line 842  _rl_vi_save_replace ()
   start = end - vi_replace_count + 1;    start = end - vi_replace_count + 1;
   len = vi_replace_count + 1;    len = vi_replace_count + 1;
   
     if (start < 0)
       {
         len = end + 1;
         start = 0;
       }
   
   vi_save_insert_buffer (start, len);      vi_save_insert_buffer (start, len);  
 }  }
   
 static void  static void
_rl_vi_save_insert (up)_rl_vi_save_insert (UNDO_LIST *up)
      UNDO_LIST *up; 
 {  {
   int len, start, end;    int len, start, end;
   
Line 777  _rl_vi_save_insert (up) Line 871  _rl_vi_save_insert (up)
 }  }
           
 void  void
_rl_vi_done_inserting ()_rl_vi_done_inserting (void)
 {  {
   if (_rl_vi_doing_insert)    if (_rl_vi_doing_insert)
     {      {
      /* The `C', `s', and `S' commands set this. */      /* The `c', `s', `S', and `R' commands set this. */
      rl_end_undo_group ();      rl_end_undo_group ();     /* for the group in rl_vi_start_inserting */
       /* Now, the text between rl_undo_list->next->start and        /* Now, the text between rl_undo_list->next->start and
          rl_undo_list->next->end is what was inserted while in insert           rl_undo_list->next->end is what was inserted while in insert
          mode.  It gets copied to VI_INSERT_BUFFER because it depends           mode.  It gets copied to VI_INSERT_BUFFER because it depends
Line 793  _rl_vi_done_inserting () Line 887  _rl_vi_done_inserting ()
         _rl_vi_save_replace ();         /* Half the battle */          _rl_vi_save_replace ();         /* Half the battle */
       else        else
         _rl_vi_save_insert (rl_undo_list->next);          _rl_vi_save_insert (rl_undo_list->next);
      vi_continued_command = 1;      /* sanity check, should always be >= 1 here */
       if (_rl_undo_group_level > 0)
         rl_end_undo_group ();   /* for the group in the command (change or replace) */
     }      }
   else    else
     {      {
Line 805  _rl_vi_done_inserting () Line 901  _rl_vi_done_inserting ()
       /* XXX - Other keys probably need to be checked. */        /* XXX - Other keys probably need to be checked. */
       else if (_rl_vi_last_key_before_insert == 'C')        else if (_rl_vi_last_key_before_insert == 'C')
         rl_end_undo_group ();          rl_end_undo_group ();
       while (_rl_undo_group_level > 0)  
         rl_end_undo_group ();  
       vi_continued_command = 0;  
     }      }
   
     /* Sanity check, make sure all the undo groups are closed before we leave
        insert mode */
     while (_rl_undo_group_level > 0)
       rl_end_undo_group ();
 }  }
   
 int  int
rl_vi_movement_mode (count, key)rl_vi_movement_mode (int count, int key)
     int count, key; 
 {  {
   if (rl_point > 0)    if (rl_point > 0)
     rl_backward_char (1, key);      rl_backward_char (1, key);
Line 834  rl_vi_movement_mode (count, key) Line 931  rl_vi_movement_mode (count, key)
 }  }
   
 int  int
rl_vi_arg_digit (count, c)rl_vi_arg_digit (int count, int c)
     int count, c; 
 {  {
   if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)    if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
     return (rl_beg_of_line (1, c));      return (rl_beg_of_line (1, c));
Line 846  rl_vi_arg_digit (count, c) Line 942  rl_vi_arg_digit (count, c)
 /* Change the case of the next COUNT characters. */  /* Change the case of the next COUNT characters. */
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
 static int  static int
_rl_vi_change_mbchar_case (count)_rl_vi_change_mbchar_case (int count)
     int count; 
 {  {
   wchar_t wc;    wchar_t wc;
   char mb[MB_LEN_MAX+1];    char mb[MB_LEN_MAX+1];
Line 886  _rl_vi_change_mbchar_case (count) Line 981  _rl_vi_change_mbchar_case (count)
           rl_begin_undo_group ();            rl_begin_undo_group ();
           rl_vi_delete (1, 0);            rl_vi_delete (1, 0);
           if (rl_point < p)     /* Did we retreat at EOL? */            if (rl_point < p)     /* Did we retreat at EOL? */
            rl_point++; /* XXX - should we advance more than 1 for mbchar? */            _rl_vi_advance_point ();
           rl_insert_text (mb);            rl_insert_text (mb);
           rl_end_undo_group ();            rl_end_undo_group ();
           rl_vi_check ();            rl_vi_check ();
Line 900  _rl_vi_change_mbchar_case (count) Line 995  _rl_vi_change_mbchar_case (count)
 #endif  #endif
   
 int  int
rl_vi_change_case (count, ignore)rl_vi_change_case (int count, int ignore)
     int count, ignore; 
 {  {
   int c, p;    int c, p;
   
Line 947  rl_vi_change_case (count, ignore) Line 1041  rl_vi_change_case (count, ignore)
 }  }
   
 int  int
rl_vi_put (count, key)rl_vi_put (int count, int key)
     int count, key; 
 {  {
   if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))    if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
     rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);      rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
Line 960  rl_vi_put (count, key) Line 1053  rl_vi_put (count, key)
   return (0);    return (0);
 }  }
   
static void/* Move the cursor back one character if you're at the end of the line */
_rl_vi_backup () 
{ 
  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 
    rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 
  else 
    rl_point--; 
} 
 
 int  int
rl_vi_check ()rl_vi_check (void)
 {  {
   if (rl_point && rl_point == rl_end)    if (rl_point && rl_point == rl_end)
    {    _rl_vi_backup ();
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 
        rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 
      else 
        rl_point--; 
    } 
   return (0);    return (0);
 }  }
   
   /* Move to the character position specified by COUNT */
 int  int
rl_vi_column (count, key)rl_vi_column (int count, int key)
     int count, key; 
 {  {
   if (count > rl_end)    if (count > rl_end)
     rl_end_of_line (1, key);      rl_end_of_line (1, key);
   else    else
    rl_point = count - 1;    {
       rl_point = 0;
       rl_point = _rl_forward_char_internal (count - 1);
     }
   return (0);    return (0);
 }  }
   
Line 997  rl_vi_column (count, key) Line 1080  rl_vi_column (count, key)
    argument should be aborted, 0 if we should not read any more chars, and     argument should be aborted, 0 if we should not read any more chars, and
    1 if we should continue to read chars. */     1 if we should continue to read chars. */
 static int  static int
_rl_vi_arg_dispatch (c)_rl_vi_arg_dispatch (int c)
     int c; 
 {  {
   int key;    int key;
   
Line 1032  _rl_vi_arg_dispatch (c) Line 1114  _rl_vi_arg_dispatch (c)
    Don't recognize minus sign?     Don't recognize minus sign?
    Should this do rl_save_prompt/rl_restore_prompt? */     Should this do rl_save_prompt/rl_restore_prompt? */
 static int  static int
rl_digit_loop1 ()rl_digit_loop1 (void)
 {  {
   int c, r;    int c, r;
   
Line 1052  rl_digit_loop1 () Line 1134  rl_digit_loop1 ()
   return (0);    return (0);
 }  }
   
   /* This set of functions is basically to handle the commands that take a
      motion argument while in callback mode: read the command, read the motion
      command modifier, find the extent of the text to affect, and dispatch the
      command for execution. */
 static void  static void
_rl_mvcxt_init (m, op, key)_rl_mvcxt_init (_rl_vimotion_cxt *m, int op, int key)
     _rl_vimotion_cxt *m; 
     int op, key; 
 {  {
   m->op = op;    m->op = op;
   m->state = m->flags = 0;    m->state = m->flags = 0;
Line 1068  _rl_mvcxt_init (m, op, key) Line 1152  _rl_mvcxt_init (m, op, key)
 }  }
   
 static _rl_vimotion_cxt *  static _rl_vimotion_cxt *
_rl_mvcxt_alloc (op, key)_rl_mvcxt_alloc (int op, int key)
     int op, key; 
 {  {
   _rl_vimotion_cxt *m;    _rl_vimotion_cxt *m;
   
Line 1079  _rl_mvcxt_alloc (op, key) Line 1162  _rl_mvcxt_alloc (op, key)
 }  }
   
 static void  static void
_rl_mvcxt_dispose (m)_rl_mvcxt_dispose (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   xfree (m);    xfree (m);
 }  }
   
 static int  static int
rl_domove_motion_callback (m)rl_domove_motion_callback (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
  int c, save, r;  int c;
  int old_end; 
   
   _rl_vi_last_motion = c = m->motion;    _rl_vi_last_motion = c = m->motion;
   
   /* Append a blank character temporarily so that the motion routines    /* Append a blank character temporarily so that the motion routines
     work right at the end of the line. */     work right at the end of the line.  Original value of rl_end is saved
  old_end = rl_end;     as m->end. */
   rl_extend_line_buffer (rl_end + 1);
   rl_line_buffer[rl_end++] = ' ';    rl_line_buffer[rl_end++] = ' ';
   rl_line_buffer[rl_end] = '\0';    rl_line_buffer[rl_end] = '\0';
   
   _rl_dispatch (c, _rl_keymap);    _rl_dispatch (c, _rl_keymap);
   
  /* Remove the blank that we added. */#if defined (READLINE_CALLBACKS)
  rl_end = old_end;  if (RL_ISSTATE (RL_STATE_CALLBACK))
     {
       /* Messy case where char search can be vi motion command; see rest of
          details in callback.c.  vi_char_search and callback_char_search just
          set and unset the CHARSEARCH state.  This is where any vi motion
          command that needs to set its own state should be handled, with any
          corresponding code to manage that state in callback.c */
       if (RL_ISSTATE (RL_STATE_CHARSEARCH))
         return 0;
       else
         return (_rl_vi_domove_motion_cleanup (c, m));
     }
 #endif
 
   return (_rl_vi_domove_motion_cleanup (c, m));
 }
 
 int
 _rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m)
 {
   int r;
 
   /* Remove the blank that we added in rl_domove_motion_callback. */
   rl_end = m->end;
   rl_line_buffer[rl_end] = '\0';    rl_line_buffer[rl_end] = '\0';
  if (rl_point > rl_end)  _rl_fix_point (0);
    rl_point = rl_end; 
   
   /* No change in position means the command failed. */    /* No change in position means the command failed. */
   if (rl_mark == rl_point)    if (rl_mark == rl_point)
    return (-1);    {
       /* 'c' and 'C' enter insert mode after the delete even if the motion
          didn't delete anything, as long as the motion command is valid. */
       if (_rl_to_upper (m->key) == 'C' && _rl_vi_motion_command (c))
         return (vidomove_dispatch (m));
       RL_UNSETSTATE (RL_STATE_VIMOTION);
       return (-1);
     }
   
   /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next    /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
      word.  If we are not at the end of the line, and we are on a       word.  If we are not at the end of the line, and we are on a
      non-whitespace character, move back one (presumably to whitespace). */       non-whitespace character, move back one (presumably to whitespace). */
   if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&    if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
       !whitespace (rl_line_buffer[rl_point]))        !whitespace (rl_line_buffer[rl_point]))
    rl_point--;    rl_point--;         /* XXX */
   
   /* If cw or cW, back up to the end of a word, so the behaviour of ce    /* If cw or cW, back up to the end of a word, so the behaviour of ce
      or cE is the actual result.  Brute-force, no subtlety. */       or cE is the actual result.  Brute-force, no subtlety. */
Line 1130  rl_domove_motion_callback (m) Line 1240  rl_domove_motion_callback (m)
       /* Posix.2 says that if cw or cW moves the cursor towards the end of        /* Posix.2 says that if cw or cW moves the cursor towards the end of
          the line, the character under the cursor should be deleted. */           the line, the character under the cursor should be deleted. */
       if (rl_point == rl_mark)        if (rl_point == rl_mark)
        rl_point++;        _rl_vi_advance_point ();
       else        else
         {          {
           /* Move past the end of the word so that the kill doesn't            /* Move past the end of the word so that the kill doesn't
              remove the last letter of the previous word.  Only do this               remove the last letter of the previous word.  Only do this
              if we are not at the end of the line. */               if we are not at the end of the line. */
           if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))            if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
            rl_point++;            _rl_vi_advance_point ();
         }          }
     }      }
   
Line 1157  rl_domove_motion_callback (m) Line 1267  rl_domove_motion_callback (m)
 #define RL_VIMOVENUMARG()       (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))  #define RL_VIMOVENUMARG()       (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
   
 static int  static int
rl_domove_read_callback (m)rl_domove_read_callback (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   int c, save;    int c, save;
   
Line 1224  rl_domove_read_callback (m) Line 1333  rl_domove_read_callback (m)
 }  }
   
 static int  static int
rl_vi_domove_getchar (m)rl_vi_domove_getchar (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
  int c;  return (_rl_bracketed_read_key ());
 
  RL_SETSTATE(RL_STATE_MOREINPUT); 
  c = rl_read_key (); 
  RL_UNSETSTATE(RL_STATE_MOREINPUT); 
 
  return c; 
 }  }
   
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
 int  int
_rl_vi_domove_callback (m)_rl_vi_domove_callback (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   int c, r;    int c, r;
   
   m->motion = c = rl_vi_domove_getchar (m);    m->motion = c = rl_vi_domove_getchar (m);
  /* XXX - what to do if this returns -1?  Should we return 1 for eof to  if (c < 0)
     callback code? */    return 1;               /* EOF */
   r = rl_domove_read_callback (m);    r = rl_domove_read_callback (m);
   
   return ((r == 0) ? r : 1);    /* normalize return values */    return ((r == 0) ? r : 1);    /* normalize return values */
 }  }
 #endif  #endif
   
/* This code path taken when not in callback mode. *//* This code path is taken when not in callback mode. */
 int  int
rl_vi_domove (x, ignore)rl_vi_domove (int x, int *ignore)
     int x, *ignore; 
 {  {
   int r;    int r;
   _rl_vimotion_cxt *m;    _rl_vimotion_cxt *m;
Line 1273  rl_vi_domove (x, ignore) Line 1373  rl_vi_domove (x, ignore)
 }  }
   
 static int  static int
vi_delete_dispatch (m)vi_delete_dispatch (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   /* These are the motion commands that do not require adjusting the    /* These are the motion commands that do not require adjusting the
      mark. */       mark. */
   if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&    if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
       (rl_mark < rl_end))        (rl_mark < rl_end))
    rl_mark++;    INCREMENT_POS (rl_mark);
   
   rl_kill_text (rl_point, rl_mark);    rl_kill_text (rl_point, rl_mark);
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_delete_to (count, key)rl_vi_delete_to (int count, int key)
     int count, key; 
 {  {
   int c, r;    int c, r;
   
  _rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);  if (_rl_vimvcxt)
     _rl_mvcxt_init (_rl_vimvcxt, VIM_DELETE, key);
   else
     _rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
 
   _rl_vimvcxt->start = rl_point;    _rl_vimvcxt->start = rl_point;
   
   rl_mark = rl_point;    rl_mark = rl_point;
Line 1301  rl_vi_delete_to (count, key) Line 1403  rl_vi_delete_to (count, key)
       _rl_vimvcxt->motion = '$';        _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing && _rl_vi_last_motion != 'd')        /* `dd' is special */  else if (_rl_vi_redoing && _rl_vi_last_motion != 'd')        /* `dd' is special */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing)             /* handle redoing `dd' here */  else if (_rl_vi_redoing)             /* handle redoing `dd' here */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       rl_mark = rl_end;        rl_mark = rl_end;
Line 1337  rl_vi_delete_to (count, key) Line 1439  rl_vi_delete_to (count, key)
 }  }
   
 static int  static int
vi_change_dispatch (m)vi_change_dispatch (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   /* These are the motion commands that do not require adjusting the    /* These are the motion commands that do not require adjusting the
      mark.  c[wW] are handled by special-case code in rl_vi_domove(),       mark.  c[wW] are handled by special-case code in rl_vi_domove(),
      and already leave the mark at the correct location. */       and already leave the mark at the correct location. */
   if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&    if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
       (rl_mark < rl_end))        (rl_mark < rl_end))
    rl_mark++;    INCREMENT_POS (rl_mark);
   
   /* The cursor never moves with c[wW]. */    /* The cursor never moves with c[wW]. */
   if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)    if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
     rl_point = m->start;      rl_point = m->start;
   
  if (vi_redoing)  if (_rl_vi_redoing)
     {      {
       if (vi_insert_buffer && *vi_insert_buffer)        if (vi_insert_buffer && *vi_insert_buffer)
         rl_begin_undo_group ();          rl_begin_undo_group ();
Line 1377  vi_change_dispatch (m) Line 1478  vi_change_dispatch (m)
 }  }
   
 int  int
rl_vi_change_to (count, key)rl_vi_change_to (int count, int key)
     int count, key; 
 {  {
   int c, r;    int c, r;
   
  _rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);  if (_rl_vimvcxt)
     _rl_mvcxt_init (_rl_vimvcxt, VIM_CHANGE, key);
   else
     _rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
   _rl_vimvcxt->start = rl_point;    _rl_vimvcxt->start = rl_point;
   
   rl_mark = rl_point;    rl_mark = rl_point;
Line 1391  rl_vi_change_to (count, key) Line 1494  rl_vi_change_to (count, key)
       _rl_vimvcxt->motion = '$';        _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing && _rl_vi_last_motion != 'c')        /* `cc' is special */  else if (_rl_vi_redoing && _rl_vi_last_motion != 'c')        /* `cc' is special */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing)             /* handle redoing `cc' here */  else if (_rl_vi_redoing)             /* handle redoing `cc' here */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       rl_mark = rl_end;        rl_mark = rl_end;
Line 1427  rl_vi_change_to (count, key) Line 1530  rl_vi_change_to (count, key)
 }  }
   
 static int  static int
vi_yank_dispatch (m)vi_yank_dispatch (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   /* These are the motion commands that do not require adjusting the    /* These are the motion commands that do not require adjusting the
      mark. */       mark. */
   if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&    if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
       (rl_mark < rl_end))        (rl_mark < rl_end))
    rl_mark++;    INCREMENT_POS (rl_mark);
   
   rl_begin_undo_group ();    rl_begin_undo_group ();
   rl_kill_text (rl_point, rl_mark);    rl_kill_text (rl_point, rl_mark);
Line 1442  vi_yank_dispatch (m) Line 1544  vi_yank_dispatch (m)
   rl_do_undo ();    rl_do_undo ();
   rl_point = m->start;    rl_point = m->start;
   
     _rl_fix_point (1);
   
   return (0);    return (0);
 }  }
   
 int  int
rl_vi_yank_to (count, key)rl_vi_yank_to (int count, int key)
     int count, key; 
 {  {
   int c, r;    int c, r;
   
  _rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);  if (_rl_vimvcxt)
     _rl_mvcxt_init (_rl_vimvcxt, VIM_YANK, key);
   else
     _rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
   _rl_vimvcxt->start = rl_point;    _rl_vimvcxt->start = rl_point;
   
   rl_mark = rl_point;    rl_mark = rl_point;
Line 1460  rl_vi_yank_to (count, key) Line 1566  rl_vi_yank_to (count, key)
       _rl_vimvcxt->motion = '$';        _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing && _rl_vi_last_motion != 'y')        /* `yy' is special */  else if (_rl_vi_redoing && _rl_vi_last_motion != 'y')        /* `yy' is special */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       r = rl_domove_motion_callback (_rl_vimvcxt);        r = rl_domove_motion_callback (_rl_vimvcxt);
     }      }
  else if (vi_redoing)                     /* handle redoing `yy' here */  else if (_rl_vi_redoing)                     /* handle redoing `yy' here */
     {      {
       _rl_vimvcxt->motion = _rl_vi_last_motion;        _rl_vimvcxt->motion = _rl_vi_last_motion;
       rl_mark = rl_end;        rl_mark = rl_end;
Line 1496  rl_vi_yank_to (count, key) Line 1602  rl_vi_yank_to (count, key)
 }  }
   
 static int  static int
vidomove_dispatch (m)vidomove_dispatch (_rl_vimotion_cxt *m)
     _rl_vimotion_cxt *m; 
 {  {
   int r;    int r;
   
Line 1523  vidomove_dispatch (m) Line 1628  vidomove_dispatch (m)
 }  }
   
 int  int
rl_vi_rubout (count, key)rl_vi_rubout (int count, int key)
     int count, key; 
 {  {
   int opoint;    int opoint;
   
Line 1534  rl_vi_rubout (count, key) Line 1638  rl_vi_rubout (count, key)
   if (rl_point == 0)    if (rl_point == 0)
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   
   opoint = rl_point;    opoint = rl_point;
Line 1554  rl_vi_rubout (count, key) Line 1658  rl_vi_rubout (count, key)
 }  }
   
 int  int
rl_vi_delete (count, key)rl_vi_delete (int count, int key)
     int count, key; 
 {  {
   int end;    int end;
   
Line 1565  rl_vi_delete (count, key) Line 1668  rl_vi_delete (count, key)
   if (rl_end == 0)    if (rl_end == 0)
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   
   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Line 1584  rl_vi_delete (count, key) Line 1687  rl_vi_delete (count, key)
   return (0);    return (0);
 }  }
   
   /* This does what Posix specifies vi-mode C-w to do: using whitespace and
      punctuation characters as the word boundaries. */
   
   #define vi_unix_word_boundary(c)        (whitespace(c) || ispunct(c))
   
 int  int
rl_vi_back_to_indent (count, key)rl_vi_unix_word_rubout (int count, int key)
     int count, key; 
 {  {
     int orig_point;
   
     if (rl_point == 0)
       rl_ding ();
     else
       {
         orig_point = rl_point;
         if (count <= 0)
           count = 1;
   
         while (count--)
           {
             /* This isn't quite what ksh93 does but it seems to match what the
                Posix description of sh specifies, with a few accommodations
                for sequences of whitespace characters between words and at
                the end of the line. */
   
             /* Skip over whitespace at the end of the line as a special case */
             if (rl_point > 0 && (rl_line_buffer[rl_point] == 0) &&
                   whitespace (rl_line_buffer[rl_point - 1]))
               while (--rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
                 ;
   
             /* If we're at the start of a word, move back to word boundary so we
                move back to the `preceding' word */
             if (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) &&
                   vi_unix_word_boundary (rl_line_buffer[rl_point - 1]))
               rl_point--;
   
             /* If we are at a word boundary (whitespace/punct), move backward
                past a sequence of word boundary characters.  If we are at the
                end of a word (non-word boundary), move back to a word boundary */
             if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]))
               while (rl_point && vi_unix_word_boundary (rl_line_buffer[rl_point - 1]))
                 rl_point--;
             else if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0)
               while (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0))
                 _rl_vi_backup_point ();
           }
   
         rl_kill_text (orig_point, rl_point);
       }
   
     return 0;
   }
   
   
   int
   rl_vi_back_to_indent (int count, int key)
   {
   rl_beg_of_line (1, key);    rl_beg_of_line (1, key);
   while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))    while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
     rl_point++;      rl_point++;
Line 1595  rl_vi_back_to_indent (count, key) Line 1752  rl_vi_back_to_indent (count, key)
 }  }
   
 int  int
rl_vi_first_print (count, key)rl_vi_first_print (int count, int key)
     int count, key; 
 {  {
   return (rl_vi_back_to_indent (1, key));    return (rl_vi_back_to_indent (1, key));
 }  }
Line 1605  static int _rl_cs_dir, _rl_cs_orig_dir; Line 1761  static int _rl_cs_dir, _rl_cs_orig_dir;
   
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
 static int  static int
_rl_vi_callback_char_search (data)_rl_vi_callback_char_search (_rl_callback_generic_arg *data)
     _rl_callback_generic_arg *data; 
 {  {
   int c;    int c;
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
Line 1618  _rl_vi_callback_char_search (data) Line 1773  _rl_vi_callback_char_search (data)
 #endif  #endif
   
   if (c <= 0)    if (c <= 0)
    return -1;    {
       RL_UNSETSTATE (RL_STATE_CHARSEARCH);
       return -1;
     }
   
 #if !defined (HANDLE_MULTIBYTE)  #if !defined (HANDLE_MULTIBYTE)
   _rl_vi_last_search_char = c;    _rl_vi_last_search_char = c;
Line 1626  _rl_vi_callback_char_search (data) Line 1784  _rl_vi_callback_char_search (data)
   
   _rl_callback_func = 0;    _rl_callback_func = 0;
   _rl_want_redisplay = 1;    _rl_want_redisplay = 1;
     RL_UNSETSTATE (RL_STATE_CHARSEARCH);
   
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
   return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));    return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
Line 1636  _rl_vi_callback_char_search (data) Line 1795  _rl_vi_callback_char_search (data)
 #endif  #endif
   
 int  int
rl_vi_char_search (count, key)rl_vi_char_search (int count, int key)
     int count, key; 
 {  {
   int c;    int c;
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
Line 1650  rl_vi_char_search (count, key) Line 1808  rl_vi_char_search (count, key)
   if (key == ';' || key == ',')    if (key == ';' || key == ',')
     {      {
       if (_rl_cs_orig_dir == 0)        if (_rl_cs_orig_dir == 0)
        return -1;        return 1;
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
       if (_rl_vi_last_search_mblen == 0)        if (_rl_vi_last_search_mblen == 0)
        return -1;        return 1;
 #else  #else
       if (_rl_vi_last_search_char == 0)        if (_rl_vi_last_search_char == 0)
        return -1;        return 1;
 #endif  #endif
       _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;        _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
     }      }
Line 1681  rl_vi_char_search (count, key) Line 1839  rl_vi_char_search (count, key)
           break;            break;
         }          }
   
      if (vi_redoing)      if (_rl_vi_redoing)
         {          {
           /* set target and tlen below */            /* set target and tlen below */
         }          }
Line 1690  rl_vi_char_search (count, key) Line 1848  rl_vi_char_search (count, key)
         {          {
           _rl_callback_data = _rl_callback_data_alloc (count);            _rl_callback_data = _rl_callback_data_alloc (count);
           _rl_callback_data->i1 = _rl_cs_dir;            _rl_callback_data->i1 = _rl_cs_dir;
             _rl_callback_data->i2 = key;
           _rl_callback_func = _rl_vi_callback_char_search;            _rl_callback_func = _rl_vi_callback_char_search;
             RL_SETSTATE (RL_STATE_CHARSEARCH);
           return (0);            return (0);
         }          }
 #endif  #endif
Line 1728  rl_vi_char_search (count, key) Line 1888  rl_vi_char_search (count, key)
   
 /* Match brackets */  /* Match brackets */
 int  int
rl_vi_match (ignore, key)rl_vi_match (int ignore, int key)
     int ignore, key; 
 {  {
   int count = 1, brack, pos, tmp, pre;    int count = 1, brack, pos, tmp, pre;
   
Line 1755  rl_vi_match (ignore, key) Line 1914  rl_vi_match (ignore, key)
         {          {
           rl_point = pos;            rl_point = pos;
           rl_ding ();            rl_ding ();
          return -1;          return 1;
         }          }
     }      }
   
Line 1785  rl_vi_match (ignore, key) Line 1944  rl_vi_match (ignore, key)
           else            else
             {              {
               rl_ding ();                rl_ding ();
              return -1;              return 1;
             }              }
         }          }
     }      }
Line 1809  rl_vi_match (ignore, key) Line 1968  rl_vi_match (ignore, key)
           else            else
             {              {
               rl_ding ();                rl_ding ();
              return -1;              return 1;
             }              }
         }          }
     }      }
Line 1818  rl_vi_match (ignore, key) Line 1977  rl_vi_match (ignore, key)
 }  }
   
 int  int
rl_vi_bracktype (c)rl_vi_bracktype (int c)
     int c; 
 {  {
   switch (c)    switch (c)
     {      {
Line 1834  rl_vi_bracktype (c) Line 1992  rl_vi_bracktype (c)
 }  }
   
 static int  static int
_rl_vi_change_char (count, c, mb)_rl_vi_change_char (int count, int c, char *mb)
     int count, c; 
     char *mb; 
 {  {
   int p;    int p;
   
Line 1849  _rl_vi_change_char (count, c, mb) Line 2005  _rl_vi_change_char (count, c, mb)
       p = rl_point;        p = rl_point;
       rl_vi_delete (1, c);        rl_vi_delete (1, c);
       if (rl_point < p)         /* Did we retreat at EOL? */        if (rl_point < p)         /* Did we retreat at EOL? */
        rl_point++;        _rl_vi_append_forward (c);
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)        if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
         rl_insert_text (mb);          rl_insert_text (mb);
Line 1867  _rl_vi_change_char (count, c, mb) Line 2023  _rl_vi_change_char (count, c, mb)
 }  }
   
 static int  static int
_rl_vi_callback_getchar (mb, mlen)_rl_vi_callback_getchar (char *mb, int mlen)
     char *mb; 
     int mlen; 
 {  {
  int c;  return (_rl_bracketed_read_mbstring (mb, mlen));
 
  RL_SETSTATE(RL_STATE_MOREINPUT); 
  c = rl_read_key (); 
  RL_UNSETSTATE(RL_STATE_MOREINPUT); 
 
  if (c < 0) 
    return -1; 
 
#if defined (HANDLE_MULTIBYTE) 
  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 
    c = _rl_read_mbstring (c, mb, mlen); 
#endif 
 
  return c; 
 }  }
   
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
 static int  static int
_rl_vi_callback_change_char (data)_rl_vi_callback_change_char (_rl_callback_generic_arg *data)
     _rl_callback_generic_arg *data; 
 {  {
   int c;    int c;
  char mb[MB_LEN_MAX];  char mb[MB_LEN_MAX+1];
   
  _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);  c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
 #if defined (HANDLE_MULTIBYTE)
   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
   else
 #endif
     _rl_vi_last_replacement[0] = c;
   _rl_vi_last_replacement[MB_LEN_MAX] = '\0';   /* XXX */
   
   if (c < 0)    if (c < 0)
     return -1;      return -1;
Line 1909  _rl_vi_callback_change_char (data) Line 2055  _rl_vi_callback_change_char (data)
 #endif  #endif
   
 int  int
rl_vi_change_char (count, key)rl_vi_change_char (int count, int key)
     int count, key; 
 {  {
   int c;    int c;
  char mb[MB_LEN_MAX];  char mb[MB_LEN_MAX+1];
   
  if (vi_redoing)  if (_rl_vi_redoing)
     {      {
      c = _rl_vi_last_replacement;      strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX);
      mb[0] = c;      c = (unsigned char)_rl_vi_last_replacement[0];    /* XXX */
      mb[1] = '\0';      mb[MB_LEN_MAX] = '\0';
     }      }
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
   else if (RL_ISSTATE (RL_STATE_CALLBACK))    else if (RL_ISSTATE (RL_STATE_CALLBACK))
Line 1930  rl_vi_change_char (count, key) Line 2075  rl_vi_change_char (count, key)
     }      }
 #endif  #endif
   else    else
    _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);    {
       c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
 #ifdef HANDLE_MULTIBYTE
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
         strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
       else
 #endif
         _rl_vi_last_replacement[0] = c;
       _rl_vi_last_replacement[MB_LEN_MAX] = '\0';       /* just in case */      
     }
   
   if (c < 0)    if (c < 0)
     return -1;      return -1;
Line 1939  rl_vi_change_char (count, key) Line 2093  rl_vi_change_char (count, key)
 }  }
   
 int  int
rl_vi_subst (count, key)rl_vi_subst (int count, int key)
     int count, key; 
 {  {
   /* If we are redoing, rl_vi_change_to will stuff the last motion char */    /* If we are redoing, rl_vi_change_to will stuff the last motion char */
  if (vi_redoing == 0)  if (_rl_vi_redoing == 0)
     rl_stuff_char ((key == 'S') ? 'c' : 'l');   /* `S' == `cc', `s' == `cl' */      rl_stuff_char ((key == 'S') ? 'c' : 'l');   /* `S' == `cc', `s' == `cl' */
   
   return (rl_vi_change_to (count, 'c'));    return (rl_vi_change_to (count, 'c'));
 }  }
   
 int  int
rl_vi_overstrike (count, key)rl_vi_overstrike (int count, int key)
     int count, key; 
 {  {
   if (_rl_vi_doing_insert == 0)    if (_rl_vi_doing_insert == 0)
     {      {
Line 1969  rl_vi_overstrike (count, key) Line 2121  rl_vi_overstrike (count, key)
 }  }
   
 int  int
rl_vi_overstrike_delete (count, key)rl_vi_overstrike_delete (int count, int key)
     int count, key; 
 {  {
   int i, s;    int i, s;
   
Line 1984  rl_vi_overstrike_delete (count, key) Line 2135  rl_vi_overstrike_delete (count, key)
       s = rl_point;        s = rl_point;
   
       if (rl_do_undo ())        if (rl_do_undo ())
        vi_replace_count--;        vi_replace_count--;             /* XXX */
   
       if (rl_point == s)        if (rl_point == s)
         rl_backward_char (1, key);          rl_backward_char (1, key);
Line 1999  rl_vi_overstrike_delete (count, key) Line 2150  rl_vi_overstrike_delete (count, key)
   return (0);    return (0);
 }  }
   
   static int
   rl_vi_overstrike_kill_line (int count, int key)
   {
     int r, end;
   
     end = rl_end;
     r = rl_unix_line_discard (count, key);
     vi_replace_count -= end - rl_end;
     return r;
   }
   
   static int
   rl_vi_overstrike_kill_word (int count, int key)
   {
     int r, end;
   
     end = rl_end;
     r = rl_vi_unix_word_rubout (count, key);
     vi_replace_count -= end - rl_end;
     return r;
   }
   
   static int
   rl_vi_overstrike_yank (int count, int key)
   {
     int r, end;
   
     end = rl_end;
     r = rl_yank (count, key);
     vi_replace_count += rl_end - end;
     return r;
   }
   
   /* Read bracketed paste mode pasted text and insert it in overwrite mode */
   static int
   rl_vi_overstrike_bracketed_paste (int count, int key)
   {
     int r;
     char *pbuf;
     size_t pblen;
   
     pbuf = _rl_bracketed_text (&pblen);
     if (pblen == 0)
       {
         xfree (pbuf);
         return 0;
       }
     r = pblen;
     while (--r >= 0)
       _rl_unget_char ((unsigned char)pbuf[r]);
     xfree (pbuf);
   
     while (_rl_pushed_input_available ())
       {
         key = rl_read_key ();
         r = rl_vi_overstrike (1, key);
       }
   
     return r;
   }
   
 int  int
rl_vi_replace (count, key)rl_vi_replace (int count, int key)
     int count, key; 
 {  {
   int i;    int i;
   
Line 2032  rl_vi_replace (count, key) Line 2243  rl_vi_replace (count, key)
           vi_insertion_keymap[CTRL ('H')].function == rl_rubout)            vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
         vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;          vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
   
         /* Same for ^U and unix-line-discard. */
         if (vi_insertion_keymap[CTRL ('U')].type == ISFUNC &&
             vi_insertion_keymap[CTRL ('U')].function == rl_unix_line_discard)
           vi_replace_map[CTRL ('U')].function = rl_vi_overstrike_kill_line;
   
         /* And for ^W and unix-word-rubout. */
         if (vi_insertion_keymap[CTRL ('W')].type == ISFUNC &&
             vi_insertion_keymap[CTRL ('W')].function == rl_vi_unix_word_rubout)
           vi_replace_map[CTRL ('W')].function = rl_vi_overstrike_kill_word;
   
         /* And finally for ^Y and yank. */
         if (vi_insertion_keymap[CTRL ('Y')].type == ISFUNC &&
             vi_insertion_keymap[CTRL ('Y')].function == rl_yank)
           vi_replace_map[CTRL ('Y')].function = rl_vi_overstrike_yank;
   
         /* Make sure this is the value we need. */
         vi_replace_map[ANYOTHERKEY].type = ISFUNC;
         vi_replace_map[ANYOTHERKEY].function = (rl_command_func_t *)NULL;
     }      }
   
   rl_vi_start_inserting (key, 1, rl_arg_sign);    rl_vi_start_inserting (key, 1, rl_arg_sign);
   
  _rl_vi_last_key_before_insert = key;  _rl_vi_last_key_before_insert = 'R';    /* in case someone rebinds it */
   _rl_keymap = vi_replace_map;    _rl_keymap = vi_replace_map;
   
     if (_rl_enable_bracketed_paste)
       rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_vi_overstrike_bracketed_paste);
   
   return (0);    return (0);
 }  }
   
Line 2047  rl_vi_replace (count, key) Line 2279  rl_vi_replace (count, key)
    the previous character.  A space matches everything.  Word delimiters are     the previous character.  A space matches everything.  Word delimiters are
    space and ;. */     space and ;. */
 int  int
rl_vi_possible_completions()rl_vi_possible_completions (void)
 {  {
   int save_pos = rl_point;    int save_pos = rl_point;
   
Line 2055  rl_vi_possible_completions() Line 2287  rl_vi_possible_completions()
     {      {
       while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&        while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
              rl_line_buffer[rl_point] != ';')               rl_line_buffer[rl_point] != ';')
        rl_point++;        _rl_vi_advance_point ();
     }      }
   else if (rl_line_buffer[rl_point - 1] == ';')    else if (rl_line_buffer[rl_point - 1] == ';')
     {      {
Line 2072  rl_vi_possible_completions() Line 2304  rl_vi_possible_completions()
   
 /* Functions to save and restore marks. */  /* Functions to save and restore marks. */
 static int  static int
_rl_vi_set_mark ()_rl_vi_set_mark (void)
 {  {
   int ch;    int ch;
   
Line 2083  _rl_vi_set_mark () Line 2315  _rl_vi_set_mark ()
   if (ch < 0 || ch < 'a' || ch > 'z')   /* make test against 0 explicit */    if (ch < 0 || ch < 'a' || ch > 'z')   /* make test against 0 explicit */
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   ch -= 'a';    ch -= 'a';
   vi_mark_chars[ch] = rl_point;    vi_mark_chars[ch] = rl_point;
Line 2092  _rl_vi_set_mark () Line 2324  _rl_vi_set_mark ()
   
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
 static int  static int
_rl_vi_callback_set_mark (data)_rl_vi_callback_set_mark (_rl_callback_generic_arg *data)
     _rl_callback_generic_arg *data; 
 {  {
   _rl_callback_func = 0;    _rl_callback_func = 0;
   _rl_want_redisplay = 1;    _rl_want_redisplay = 1;
Line 2103  _rl_vi_callback_set_mark (data) Line 2334  _rl_vi_callback_set_mark (data)
 #endif  #endif
   
 int  int
rl_vi_set_mark (count, key)rl_vi_set_mark (int count, int key)
     int count, key; 
 {  {
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
   if (RL_ISSTATE (RL_STATE_CALLBACK))    if (RL_ISSTATE (RL_STATE_CALLBACK))
Line 2119  rl_vi_set_mark (count, key) Line 2349  rl_vi_set_mark (count, key)
 }  }
   
 static int  static int
_rl_vi_goto_mark ()_rl_vi_goto_mark (void)
 {  {
   int ch;    int ch;
   
Line 2130  _rl_vi_goto_mark () Line 2360  _rl_vi_goto_mark ()
   if (ch == '`')    if (ch == '`')
     {      {
       rl_point = rl_mark;        rl_point = rl_mark;
         _rl_fix_point (1);
       return 0;        return 0;
     }      }
   else if (ch < 0 || ch < 'a' || ch > 'z')      /* make test against 0 explicit */    else if (ch < 0 || ch < 'a' || ch > 'z')      /* make test against 0 explicit */
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   
   ch -= 'a';    ch -= 'a';
   if (vi_mark_chars[ch] == -1)    if (vi_mark_chars[ch] == -1)
     {      {
       rl_ding ();        rl_ding ();
      return -1;      return 1;
     }      }
   rl_point = vi_mark_chars[ch];    rl_point = vi_mark_chars[ch];
     _rl_fix_point (1);
   return 0;    return 0;
 }  }
   
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
 static int  static int
_rl_vi_callback_goto_mark (data)_rl_vi_callback_goto_mark (_rl_callback_generic_arg *data)
     _rl_callback_generic_arg *data; 
 {  {
   _rl_callback_func = 0;    _rl_callback_func = 0;
   _rl_want_redisplay = 1;    _rl_want_redisplay = 1;
Line 2161  _rl_vi_callback_goto_mark (data) Line 2392  _rl_vi_callback_goto_mark (data)
 #endif  #endif
   
 int  int
rl_vi_goto_mark (count, key)rl_vi_goto_mark (int count, int key)
     int count, key; 
 {  {
 #if defined (READLINE_CALLBACKS)  #if defined (READLINE_CALLBACKS)
   if (RL_ISSTATE (RL_STATE_CALLBACK))    if (RL_ISSTATE (RL_STATE_CALLBACK))

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>