diff options
author | Stu Grossman <grossman@cygnus> | 1991-11-19 05:59:18 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1991-11-19 05:59:18 +0000 |
commit | 870ca2534097fc727b6762fab958fad76722d638 (patch) | |
tree | 45e293360e93ebd8320410c8b9b65fb6729f13ff /readline/vi_mode.c | |
parent | c5bbc6ea4136d242ea345285f0758826d019dbaf (diff) | |
download | gdb-870ca2534097fc727b6762fab958fad76722d638.zip gdb-870ca2534097fc727b6762fab958fad76722d638.tar.gz gdb-870ca2534097fc727b6762fab958fad76722d638.tar.bz2 |
Integrate new readline from Brian Fox.
Diffstat (limited to 'readline/vi_mode.c')
-rw-r--r-- | readline/vi_mode.c | 600 |
1 files changed, 449 insertions, 151 deletions
diff --git a/readline/vi_mode.c b/readline/vi_mode.c index 478af91..bdc8107 100644 --- a/readline/vi_mode.c +++ b/readline/vi_mode.c @@ -1,14 +1,83 @@ /* 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 (jeff1@????). - */ +/* Copyright (C) 1988, 1991 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The 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 (at your option) + any later version. + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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. */ /* **************************************************************** */ /* */ /* VI Emulation Mode */ /* */ /* **************************************************************** */ +#if defined (VI_MODE) + +#include <stdio.h> + +#if defined (__GNUC__) +# define alloca __builtin_alloca +#else +# if defined (sparc) || defined (HAVE_ALLOCA_H) +# include <alloca.h> +# endif +#endif + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#ifndef digit +#define digit(c) ((c) >= '0' && (c) <= '9') +#endif + +#ifndef isletter +#define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) +#endif + +#ifndef digit_value +#define digit_value(c) ((c) - '0') +#endif + +#ifndef member +#define member(c, s) ((c) ? index ((s), (c)) : 0) +#endif + +#ifndef isident +#define isident(c) ((isletter(c) || digit(c) || c == '_')) +#endif + +#ifndef exchange +#define exchange(x, y) {int temp = x; x = y; y = temp;} +#endif + +/* 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 keymap; +extern char *rl_prompt; +extern char *rl_line_buffer; +extern int rl_arg_sign; + +extern char *xmalloc (), *xrealloc (); +extern void rl_extend_line_buffer (); /* Last string searched for from `/' or `?'. */ static char *vi_last_search = (char *)NULL; @@ -17,6 +86,9 @@ static int vi_histpos; /* Non-zero means enter insertion mode. */ int vi_doing_insert = 0; +/* String inserted into the line by rl_vi_comment (). */ +char *rl_vi_comment_begin = (char *)NULL; + /* *** UNCLEAN *** */ /* Command keys which do movement for xxx_to commands. */ static char *vi_motion = " hl^$0ftFt;,%wbeWBE|"; @@ -26,13 +98,43 @@ static char *vi_motion = " hl^$0ftFt;,%wbeWBE|"; static Keymap vi_replace_map = (Keymap)NULL; /* The number of characters inserted in the last replace operation. */ -static vi_replace_count = 0; +static int vi_replace_count = 0; /* Yank the nth arg from the previous line into this line at point. */ rl_vi_yank_arg (count) int count; { - rl_yank_nth_arg (count, 0); + /* 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. */ + if (rl_explicit_arg) + rl_yank_nth_arg (count - 1, 0); + else + rl_yank_nth_arg ('$', 0); +} + +/* With an argument, move back that many history lines, else move to the + beginning of history. */ +rl_vi_fetch_history (count, c) + int count, c; +{ + extern int rl_explicit_arg; + int current = where_history (); + + /* 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 + `history' command does it -- that is, giving an argument count of 450 + to this command would get the command listed as number 450 in the + output of `history'. */ + if (rl_explicit_arg) + { + int wanted = history_base + current - count; + if (wanted <= 0) + rl_beginning_of_history (0, 0); + else + rl_get_previous_history (wanted); + } + else + rl_beginning_of_history (count, 0); } /* Search again for the last thing searched for. */ @@ -78,7 +180,7 @@ rl_vi_search (count, key) save_pos = rl_point; /* Reuse the line input buffer to read the search string. */ - the_line[0] = 0; + rl_line_buffer[0] = 0; rl_end = rl_point = 0; p = (char *)alloca (2 + (rl_prompt ? strlen (rl_prompt) : 0)); @@ -128,8 +230,38 @@ rl_vi_search (count, key) if (vi_last_search) free (vi_last_search); - vi_last_search = savestring (the_line); - rl_vi_dosearch (the_line, dir); + vi_last_search = savestring (rl_line_buffer); + rl_vi_dosearch (rl_line_buffer, dir); +} + +/* Search for STRING in the history list. DIR is < 0 for searching + backwards. POS is an absolute index into the history list at + which point to begin searching. If the first character of STRING + is `^', the string must match a prefix of a history line, otherwise + a full substring match is performed. */ +static int +vi_history_search_pos (string, dir, pos) + char *string; + int dir, pos; +{ + int ret, old = where_history (); + + history_set_pos (pos); + + if (*string == '^') + ret = history_search_prefix (string + 1, dir); + else + ret = history_search (string, dir); + + if (ret == -1) + { + history_set_pos (old); + return (-1); + } + + ret = where_history (); + history_set_pos (old); + return ret; } rl_vi_dosearch (string, dir) @@ -145,7 +277,7 @@ rl_vi_dosearch (string, dir) return; } - if ((save = history_search_pos (string, dir, vi_histpos + dir)) == -1) + if ((save = vi_history_search_pos (string, dir, vi_histpos + dir)) == -1) { maybe_unsave_line (); rl_clear_message (); @@ -161,9 +293,16 @@ rl_vi_dosearch (string, dir) h = current_history (); history_set_pos (old); - strcpy (the_line, h->line); + { + int line_len = strlen (h->line); + + if (line_len >= rl_line_buffer_len) + rl_extend_line_buffer (line_len); + strcpy (rl_line_buffer, h->line); + } + rl_undo_list = (UNDO_LIST *)h->data; - rl_end = strlen (the_line); + rl_end = strlen (rl_line_buffer); rl_point = 0; rl_clear_message (); } @@ -172,19 +311,21 @@ rl_vi_dosearch (string, dir) rl_vi_complete (ignore, key) int ignore, key; { - if (!whitespace (the_line[rl_point])) + if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) { - if (!whitespace (the_line[rl_point + 1])) + if (!whitespace (rl_line_buffer[rl_point + 1])) rl_vi_end_word (1, 'E'); rl_point++; } if (key == '*') - rl_complete_internal ('*'); + rl_complete_internal ('*'); /* Expansion and replacement. */ + else if (key == '=') + rl_complete_internal ('?'); /* List possible completions. */ + else if (key == '\\') + rl_complete_internal (TAB); /* Standard Readline completion. */ else rl_complete (0, key); - - rl_vi_insertion_mode (); } /* Previous word in vi mode. */ @@ -197,6 +338,12 @@ rl_vi_prev_word (count, key) return; } + if (rl_point == 0) + { + ding (); + return; + } + if (uppercase_p (key)) rl_vi_bWord (count); else @@ -213,6 +360,12 @@ rl_vi_next_word (count, key) return; } + if (rl_point >= (rl_end - 1)) + { + ding (); + return; + } + if (uppercase_p (key)) rl_vi_fWord (count); else @@ -242,11 +395,11 @@ rl_vi_fWord (count) while (count-- && rl_point < (rl_end - 1)) { /* Skip until whitespace. */ - while (!whitespace (the_line[rl_point]) && rl_point < rl_end) + while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) rl_point++; /* Now skip whitespace. */ - while (whitespace (the_line[rl_point]) && rl_point < rl_end) + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) rl_point++; } } @@ -256,42 +409,71 @@ rl_vi_bWord (count) { while (count-- && rl_point > 0) { - while (rl_point-- >= 0 && whitespace (the_line[rl_point])); - while (rl_point >= 0 && !whitespace (the_line[rl_point])) + /* 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. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) rl_point--; - rl_point++; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + if (rl_point > 0) + { + while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point])); + rl_point++; + } } } rl_vi_eWord (count) int count; { - while (count -- && rl_point < (rl_end - 1)) + while (count-- && rl_point < (rl_end - 1)) { - while (rl_point++ < rl_end && whitespace (the_line[rl_point])); - while (rl_point++ < rl_end && !whitespace (the_line[rl_point])); - rl_point--; + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Move to the next non-whitespace character (to the start of the + next word). */ + while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point])); + + if (rl_point && rl_point < rl_end) + { + /* Skip whitespace. */ + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Skip until whitespace. */ + while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Move back to the last character of the word. */ + rl_point--; + } } } rl_vi_fword (count) int count; { - while (count -- && rl_point < (rl_end - 1)) + while (count-- && rl_point < (rl_end - 1)) { - if (isident (the_line[rl_point])) + /* Move to white space (really non-identifer). */ + if (isident (rl_line_buffer[rl_point])) { - while (isident (the_line[rl_point]) && rl_point < rl_end) - rl_point += 1; + while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; } - else if (!whitespace (the_line[rl_point])) + else /* if (!whitespace (rl_line_buffer[rl_point])) */ { - while (!isident (the_line[rl_point]) && - !whitespace (the_line[rl_point]) && rl_point < rl_end) - rl_point += 1; + while (!isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; } - while (whitespace (the_line[rl_point]) && rl_point < rl_end) + /* Move past whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) rl_point++; } } @@ -299,16 +481,35 @@ rl_vi_fword (count) rl_vi_bword (count) int count; { - while (count -- && rl_point > 0) + while (count-- && rl_point > 0) { - while (--rl_point > 0 && whitespace (the_line[rl_point])); + int last_is_ident; + + /* 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. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + /* 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 + the while loop. Without this code, words like `l;' screw up the + function. */ + last_is_ident = isident (rl_line_buffer[rl_point - 1]); + if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) || + (!isident (rl_line_buffer[rl_point]) && last_is_ident)) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + if (rl_point > 0) { - if (isident (the_line[rl_point])) - while (--rl_point >= 0 && isident (the_line[rl_point])); + if (isident (rl_line_buffer[rl_point])) + while (--rl_point >= 0 && isident (rl_line_buffer[rl_point])); else - while (--rl_point >= 0 && !isident (the_line[rl_point]) && - !whitespace (the_line[rl_point])); + while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point])); rl_point++; } } @@ -317,19 +518,23 @@ rl_vi_bword (count) rl_vi_eword (count) int count; { - while (count -- && rl_point < rl_end - 1) + while (count-- && rl_point < rl_end - 1) { - while (++rl_point < rl_end && whitespace (the_line[rl_point])); + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; if (rl_point < rl_end) { - if (isident (the_line[rl_point])) - while (++rl_point < rl_end && isident (the_line[rl_point])); + if (isident (rl_line_buffer[rl_point])) + while (++rl_point < rl_end && isident (rl_line_buffer[rl_point])); else - while (++rl_point < rl_end && !isident (the_line[rl_point]) - && !whitespace (the_line[rl_point])); - rl_point--; + while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point]) + && !whitespace (rl_line_buffer[rl_point])); } + rl_point--; } } @@ -398,35 +603,41 @@ rl_vi_arg_digit (count, c) rl_digit_argument (count, c); } -/* Doesn't take an arg count in vi */ -rl_vi_change_case (ignore1, ignore2) - int ignore1, ignore2; +rl_vi_change_case (count, ignore) + int count, ignore; { char c = 0; - if (uppercase_p (the_line[rl_point])) - c = to_lower (the_line[rl_point]); - else if (lowercase_p (the_line[rl_point])) - c = to_upper (the_line[rl_point]); + /* Don't try this on an empty line. */ + if (rl_point >= rl_end) + return; - /* Vi is kind of strange here. */ - if (c) + while (count-- && rl_point < rl_end) { - rl_begin_undo_group (); - rl_delete (1, c); - rl_insert (1, c); - rl_end_undo_group (); - rl_vi_check (); + 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]); + + /* Vi is kind of strange here. */ + if (c) + { + rl_begin_undo_group (); + rl_delete (1, c); + rl_insert (1, c); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward (1); } - else - rl_forward (1); } rl_vi_put (count, key) int count, key; { - if (!uppercase_p (key)) - rl_forward (1); + if (!uppercase_p (key) && (rl_point + 1 <= rl_end)) + rl_point++; rl_yank (); rl_backward (1); @@ -451,6 +662,9 @@ rl_vi_domove (key, nextkey) int key, *nextkey; { int c, save; + int old_end, added_blank; + + added_blank = 0; rl_mark = rl_point; c = rl_read_key (); @@ -461,10 +675,14 @@ rl_vi_domove (key, nextkey) if (digit (c)) { save = rl_numeric_arg; + rl_numeric_arg = digit_value (c); rl_digit_loop1 (); rl_numeric_arg *= save; + c = rl_read_key (); /* real command */ + *nextkey = c; } else if ((key == 'd' && c == 'd') || + (key == 'y' && c == 'y') || (key == 'c' && c == 'c')) { rl_mark = rl_end; @@ -475,15 +693,41 @@ rl_vi_domove (key, nextkey) return (-1); } + /* Append a blank character temporarily so that the motion routines + work right at the end of the line. */ + old_end = rl_end; + rl_line_buffer[rl_end++] = ' '; /* This looks pretty bogus to me??? */ + rl_line_buffer[rl_end] = '\0'; + added_blank++; + rl_dispatch (c, keymap); + /* Remove the blank that we added. */ + rl_end = old_end; + rl_line_buffer[rl_end] = '\0'; + if (rl_point > rl_end) + rl_point = rl_end - 1; + /* No change in position means the command failed. */ if (rl_mark == rl_point) return (-1); - if ((c == 'w' || c == 'W') && rl_point < rl_end) + /* 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 ((c == 'w' || c == 'W') && (rl_point < rl_end) && + !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. Do the same + thing for dw or dW. */ + if (key == 'c' && (to_upper (c) == 'W')) + { + while (rl_point && whitespace (rl_line_buffer[rl_point])) + rl_point--; + } + if (rl_mark < rl_point) exchange (rl_point, rl_mark); @@ -498,7 +742,7 @@ rl_digit_loop1 () while (1) { - rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg, 0); + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0); key = c = rl_read_key (); if (keymap[c].type == ISFUNC && @@ -507,19 +751,21 @@ rl_digit_loop1 () rl_numeric_arg *= 4; continue; } + c = UNMETA (c); if (numeric (c)) { if (rl_explicit_arg) - rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0'); + rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c); else - rl_numeric_arg = (c - '0'); + rl_numeric_arg = digit_value (c); rl_explicit_arg = 1; } else { rl_clear_message (); rl_stuff_char (key); + break; } } } @@ -538,7 +784,7 @@ rl_vi_delete_to (count, key) return; } - if ((c != '|') && (c != 'h') && rl_mark < rl_end) + if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end) rl_mark++; rl_kill_text (rl_point, rl_mark); @@ -558,7 +804,7 @@ rl_vi_change_to (count, key) return; } - if ((c != '|') && (c != 'h') && rl_mark < rl_end) + if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end) rl_mark++; rl_begin_undo_group (); @@ -581,6 +827,9 @@ rl_vi_yank_to (count, key) return; } + if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end) + rl_mark++; + rl_begin_undo_group (); rl_kill_text (rl_point, rl_mark); rl_end_undo_group (); @@ -590,21 +839,36 @@ rl_vi_yank_to (count, key) rl_vi_delete (count) { - if (rl_point >= rl_end - 1) + int end; + + if (rl_end == 0) { - rl_delete (count, 0); - if (rl_point > 0) - rl_backward (1); + ding (); + return; } - else - rl_delete (count, 0); + + end = rl_point + count; + + if (end >= rl_end) + end = rl_end; + + rl_kill_text (rl_point, end); + + if (rl_point > 0 && rl_point == rl_end) + rl_backward (1); } -/* Turn the current line into a comment in shell history. A ksh function */ +/* Turn the current line into a comment in shell history. + A K*rn shell style function. */ rl_vi_comment () { rl_beg_of_line (); - rl_insert_text (": "); /* # doesn't work in interactive mode */ + + if (rl_vi_comment_begin != (char *)NULL) + rl_insert_text (rl_vi_comment_begin); + else + rl_insert_text (": "); /* Default. */ + rl_redisplay (); rl_newline (1, '\010'); } @@ -618,7 +882,7 @@ rl_back_to_indent (ignore1, ignore2) int ignore1, ignore2; { rl_beg_of_line (); - while (rl_point < rl_end && whitespace (the_line[rl_point])) + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) rl_point++; } @@ -639,70 +903,88 @@ rl_vi_char_search (count, key) dir = (key == ';' ? orig_dir : -orig_dir); else { - target = rl_getc (in_stream); + target = rl_getc (rl_instream); switch (key) - { - case 't': - orig_dir = dir = FTO; - break; - - case 'T': - orig_dir = dir = BTO; - break; - - case 'f': - orig_dir = dir = FFIND; - break; - - case 'F': - orig_dir = dir = BFIND; - break; - } + { + case 't': + orig_dir = dir = FTO; + break; + + case 'T': + orig_dir = dir = BTO; + break; + + case 'f': + orig_dir = dir = FFIND; + break; + + case 'F': + orig_dir = dir = BFIND; + break; + } } pos = rl_point; - if (dir < 0) + while (count--) { - pos--; - do + if (dir < 0) { - if (the_line[pos] == target) + if (pos == 0) { - if (dir == BTO) - rl_point = pos + 1; - else - rl_point = pos; + ding (); return; } - } - while (pos--); - if (pos < 0) - { - ding (); - return; - } - } - else - { /* dir > 0 */ - pos++; - do - { - if (the_line[pos] == target) + pos--; + do { - if (dir == FTO) - rl_point = pos - 1; - else - rl_point = pos; + 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; } } - while (++pos < rl_end); + else + { /* dir > 0 */ + if (pos >= rl_end) + { + ding (); + return; + } - if (pos >= (rl_end - 1)) - ding (); + 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; + } + } } } @@ -712,9 +994,9 @@ rl_vi_match () int count = 1, brack, pos; pos = rl_point; - if ((brack = rl_vi_bracktype (the_line[rl_point])) == 0) + if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) { - while ((brack = rl_vi_bracktype (the_line[rl_point])) == 0 && + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && rl_point < rl_end - 1) rl_forward (1); @@ -734,7 +1016,7 @@ rl_vi_match () { if (--pos >= 0) { - int b = rl_vi_bracktype (the_line[pos]); + int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) @@ -753,7 +1035,7 @@ rl_vi_match () { if (++pos < rl_end) { - int b = rl_vi_bracktype (the_line[pos]); + int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) @@ -785,24 +1067,26 @@ rl_vi_bracktype (c) } } -rl_vi_change_char () +rl_vi_change_char (count, key) + int count, key; { int c; - c = rl_getc (in_stream); + c = rl_getc (rl_instream); - switch (c) - { - case '\033': - case CTRL('C'): - return; + if (c == '\033' || c == CTRL ('C')) + return; - default: + while (count-- && rl_point < rl_end) + { rl_begin_undo_group (); + rl_delete (1, c); rl_insert (1, c); + if (count == 0) + rl_backward (1); + rl_end_undo_group (); - break; } } @@ -818,7 +1102,7 @@ rl_vi_subst (count, key) rl_kill_line (1); } else - rl_delete (1, key); + rl_delete (count, key); rl_vi_insertion_mode (); } @@ -880,21 +1164,33 @@ rl_vi_overstrike_delete (count) } } -rl_vi_replace () +rl_vi_replace (count, key) + int count, key; { int i; vi_replace_count = 0; - vi_replace_map = rl_make_bare_keymap (); + if (!vi_replace_map) + { + vi_replace_map = rl_make_bare_keymap (); - for (i = ' '; i < 127; i++) - vi_replace_map[i].function = rl_vi_overstrike; + for (i = ' '; i < 127; i++) + vi_replace_map[i].function = rl_vi_overstrike; - vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; - vi_replace_map[ESC].function = rl_vi_movement_mode; - vi_replace_map[RETURN].function = rl_newline; - vi_replace_map[NEWLINE].function = rl_newline; + vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; + vi_replace_map[ESC].function = rl_vi_movement_mode; + vi_replace_map[RETURN].function = rl_newline; + vi_replace_map[NEWLINE].function = rl_newline; + + /* If the normal vi insertion keymap has ^H bound to erase, do the + same here. Probably should remove the assignment to RUBOUT up + there, but I don't think it will make a difference in real life. */ + if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC && + vi_insertion_keymap[CTRL ('H')].function == rl_rubout) + vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + + } keymap = vi_replace_map; } @@ -907,12 +1203,12 @@ rl_vi_possible_completions() { int save_pos = rl_point; - if (!index (" ;", the_line[rl_point])) + if (!index (" ;", rl_line_buffer[rl_point])) { - while (!index(" ;", the_line[++rl_point])) + while (!index(" ;", rl_line_buffer[++rl_point])) ; } - else if (the_line[rl_point-1] == ';') + else if (rl_line_buffer[rl_point-1] == ';') { ding (); return (0); @@ -923,3 +1219,5 @@ rl_vi_possible_completions() return (0); } + +#endif /* VI_MODE */ |