The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 1, or
+ as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
- 675 Mass Ave, Cambridge, MA 02139, USA. */
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
/* **************************************************************** */
#if defined (VI_MODE)
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
#include <sys/types.h>
#if defined (HAVE_STDLIB_H)
#include "readline.h"
#include "history.h"
-#ifndef digit_p
-#define digit_p(c) ((c) >= '0' && (c) <= '9')
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+#ifndef _rl_digit_p
+#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#endif
-#ifndef digit_value
-#define digit_value(c) ((c) - '0')
+#ifndef _rl_digit_value
+#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member
#endif
#ifndef isident
-#define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_'))
+#define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_'))
#endif
#ifndef exchange
#define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
#endif
-#ifndef VI_COMMENT_BEGIN_DEFAULT
-#define VI_COMMENT_BEGIN_DEFAULT "#"
-#endif
-
-#if defined (STATIC_MALLOC)
-static char *xmalloc (), *xrealloc ();
-#else
-extern char *xmalloc (), *xrealloc ();
-#endif /* STATIC_MALLOC */
-
-/* Variables imported from readline.c */
-extern int rl_point, rl_end, rl_mark, rl_done;
-extern FILE *rl_instream;
-extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
-extern Keymap _rl_keymap;
-extern char *rl_prompt;
-extern char *rl_line_buffer;
-extern int rl_arg_sign;
-
-extern void _rl_dispatch ();
-
-extern void rl_extend_line_buffer ();
-extern int rl_vi_check ();
-
/* Non-zero means enter insertion mode. */
-static int _rl_vi_doing_insert = 0;
-
-/* String inserted into the line by rl_vi_comment (). */
-char *rl_vi_comment_begin = (char *)NULL;
+static int _rl_vi_doing_insert;
-/* *** UNCLEAN *** */
/* Command keys which do movement for xxx_to commands. */
-static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
+static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
-static Keymap vi_replace_map = (Keymap)NULL;
+static Keymap vi_replace_map;
/* The number of characters inserted in the last replace operation. */
-static int vi_replace_count = 0;
+static int vi_replace_count;
/* If non-zero, we have text inserted after a c[motion] command that put
us implicitly into insert mode. Some people want this text to be
attached to the command so that it is `redoable' with `.'. */
-static int vi_continued_command = 0;
+static int vi_continued_command;
+static char *vi_insert_buffer;
+static int vi_insert_buffer_size;
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
-static int _rl_vi_last_motion = 0;
-static int _rl_vi_last_search_char = 0;
-static int _rl_vi_last_replacement = 0;
+static int _rl_vi_last_motion;
+static int _rl_vi_last_search_char;
+static int _rl_vi_last_replacement;
-static int vi_redoing = 0;
+static int _rl_vi_last_key_before_insert;
+
+static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
-static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+
+/* Arrays for the saved marks. */
+static int vi_mark_chars[27];
-static int rl_digit_loop1 ();
+static int rl_digit_loop1 __P((void));
+
+void
+_rl_vi_initialize_line ()
+{
+ register int i;
+
+ for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
+ vi_mark_chars[i] = -1;
+}
void
_rl_vi_reset_last ()
/* Is the command C a VI mode text modification command? */
int
-rl_vi_textmod_command (c)
+_rl_vi_textmod_command (c)
int c;
{
return (member (c, vi_textmod));
}
+static void
+_rl_vi_stuff_insert (count)
+ int count;
+{
+ rl_begin_undo_group ();
+ while (count--)
+ rl_insert_text (vi_insert_buffer);
+ rl_end_undo_group ();
+}
+
/* Bound to `.'. Called from command mode, so we know that we have to
redo a text modification command. The default for _rl_vi_last_command
puts you back into insert mode. */
+int
rl_vi_redo (count, c)
int count, c;
{
}
vi_redoing = 1;
- _rl_dispatch (_rl_vi_last_command, _rl_keymap);
+ /* If we're redoing an insert with `i', stuff in the inserted text
+ and do not go into insertion mode. */
+ if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
+ {
+ _rl_vi_stuff_insert (count);
+ /* And back up point over the last character inserted. */
+ if (rl_point > 0)
+ rl_point--;
+ }
+ else
+ _rl_dispatch (_rl_vi_last_command, _rl_keymap);
vi_redoing = 0;
return (0);
}
+
+/* A placeholder for further expansion. */
+int
+rl_vi_undo (count, key)
+ int count, key;
+{
+ return (rl_undo_command (count, key));
+}
/* Yank the nth arg from the previous line into this line at point. */
+int
rl_vi_yank_arg (count, key)
int count, key;
{
/* With an argument, move back that many history lines, else move to the
beginning of history. */
+int
rl_vi_fetch_history (count, c)
int count, c;
{
- int current = where_history ();
+ int wanted;
/* Giving an argument of n means we want the nth command in the history
file. The command number is interpreted the same way that the bash
output of `history'. */
if (rl_explicit_arg)
{
- int wanted = history_base + current - count;
+ wanted = history_base + where_history () - count;
if (wanted <= 0)
rl_beginning_of_history (0, 0);
else
- rl_get_previous_history (wanted);
+ rl_get_previous_history (wanted, c);
}
else
rl_beginning_of_history (count, 0);
}
/* Search again for the last thing searched for. */
+int
rl_vi_search_again (count, key)
int count, key;
{
}
/* Do a vi style search. */
+int
rl_vi_search (count, key)
int count, key;
{
break;
default:
- ding ();
+ rl_ding ();
break;
}
return (0);
}
/* Completion, from vi's point of view. */
+int
rl_vi_complete (ignore, key)
int ignore, key;
{
}
/* Tilde expansion for vi mode. */
+int
rl_vi_tilde_expand (ignore, key)
int ignore, key;
{
}
/* Previous word in vi mode. */
+int
rl_vi_prev_word (count, key)
int count, key;
{
if (rl_point == 0)
{
- ding ();
+ rl_ding ();
return (0);
}
- if (uppercase_p (key))
- rl_vi_bWord (count);
+ if (_rl_uppercase_p (key))
+ rl_vi_bWord (count, key);
else
- rl_vi_bword (count);
+ rl_vi_bword (count, key);
return (0);
}
/* Next word in vi mode. */
+int
rl_vi_next_word (count, key)
int count, key;
{
if (rl_point >= (rl_end - 1))
{
- ding ();
+ rl_ding ();
return (0);
}
- if (uppercase_p (key))
- rl_vi_fWord (count);
+ if (_rl_uppercase_p (key))
+ rl_vi_fWord (count, key);
else
- rl_vi_fword (count);
+ rl_vi_fword (count, key);
return (0);
}
/* Move to the end of the ?next? word. */
+int
rl_vi_end_word (count, key)
int count, key;
{
if (count < 0)
{
- ding ();
+ rl_ding ();
return -1;
}
- if (uppercase_p (key))
- rl_vi_eWord (count);
+ if (_rl_uppercase_p (key))
+ rl_vi_eWord (count, key);
else
- rl_vi_eword (count);
+ rl_vi_eword (count, key);
return (0);
}
/* Move forward a word the way that 'W' does. */
-rl_vi_fWord (count)
- int count;
+int
+rl_vi_fWord (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
return (0);
}
-rl_vi_bWord (count)
- int count;
+int
+rl_vi_bWord (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point > 0)
{
return (0);
}
-rl_vi_eWord (count)
- int count;
+int
+rl_vi_eWord (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
return (0);
}
-rl_vi_fword (count)
- int count;
+int
+rl_vi_fword (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
return (0);
}
-rl_vi_bword (count)
- int count;
+int
+rl_vi_bword (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point > 0)
{
return (0);
}
-rl_vi_eword (count)
- int count;
+int
+rl_vi_eword (count, ignore)
+ int count, ignore;
{
while (count-- && rl_point < rl_end - 1)
{
return (0);
}
+int
rl_vi_insert_beg (count, key)
int count, key;
{
return (0);
}
+int
rl_vi_append_mode (count, key)
int count, key;
{
return (0);
}
+int
rl_vi_append_eol (count, key)
int count, key;
{
}
/* What to do in the case of C-d. */
+int
rl_vi_eof_maybe (count, c)
int count, c;
{
/* Switching from one mode to the other really just involves
switching keymaps. */
+int
rl_vi_insertion_mode (count, key)
int count, key;
{
_rl_keymap = vi_insertion_keymap;
+ _rl_vi_last_key_before_insert = key;
return (0);
}
+static void
+_rl_vi_save_insert (up)
+ UNDO_LIST *up;
+{
+ int len, start, end;
+
+ if (up == 0)
+ {
+ if (vi_insert_buffer_size >= 1)
+ vi_insert_buffer[0] = '\0';
+ return;
+ }
+
+ 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 = xrealloc (vi_insert_buffer, vi_insert_buffer_size);
+ }
+ strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
+ vi_insert_buffer[len-1] = '\0';
+}
+
void
_rl_vi_done_inserting ()
{
rl_end_undo_group ();
/* Now, the text between rl_undo_list->next->start and
rl_undo_list->next->end is what was inserted while in insert
- mode. */
+ mode. It gets copied to VI_INSERT_BUFFER because it depends
+ 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);
vi_continued_command = 1;
}
else
- vi_continued_command = 0;
+ {
+ if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
+ _rl_vi_save_insert (rl_undo_list);
+ /* XXX - Other keys probably need to be checked. */
+ else if (_rl_vi_last_key_before_insert == 'C')
+ rl_end_undo_group ();
+ while (_rl_undo_group_level > 0)
+ rl_end_undo_group ();
+ vi_continued_command = 0;
+ }
}
+int
rl_vi_movement_mode (count, key)
int count, key;
{
if (rl_point > 0)
- rl_backward (1);
-
-#if 0
- _rl_vi_reset_last ();
-#endif
+ rl_backward (1, key);
_rl_keymap = vi_movement_keymap;
_rl_vi_done_inserting ();
return (0);
}
+int
rl_vi_arg_digit (count, c)
int count, c;
{
if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
- return (rl_beg_of_line ());
+ return (rl_beg_of_line (1, c));
else
return (rl_digit_argument (count, c));
}
+int
rl_vi_change_case (count, ignore)
int count, ignore;
{
while (count-- && rl_point < rl_end)
{
- if (uppercase_p (rl_line_buffer[rl_point]))
- c = to_lower (rl_line_buffer[rl_point]);
- else if (lowercase_p (rl_line_buffer[rl_point]))
- c = to_upper (rl_line_buffer[rl_point]);
+ if (_rl_uppercase_p (rl_line_buffer[rl_point]))
+ c = _rl_to_lower (rl_line_buffer[rl_point]);
+ else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
+ c = _rl_to_upper (rl_line_buffer[rl_point]);
else
{
/* Just skip over characters neither upper nor lower case. */
- rl_forward (1);
+ rl_forward (1, c);
continue;
}
rl_vi_check ();
}
else
- rl_forward (1);
+ rl_forward (1, c);
}
return (0);
}
+int
rl_vi_put (count, key)
int count, key;
{
- if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
+ if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point++;
- rl_yank ();
- rl_backward (1);
+ rl_yank (1, key);
+ rl_backward (1, key);
return (0);
}
+int
rl_vi_check ()
{
if (rl_point && rl_point == rl_end)
return (0);
}
+int
rl_vi_column (count, key)
int count, key;
{
if (count > rl_end)
- rl_end_of_line ();
+ rl_end_of_line (1, key);
else
rl_point = count - 1;
return (0);
int old_end;
rl_mark = rl_point;
+ RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
*nextkey = c;
if (!member (c, vi_motion))
{
- if (digit_p (c))
+ if (_rl_digit_p (c))
{
save = rl_numeric_arg;
- rl_numeric_arg = digit_value (c);
+ rl_numeric_arg = _rl_digit_value (c);
rl_digit_loop1 ();
rl_numeric_arg *= save;
+ RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); /* real command */
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
*nextkey = c;
}
else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
{
rl_mark = rl_end;
- rl_beg_of_line ();
+ rl_beg_of_line (1, c);
_rl_vi_last_motion = c;
return (0);
}
/* 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
non-whitespace character, move back one (presumably to whitespace). */
- if ((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]))
rl_point--;
/* 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. */
- if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W'))
+ if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
{
/* Don't move farther back than where we started. */
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
}
/* A simplified loop for vi. Don't dispatch key at end.
- Don't recognize minus sign? */
+ Don't recognize minus sign?
+ Should this do rl_save_prompt/rl_restore_prompt? */
static int
rl_digit_loop1 ()
{
int key, c;
+ RL_SETSTATE(RL_STATE_NUMERICARG);
while (1)
{
+ if (rl_numeric_arg > 1000000)
+ {
+ rl_explicit_arg = rl_numeric_arg = 0;
+ rl_ding ();
+ rl_clear_message ();
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return 1;
+ }
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
+ RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (_rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
}
c = UNMETA (c);
- if (digit_p (c))
+ if (_rl_digit_p (c))
{
if (rl_explicit_arg)
- rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c);
+ rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
else
- rl_numeric_arg = digit_value (c);
+ rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
}
else
break;
}
}
+
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (0);
}
+int
rl_vi_delete_to (count, key)
int count, key;
{
int c;
- if (uppercase_p (key))
+ if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
if (rl_vi_domove (key, &c))
{
- ding ();
+ rl_ding ();
return -1;
}
return (0);
}
+int
rl_vi_change_to (count, key)
int count, key;
{
int c, start_pos;
- if (uppercase_p (key))
+ if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
if (rl_vi_domove (key, &c))
{
- ding ();
+ rl_ding ();
return -1;
}
rl_mark++;
/* The cursor never moves with c[wW]. */
- if ((to_upper (c) == 'W') && rl_point < start_pos)
+ if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
rl_point = start_pos;
- rl_kill_text (rl_point, rl_mark);
-
- rl_begin_undo_group ();
- _rl_vi_doing_insert = 1;
- _rl_vi_set_last (key, count, rl_arg_sign);
- rl_vi_insertion_mode (1, key);
+ if (vi_redoing)
+ {
+ if (vi_insert_buffer && *vi_insert_buffer)
+ rl_begin_undo_group ();
+ rl_delete_text (rl_point, rl_mark);
+ if (vi_insert_buffer && *vi_insert_buffer)
+ {
+ rl_insert_text (vi_insert_buffer);
+ rl_end_undo_group ();
+ }
+ }
+ else
+ {
+ rl_begin_undo_group (); /* to make the `u' command work */
+ rl_kill_text (rl_point, rl_mark);
+ /* `C' does not save the text inserted for undoing or redoing. */
+ if (_rl_uppercase_p (key) == 0)
+ _rl_vi_doing_insert = 1;
+ _rl_vi_set_last (key, count, rl_arg_sign);
+ rl_vi_insertion_mode (1, key);
+ }
return (0);
}
+int
rl_vi_yank_to (count, key)
int count, key;
{
int c, save = rl_point;
- if (uppercase_p (key))
+ if (_rl_uppercase_p (key))
rl_stuff_char ('$');
if (rl_vi_domove (key, &c))
{
- ding ();
+ rl_ding ();
return -1;
}
return (0);
}
+int
rl_vi_delete (count, key)
int count, key;
{
if (rl_end == 0)
{
- ding ();
+ rl_ding ();
return -1;
}
rl_kill_text (rl_point, end);
if (rl_point > 0 && rl_point == rl_end)
- rl_backward (1);
+ rl_backward (1, key);
return (0);
}
-/* Turn the current line into a comment in shell history.
- A K*rn shell style function. */
-rl_vi_comment (count, key)
+int
+rl_vi_back_to_indent (count, key)
int count, key;
{
- rl_beg_of_line ();
-
- if (rl_vi_comment_begin != (char *)NULL)
- rl_insert_text (rl_vi_comment_begin);
- else
- rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
-
- rl_redisplay ();
- rl_newline (1, '\n');
+ rl_beg_of_line (1, key);
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
return (0);
}
+int
rl_vi_first_print (count, key)
int count, key;
{
- return (rl_back_to_indent ());
-}
-
-rl_back_to_indent (ignore1, ignore2)
- int ignore1, ignore2;
-{
- rl_beg_of_line ();
- while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
- rl_point++;
- return (0);
+ return (rl_vi_back_to_indent (1, key));
}
-/* NOTE: it is necessary that opposite directions are inverses */
-#define FTO 1 /* forward to */
-#define BTO -1 /* backward to */
-#define FFIND 2 /* forward find */
-#define BFIND -2 /* backward find */
-
+int
rl_vi_char_search (count, key)
int count, key;
{
static char target;
static int orig_dir, dir;
- int pos;
if (key == ';' || key == ',')
- dir = (key == ';' ? orig_dir : -orig_dir);
+ dir = key == ';' ? orig_dir : -orig_dir;
else
{
if (vi_redoing)
target = _rl_vi_last_search_char;
else
- _rl_vi_last_search_char = target = rl_getc (rl_instream);
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ _rl_vi_last_search_char = target = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ }
switch (key)
{
}
}
- pos = rl_point;
-
- while (count--)
- {
- if (dir < 0)
- {
- if (pos == 0)
- {
- ding ();
- return -1;
- }
-
- pos--;
- do
- {
- if (rl_line_buffer[pos] == target)
- {
- if (dir == BTO)
- rl_point = pos + 1;
- else
- rl_point = pos;
- break;
- }
- }
- while (pos--);
-
- if (pos < 0)
- {
- ding ();
- return -1;
- }
- }
- else
- { /* dir > 0 */
- if (pos >= rl_end)
- {
- ding ();
- return -1;
- }
-
- pos++;
- do
- {
- if (rl_line_buffer[pos] == target)
- {
- if (dir == FTO)
- rl_point = pos - 1;
- else
- rl_point = pos;
- break;
- }
- }
- while (++pos < rl_end);
-
- if (pos >= (rl_end - 1))
- {
- ding ();
- return -1;
- }
- }
- }
- return (0);
+ return (_rl_char_search_internal (count, dir, target));
}
/* Match brackets */
+int
rl_vi_match (ignore, key)
int ignore, key;
{
{
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
rl_point < rl_end - 1)
- rl_forward (1);
+ rl_forward (1, key);
if (brack <= 0)
{
rl_point = pos;
- ding ();
+ rl_ding ();
return -1;
}
}
}
else
{
- ding ();
+ rl_ding ();
return -1;
}
}
}
else
{
- ding ();
+ rl_ding ();
return -1;
}
}
}
}
+int
rl_vi_change_char (count, key)
int count, key;
{
if (vi_redoing)
c = _rl_vi_last_replacement;
else
- _rl_vi_last_replacement = c = rl_getc (rl_instream);
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ _rl_vi_last_replacement = c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ }
if (c == '\033' || c == CTRL ('C'))
return -1;
rl_delete (1, c);
rl_insert (1, c);
if (count == 0)
- rl_backward (1);
+ rl_backward (1, c);
rl_end_undo_group ();
}
return (0);
}
+int
rl_vi_subst (count, key)
int count, key;
{
rl_begin_undo_group ();
- if (uppercase_p (key))
+ if (_rl_uppercase_p (key))
{
- rl_beg_of_line ();
- rl_kill_line (1);
+ rl_beg_of_line (1, key);
+ rl_kill_line (1, key);
}
else
rl_delete_text (rl_point, rl_point+count);
_rl_vi_set_last (key, count, rl_arg_sign);
- rl_begin_undo_group ();
- _rl_vi_doing_insert = 1;
- rl_vi_insertion_mode (1, key);
+ if (vi_redoing)
+ {
+ int o = _rl_doing_an_undo;
+
+ _rl_doing_an_undo = 1;
+ if (vi_insert_buffer && *vi_insert_buffer)
+ rl_insert_text (vi_insert_buffer);
+ _rl_doing_an_undo = o;
+ }
+ else
+ {
+ rl_begin_undo_group ();
+ _rl_vi_doing_insert = 1;
+ rl_vi_insertion_mode (1, key);
+ }
return (0);
}
+int
rl_vi_overstrike (count, key)
int count, key;
{
return (0);
}
-rl_vi_overstrike_delete (count)
- int count;
+int
+rl_vi_overstrike_delete (count, key)
+ int count, key;
{
int i, s;
{
if (vi_replace_count == 0)
{
- ding ();
+ rl_ding ();
break;
}
s = rl_point;
vi_replace_count--;
if (rl_point == s)
- rl_backward (1);
+ rl_backward (1, key);
}
if (vi_replace_count == 0 && _rl_vi_doing_insert)
return (0);
}
+int
rl_vi_replace (count, key)
int count, key;
{
/* Try to complete the word we are standing on or the word that ends with
the previous character. A space matches everything. Word delimiters are
space and ;. */
+int
rl_vi_possible_completions()
{
int save_pos = rl_point;
}
else if (rl_line_buffer[rl_point - 1] == ';')
{
- ding ();
+ rl_ding ();
return (0);
}
}
#endif
-#if defined (STATIC_MALLOC)
-\f
-/* **************************************************************** */
-/* */
-/* xmalloc and xrealloc () */
-/* */
-/* **************************************************************** */
-
-static void memory_error_and_abort ();
-
-static char *
-xmalloc (bytes)
- int bytes;
+/* Functions to save and restore marks. */
+int
+rl_vi_set_mark (count, key)
+ int count, key;
{
- char *temp = (char *)malloc (bytes);
+ int ch;
- if (!temp)
- memory_error_and_abort ();
- return (temp);
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (_rl_lowercase_p (ch) == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+ ch -= 'a';
+ vi_mark_chars[ch] = rl_point;
+ return 0;
}
-static char *
-xrealloc (pointer, bytes)
- char *pointer;
- int bytes;
+int
+rl_vi_goto_mark (count, key)
+ int count, key;
{
- char *temp;
+ int ch;
- if (!pointer)
- temp = (char *)xmalloc (bytes);
- else
- temp = (char *)realloc (pointer, bytes);
-
- if (!temp)
- memory_error_and_abort ();
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
- return (temp);
-}
+ if (ch == '`')
+ {
+ rl_point = rl_mark;
+ return 0;
+ }
+ else if (_rl_lowercase_p (ch) == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
-static void
-memory_error_and_abort ()
-{
- fprintf (stderr, "readline: Out of virtual memory!\n");
- abort ();
+ ch -= 'a';
+ if (vi_mark_chars[ch] == -1)
+ {
+ rl_ding ();
+ return -1;
+ }
+ rl_point = vi_mark_chars[ch];
+ return 0;
}
-#endif /* STATIC_MALLOC */
#endif /* VI_MODE */