Don't build readline's shared libs by default
[deliverable/binutils-gdb.git] / readline / vi_mode.c
index a3c35786c366940391f7f56fd690406c9a81c5e4..cae80cac8c407191b3382b4e8065987bfa581b3a 100644 (file)
@@ -1,7 +1,7 @@
 /* vi_mode.c -- A vi emulation mode for Bash.
    Derived from code written by Jeff Sparkes (jsparkes@bnr.ca).  */
 
-/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library (Readline), a library
    for reading lines of text with interactive input and history editing.      
@@ -108,9 +108,13 @@ static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
 /* Arrays for the saved marks. */
 static int vi_mark_chars['z' - 'a' + 1];
 
+static void _rl_vi_replace_insert PARAMS((int));
+static void _rl_vi_save_replace PARAMS((void));
 static void _rl_vi_stuff_insert PARAMS((int));
 static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
 
+static void vi_save_insert_buffer PARAMS ((int, int));
+
 static void _rl_vi_backup PARAMS((void));
 
 static int _rl_vi_arg_dispatch PARAMS((int));
@@ -188,6 +192,29 @@ _rl_vi_textmod_command (c)
   return (member (c, vi_textmod));
 }
 
+int
+_rl_vi_motion_command (c)
+     int c;
+{
+  return (member (c, vi_motion));
+}
+
+static void
+_rl_vi_replace_insert (count)
+     int count;
+{
+  int nchars;
+
+  nchars = strlen (vi_insert_buffer);
+
+  rl_begin_undo_group ();
+  while (count--)
+    /* nchars-1 to compensate for _rl_replace_text using `end+1' in call
+       to rl_delete_text */
+    _rl_replace_text (vi_insert_buffer, rl_point, rl_point+nchars-1);
+  rl_end_undo_group ();
+}
+
 static void
 _rl_vi_stuff_insert (count)
      int count;
@@ -207,7 +234,7 @@ rl_vi_redo (count, c)
 {
   int r;
 
-  if (!rl_explicit_arg)
+  if (rl_explicit_arg == 0)
     {
       rl_numeric_arg = _rl_vi_last_repeat;
       rl_arg_sign = _rl_vi_last_arg_sign;
@@ -224,6 +251,13 @@ rl_vi_redo (count, c)
       if (rl_point > 0)
        _rl_vi_backup ();
     }
+  else if (_rl_vi_last_command == 'R' && vi_insert_buffer && *vi_insert_buffer)
+    {
+      _rl_vi_replace_insert (count);
+      /* And back up point over the last character inserted. */
+      if (rl_point > 0)
+       _rl_vi_backup ();
+    }
   /* Ditto for redoing an insert with `I', but move to the beginning of the
      line like the `I' command does. */
   else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer)
@@ -437,7 +471,7 @@ rl_vi_end_word (count, key)
   if (count < 0)
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
 
   if (_rl_uppercase_p (key))
@@ -679,6 +713,8 @@ rl_vi_insertion_mode (count, key)
 {
   _rl_keymap = vi_insertion_keymap;
   _rl_vi_last_key_before_insert = key;
+  if (_rl_show_mode_in_prompt)
+    _rl_reset_prompt ();
   return (0);
 }
 
@@ -690,6 +726,43 @@ rl_vi_insert_mode (count, key)
   return (0);
 }
 
+static void
+vi_save_insert_buffer (start, len)
+     int start, len;
+{
+  /* Same code as _rl_vi_save_insert below */
+  if (len >= vi_insert_buffer_size)
+    {
+      vi_insert_buffer_size += (len + 32) - (len % 32);
+      vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
+    }
+  strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
+  vi_insert_buffer[len-1] = '\0';
+}
+
+static void
+_rl_vi_save_replace ()
+{
+  int len, start, end;
+  UNDO_LIST *up;
+
+  up = rl_undo_list;
+  if (up == 0 || up->what != UNDO_END || vi_replace_count <= 0)
+    {
+      if (vi_insert_buffer_size >= 1)
+       vi_insert_buffer[0] = '\0';
+      return;
+    }
+  /* Let's try it the quick and easy way for now.  This should essentially
+     accommodate every UNDO_INSERT and save the inserted text to
+     vi_insert_buffer */
+  end = rl_point;
+  start = end - vi_replace_count + 1;
+  len = vi_replace_count + 1;
+
+  vi_save_insert_buffer (start, len);  
+}
+
 static void
 _rl_vi_save_insert (up)
       UNDO_LIST *up;
@@ -706,13 +779,8 @@ _rl_vi_save_insert (up)
   start = up->start;
   end = up->end;
   len = end - start + 1;
-  if (len >= vi_insert_buffer_size)
-    {
-      vi_insert_buffer_size += (len + 32) - (len % 32);
-      vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
-    }
-  strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
-  vi_insert_buffer[len-1] = '\0';
+
+  vi_save_insert_buffer (start, len);
 }
     
 void
@@ -728,7 +796,10 @@ _rl_vi_done_inserting ()
         on absolute indices into the line which may change (though they
         probably will not). */
       _rl_vi_doing_insert = 0;
-      _rl_vi_save_insert (rl_undo_list->next);
+      if (_rl_vi_last_key_before_insert == 'R')
+       _rl_vi_save_replace ();         /* Half the battle */
+      else
+       _rl_vi_save_insert (rl_undo_list->next);
       vi_continued_command = 1;
     }
   else
@@ -762,6 +833,9 @@ rl_vi_movement_mode (count, key)
   if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
     rl_free_undo_list ();
 
+  if (_rl_show_mode_in_prompt)
+    _rl_reset_prompt ();
+
   RL_SETSTATE (RL_STATE_VICMDONCE);
   return (0);
 }
@@ -1234,11 +1308,19 @@ rl_vi_delete_to (count, key)
       _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);
     }
-  else if (vi_redoing)
+  else if (vi_redoing && _rl_vi_last_motion != 'd')    /* `dd' is special */
     {
       _rl_vimvcxt->motion = _rl_vi_last_motion;
       r = rl_domove_motion_callback (_rl_vimvcxt);
     }
+  else if (vi_redoing)         /* handle redoing `dd' here */
+    {
+      _rl_vimvcxt->motion = _rl_vi_last_motion;
+      rl_mark = rl_end;
+      rl_beg_of_line (1, key);
+      RL_UNSETSTATE (RL_STATE_VIMOTION);
+      r = vidomove_dispatch (_rl_vimvcxt);
+    }
 #if defined (READLINE_CALLBACKS)
   else if (RL_ISSTATE (RL_STATE_CALLBACK))
     {
@@ -1316,11 +1398,19 @@ rl_vi_change_to (count, key)
       _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);
     }
-  else if (vi_redoing)
+  else if (vi_redoing && _rl_vi_last_motion != 'c')    /* `cc' is special */
     {
       _rl_vimvcxt->motion = _rl_vi_last_motion;
       r = rl_domove_motion_callback (_rl_vimvcxt);
     }
+  else if (vi_redoing)         /* handle redoing `cc' here */
+    {
+      _rl_vimvcxt->motion = _rl_vi_last_motion;
+      rl_mark = rl_end;
+      rl_beg_of_line (1, key);
+      RL_UNSETSTATE (RL_STATE_VIMOTION);
+      r = vidomove_dispatch (_rl_vimvcxt);
+    }
 #if defined (READLINE_CALLBACKS)
   else if (RL_ISSTATE (RL_STATE_CALLBACK))
     {
@@ -1377,6 +1467,19 @@ rl_vi_yank_to (count, key)
       _rl_vimvcxt->motion = '$';
       r = rl_domove_motion_callback (_rl_vimvcxt);
     }
+  else if (vi_redoing && _rl_vi_last_motion != 'y')    /* `yy' is special */
+    {
+      _rl_vimvcxt->motion = _rl_vi_last_motion;
+      r = rl_domove_motion_callback (_rl_vimvcxt);
+    }
+  else if (vi_redoing)                 /* handle redoing `yy' here */
+    {
+      _rl_vimvcxt->motion = _rl_vi_last_motion;
+      rl_mark = rl_end;
+      rl_beg_of_line (1, key);
+      RL_UNSETSTATE (RL_STATE_VIMOTION);
+      r = vidomove_dispatch (_rl_vimvcxt);
+    }
 #if defined (READLINE_CALLBACKS)
   else if (RL_ISSTATE (RL_STATE_CALLBACK))
     {
@@ -1438,7 +1541,7 @@ rl_vi_rubout (count, key)
   if (rl_point == 0)
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
 
   opoint = rl_point;
@@ -1469,7 +1572,7 @@ rl_vi_delete (count, key)
   if (rl_end == 0)
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
 
   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -1554,13 +1657,13 @@ rl_vi_char_search (count, key)
   if (key == ';' || key == ',')
     {
       if (_rl_cs_orig_dir == 0)
-       return -1;
+       return 1;
 #if defined (HANDLE_MULTIBYTE)
       if (_rl_vi_last_search_mblen == 0)
-       return -1;
+       return 1;
 #else
       if (_rl_vi_last_search_char == 0)
-       return -1;
+       return 1;
 #endif
       _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
     }
@@ -1659,7 +1762,7 @@ rl_vi_match (ignore, key)
        {
          rl_point = pos;
          rl_ding ();
-         return -1;
+         return 1;
        }
     }
 
@@ -1689,7 +1792,7 @@ rl_vi_match (ignore, key)
          else
            {
              rl_ding ();
-             return -1;
+             return 1;
            }
        }
     }
@@ -1713,7 +1816,7 @@ rl_vi_match (ignore, key)
          else
            {
              rl_ding ();
-             return -1;
+             return 1;
            }
        }
     }
@@ -1911,14 +2014,20 @@ rl_vi_replace (count, key)
 
   vi_replace_count = 0;
 
-  if (!vi_replace_map)
+  if (vi_replace_map == 0)
     {
       vi_replace_map = rl_make_bare_keymap ();
 
+      for (i = 0; i < ' '; i++)
+       if (vi_insertion_keymap[i].type == ISFUNC)
+         vi_replace_map[i].function = vi_insertion_keymap[i].function;
+
       for (i = ' '; i < KEYMAP_SIZE; i++)
        vi_replace_map[i].function = rl_vi_overstrike;
 
       vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
+
+      /* Make sure these are what we want. */
       vi_replace_map[ESC].function = rl_vi_movement_mode;
       vi_replace_map[RETURN].function = rl_newline;
       vi_replace_map[NEWLINE].function = rl_newline;
@@ -1931,7 +2040,12 @@ rl_vi_replace (count, key)
        vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
 
     }
+
+  rl_vi_start_inserting (key, 1, rl_arg_sign);
+
+  _rl_vi_last_key_before_insert = key;
   _rl_keymap = vi_replace_map;
+
   return (0);
 }
 
@@ -1976,7 +2090,7 @@ _rl_vi_set_mark ()
   if (ch < 0 || ch < 'a' || ch > 'z')  /* make test against 0 explicit */
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
   ch -= 'a';
   vi_mark_chars[ch] = rl_point;
@@ -2028,14 +2142,14 @@ _rl_vi_goto_mark ()
   else if (ch < 0 || ch < 'a' || ch > 'z')     /* make test against 0 explicit */
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
 
   ch -= 'a';
   if (vi_mark_chars[ch] == -1)
     {
       rl_ding ();
-      return -1;
+      return 1;
     }
   rl_point = vi_mark_chars[ch];
   return 0;
This page took 0.027789 seconds and 4 git commands to generate.