diff options
author | Chet Ramey <chet.ramey@case.edu> | 2011-11-23 18:44:58 -0500 |
---|---|---|
committer | Chet Ramey <chet.ramey@case.edu> | 2011-11-23 18:44:58 -0500 |
commit | fe34a312c8be645944828402351bd1192972586b (patch) | |
tree | ca2a8dae3e43cc5d8ee1d96b6252255eecd866ff /vi_mode.c | |
parent | 06cd36cdc90634c88636a6d09230c573078ead0e (diff) | |
download | readline-fe34a312c8be645944828402351bd1192972586b.tar.gz |
Readline-2.1 import
Diffstat (limited to 'vi_mode.c')
-rw-r--r-- | vi_mode.c | 491 |
1 files changed, 270 insertions, 221 deletions
@@ -31,6 +31,10 @@ #if defined (VI_MODE) +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <sys/types.h> #if defined (HAVE_STDLIB_H) @@ -50,12 +54,12 @@ #include "readline.h" #include "history.h" -#ifndef digit_p -#define digit_p(c) ((c) >= '0' && (c) <= '9') +#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 @@ -63,22 +67,14 @@ #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; @@ -89,48 +85,64 @@ extern char *rl_prompt; extern char *rl_line_buffer; extern int rl_arg_sign; +extern int _rl_doing_an_undo; +extern int _rl_undo_group_level; + extern void _rl_dispatch (); +extern int _rl_char_search_internal (); extern void rl_extend_line_buffer (); extern int rl_vi_check (); /* Non-zero means enter insertion mode. */ -static int _rl_vi_doing_insert = 0; +static int _rl_vi_doing_insert; -/* 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|"; /* 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 _rl_vi_last_key_before_insert; -static int vi_redoing = 0; +static int vi_redoing; /* Text modification commands. These are the `redoable' commands. */ static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; +/* Arrays for the saved marks. */ +static int vi_mark_chars[27]; + static int rl_digit_loop1 (); 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 () { _rl_vi_last_command = 'i'; @@ -150,15 +162,26 @@ _rl_vi_set_last (key, repeat, sign) /* 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; { @@ -169,13 +192,32 @@ rl_vi_redo (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; { @@ -191,10 +233,11 @@ rl_vi_yank_arg (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 @@ -203,11 +246,11 @@ rl_vi_fetch_history (count, c) 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); @@ -215,6 +258,7 @@ rl_vi_fetch_history (count, c) } /* Search again for the last thing searched for. */ +int rl_vi_search_again (count, key) int count, key; { @@ -232,6 +276,7 @@ rl_vi_search_again (count, key) } /* Do a vi style search. */ +int rl_vi_search (count, key) int count, key; { @@ -253,6 +298,7 @@ rl_vi_search (count, key) } /* Completion, from vi's point of view. */ +int rl_vi_complete (ignore, key) int ignore, key; { @@ -275,22 +321,24 @@ rl_vi_complete (ignore, key) if (key == '*' || key == '\\') { _rl_vi_set_last (key, 1, rl_arg_sign); - rl_vi_insertion_mode (); + rl_vi_insertion_mode (1, key); } return (0); } /* Tilde expansion for vi mode. */ +int rl_vi_tilde_expand (ignore, key) int ignore, key; { rl_tilde_expand (0, key); _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */ - rl_vi_insertion_mode (); + rl_vi_insertion_mode (1, key); return (0); } /* Previous word in vi mode. */ +int rl_vi_prev_word (count, key) int count, key; { @@ -303,7 +351,7 @@ rl_vi_prev_word (count, key) return (0); } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_bWord (count); else rl_vi_bword (count); @@ -312,6 +360,7 @@ rl_vi_prev_word (count, key) } /* Next word in vi mode. */ +int rl_vi_next_word (count, key) int count, key; { @@ -324,7 +373,7 @@ rl_vi_next_word (count, key) return (0); } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_fWord (count); else rl_vi_fword (count); @@ -332,6 +381,7 @@ rl_vi_next_word (count, key) } /* Move to the end of the ?next? word. */ +int rl_vi_end_word (count, key) int count, key; { @@ -341,7 +391,7 @@ rl_vi_end_word (count, key) return -1; } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_eWord (count); else rl_vi_eword (count); @@ -349,6 +399,7 @@ rl_vi_end_word (count, key) } /* Move forward a word the way that 'W' does. */ +int rl_vi_fWord (count) int count; { @@ -365,6 +416,7 @@ rl_vi_fWord (count) return (0); } +int rl_vi_bWord (count) int count; { @@ -388,6 +440,7 @@ rl_vi_bWord (count) return (0); } +int rl_vi_eWord (count) int count; { @@ -417,6 +470,7 @@ rl_vi_eWord (count) return (0); } +int rl_vi_fword (count) int count; { @@ -442,6 +496,7 @@ rl_vi_fword (count) return (0); } +int rl_vi_bword (count) int count; { @@ -480,6 +535,7 @@ rl_vi_bword (count) return (0); } +int rl_vi_eword (count) int count; { @@ -504,32 +560,36 @@ rl_vi_eword (count) return (0); } +int rl_vi_insert_beg (count, key) int count, key; { - rl_beg_of_line (); - rl_vi_insertion_mode (); + rl_beg_of_line (1, key); + rl_vi_insertion_mode (1, key); return (0); } +int rl_vi_append_mode (count, key) int count, key; { if (rl_point < rl_end) rl_point++; - rl_vi_insertion_mode (); + rl_vi_insertion_mode (1, key); return (0); } +int rl_vi_append_eol (count, key) int count, key; { - rl_end_of_line (); - rl_vi_append_mode (); + rl_end_of_line (1, key); + rl_vi_append_mode (1, key); return (0); } /* What to do in the case of C-d. */ +int rl_vi_eof_maybe (count, c) int count, c; { @@ -540,13 +600,33 @@ rl_vi_eof_maybe (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; + + 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 () { @@ -555,38 +635,49 @@ _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; { @@ -598,14 +689,14 @@ rl_vi_change_case (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; } @@ -619,22 +710,24 @@ rl_vi_change_case (count, ignore) 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_backward (1, key); return (0); } +int rl_vi_check () { if (rl_point && rl_point == rl_end) @@ -642,11 +735,12 @@ rl_vi_check () 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); @@ -665,10 +759,10 @@ rl_vi_domove (key, nextkey) 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; c = rl_read_key (); /* real command */ @@ -677,7 +771,7 @@ rl_vi_domove (key, nextkey) 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); } @@ -708,13 +802,13 @@ rl_vi_domove (key, nextkey) /* 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])) @@ -760,12 +854,12 @@ rl_digit_loop1 () } 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 @@ -778,12 +872,13 @@ rl_digit_loop1 () 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); @@ -796,19 +891,20 @@ rl_vi_delete_to (count, key) /* These are the motion commands that do not require adjusting the mark. */ - if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end)) + if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; rl_kill_text (rl_point, rl_mark); 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); @@ -824,29 +920,45 @@ rl_vi_change_to (count, key) /* These are the motion commands that do not require adjusting the mark. c[wW] are handled by special-case code in rl_vi_domove(), and already leave the mark at the correct location. */ - if ((strchr (" l|hwW^0%bB", c) == 0) && (rl_mark < rl_end)) + if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end)) 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 (); + 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)) @@ -869,6 +981,7 @@ rl_vi_yank_to (count, key) return (0); } +int rl_vi_delete (count, key) int count, key; { @@ -888,57 +1001,36 @@ rl_vi_delete (count, key) 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, '\010'); + 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) @@ -966,71 +1058,11 @@ rl_vi_char_search (count, 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; { @@ -1041,7 +1073,7 @@ rl_vi_match (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) { @@ -1111,6 +1143,7 @@ rl_vi_bracktype (c) } } +int rl_vi_change_char (count, key) int count, key; { @@ -1131,37 +1164,51 @@ rl_vi_change_char (count, key) 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 (count, key); + rl_delete_text (rl_point, rl_point+count); rl_end_undo_group (); _rl_vi_set_last (key, count, rl_arg_sign); - rl_begin_undo_group (); - _rl_vi_doing_insert = 1; - rl_vi_insertion_mode (); + 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; { @@ -1191,8 +1238,9 @@ rl_vi_overstrike (count, key) return (0); } -rl_vi_overstrike_delete (count) - int count; +int +rl_vi_overstrike_delete (count, key) + int count, key; { int i, s; @@ -1209,7 +1257,7 @@ rl_vi_overstrike_delete (count) vi_replace_count--; if (rl_point == s) - rl_backward (1); + rl_backward (1, key); } if (vi_replace_count == 0 && _rl_vi_doing_insert) @@ -1221,6 +1269,7 @@ rl_vi_overstrike_delete (count) return (0); } +int rl_vi_replace (count, key) int count, key; { @@ -1232,7 +1281,7 @@ rl_vi_replace (count, key) { vi_replace_map = rl_make_bare_keymap (); - for (i = ' '; i < 127; i++) + for (i = ' '; i < KEYMAP_SIZE; i++) vi_replace_map[i].function = rl_vi_overstrike; vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; @@ -1256,6 +1305,7 @@ rl_vi_replace (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; @@ -1279,51 +1329,50 @@ rl_vi_possible_completions() } #endif -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* 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); + ch = rl_read_key (); + if (_rl_lowercase_p (ch) == 0) + { + 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; - - if (!pointer) - temp = (char *)xmalloc (bytes); - else - temp = (char *)realloc (pointer, bytes); + int ch; - if (!temp) - memory_error_and_abort (); - - return (temp); -} + ch = rl_read_key (); + if (ch == '`') + { + rl_point = rl_mark; + return 0; + } + else if (_rl_lowercase_p (ch) == 0) + { + 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) + { + ding (); + return -1; + } + rl_point = vi_mark_chars[ch]; + return 0; } -#endif /* STATIC_MALLOC */ #endif /* VI_MODE */ |