* arm-tdep.c (arm_pc_is_thumb): Use obj_section_addr.
[binutils-gdb.git] / readline / vi_mode.c
blobac5fd7446dcf611d5cea7980e63c848c15233214
1 /* vi_mode.c -- A vi emulation mode for Bash.
2 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
4 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
9 The GNU Readline Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
14 The GNU Readline Library is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
25 /* **************************************************************** */
26 /* */
27 /* VI Emulation Mode */
28 /* */
29 /* **************************************************************** */
30 #include "rlconf.h"
32 #if defined (VI_MODE)
34 #if defined (HAVE_CONFIG_H)
35 # include <config.h>
36 #endif
38 #include <sys/types.h>
40 #if defined (HAVE_STDLIB_H)
41 # include <stdlib.h>
42 #else
43 # include "ansi_stdlib.h"
44 #endif /* HAVE_STDLIB_H */
46 #if defined (HAVE_UNISTD_H)
47 # include <unistd.h>
48 #endif
50 #include <stdio.h>
52 /* Some standard library routines. */
53 #include "rldefs.h"
54 #include "rlmbutil.h"
56 #include "readline.h"
57 #include "history.h"
59 #include "rlprivate.h"
60 #include "xmalloc.h"
62 #ifndef member
63 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
64 #endif
66 int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
68 /* Non-zero means enter insertion mode. */
69 static int _rl_vi_doing_insert;
71 /* Command keys which do movement for xxx_to commands. */
72 static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
74 /* Keymap used for vi replace characters. Created dynamically since
75 rarely used. */
76 static Keymap vi_replace_map;
78 /* The number of characters inserted in the last replace operation. */
79 static int vi_replace_count;
81 /* If non-zero, we have text inserted after a c[motion] command that put
82 us implicitly into insert mode. Some people want this text to be
83 attached to the command so that it is `redoable' with `.'. */
84 static int vi_continued_command;
85 static char *vi_insert_buffer;
86 static int vi_insert_buffer_size;
88 static int _rl_vi_last_repeat = 1;
89 static int _rl_vi_last_arg_sign = 1;
90 static int _rl_vi_last_motion;
91 #if defined (HANDLE_MULTIBYTE)
92 static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
93 static int _rl_vi_last_search_mblen;
94 #else
95 static int _rl_vi_last_search_char;
96 #endif
97 static int _rl_vi_last_replacement;
99 static int _rl_vi_last_key_before_insert;
101 static int vi_redoing;
103 /* Text modification commands. These are the `redoable' commands. */
104 static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
106 /* Arrays for the saved marks. */
107 static int vi_mark_chars['z' - 'a' + 1];
109 static void _rl_vi_stuff_insert PARAMS((int));
110 static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
112 static int _rl_vi_arg_dispatch PARAMS((int));
113 static int rl_digit_loop1 PARAMS((void));
115 static int _rl_vi_set_mark PARAMS((void));
116 static int _rl_vi_goto_mark PARAMS((void));
118 static int _rl_vi_callback_getchar PARAMS((char *, int));
120 #if defined (READLINE_CALLBACKS)
121 static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
122 static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
123 static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
124 static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
125 #endif
127 void
128 _rl_vi_initialize_line ()
130 register int i;
132 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
133 vi_mark_chars[i] = -1;
135 RL_UNSETSTATE(RL_STATE_VICMDONCE);
138 void
139 _rl_vi_reset_last ()
141 _rl_vi_last_command = 'i';
142 _rl_vi_last_repeat = 1;
143 _rl_vi_last_arg_sign = 1;
144 _rl_vi_last_motion = 0;
147 void
148 _rl_vi_set_last (key, repeat, sign)
149 int key, repeat, sign;
151 _rl_vi_last_command = key;
152 _rl_vi_last_repeat = repeat;
153 _rl_vi_last_arg_sign = sign;
156 /* A convenience function that calls _rl_vi_set_last to save the last command
157 information and enters insertion mode. */
158 void
159 rl_vi_start_inserting (key, repeat, sign)
160 int key, repeat, sign;
162 _rl_vi_set_last (key, repeat, sign);
163 rl_vi_insertion_mode (1, key);
166 /* Is the command C a VI mode text modification command? */
168 _rl_vi_textmod_command (c)
169 int c;
171 return (member (c, vi_textmod));
174 static void
175 _rl_vi_stuff_insert (count)
176 int count;
178 rl_begin_undo_group ();
179 while (count--)
180 rl_insert_text (vi_insert_buffer);
181 rl_end_undo_group ();
184 /* Bound to `.'. Called from command mode, so we know that we have to
185 redo a text modification command. The default for _rl_vi_last_command
186 puts you back into insert mode. */
188 rl_vi_redo (count, c)
189 int count, c;
191 int r;
193 if (!rl_explicit_arg)
195 rl_numeric_arg = _rl_vi_last_repeat;
196 rl_arg_sign = _rl_vi_last_arg_sign;
199 r = 0;
200 vi_redoing = 1;
201 /* If we're redoing an insert with `i', stuff in the inserted text
202 and do not go into insertion mode. */
203 if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
205 _rl_vi_stuff_insert (count);
206 /* And back up point over the last character inserted. */
207 if (rl_point > 0)
208 rl_point--;
210 else
211 r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
212 vi_redoing = 0;
214 return (r);
217 /* A placeholder for further expansion. */
219 rl_vi_undo (count, key)
220 int count, key;
222 return (rl_undo_command (count, key));
225 /* Yank the nth arg from the previous line into this line at point. */
227 rl_vi_yank_arg (count, key)
228 int count, key;
230 /* Readline thinks that the first word on a line is the 0th, while vi
231 thinks the first word on a line is the 1st. Compensate. */
232 if (rl_explicit_arg)
233 rl_yank_nth_arg (count - 1, 0);
234 else
235 rl_yank_nth_arg ('$', 0);
237 return (0);
240 /* With an argument, move back that many history lines, else move to the
241 beginning of history. */
243 rl_vi_fetch_history (count, c)
244 int count, c;
246 int wanted;
248 /* Giving an argument of n means we want the nth command in the history
249 file. The command number is interpreted the same way that the bash
250 `history' command does it -- that is, giving an argument count of 450
251 to this command would get the command listed as number 450 in the
252 output of `history'. */
253 if (rl_explicit_arg)
255 wanted = history_base + where_history () - count;
256 if (wanted <= 0)
257 rl_beginning_of_history (0, 0);
258 else
259 rl_get_previous_history (wanted, c);
261 else
262 rl_beginning_of_history (count, 0);
263 return (0);
266 /* Search again for the last thing searched for. */
268 rl_vi_search_again (count, key)
269 int count, key;
271 switch (key)
273 case 'n':
274 rl_noninc_reverse_search_again (count, key);
275 break;
277 case 'N':
278 rl_noninc_forward_search_again (count, key);
279 break;
281 return (0);
284 /* Do a vi style search. */
286 rl_vi_search (count, key)
287 int count, key;
289 switch (key)
291 case '?':
292 _rl_free_saved_history_line ();
293 rl_noninc_forward_search (count, key);
294 break;
296 case '/':
297 _rl_free_saved_history_line ();
298 rl_noninc_reverse_search (count, key);
299 break;
301 default:
302 rl_ding ();
303 break;
305 return (0);
308 /* Completion, from vi's point of view. */
310 rl_vi_complete (ignore, key)
311 int ignore, key;
313 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
315 if (!whitespace (rl_line_buffer[rl_point + 1]))
316 rl_vi_end_word (1, 'E');
317 rl_point++;
320 if (key == '*')
321 rl_complete_internal ('*'); /* Expansion and replacement. */
322 else if (key == '=')
323 rl_complete_internal ('?'); /* List possible completions. */
324 else if (key == '\\')
325 rl_complete_internal (TAB); /* Standard Readline completion. */
326 else
327 rl_complete (0, key);
329 if (key == '*' || key == '\\')
330 rl_vi_start_inserting (key, 1, rl_arg_sign);
332 return (0);
335 /* Tilde expansion for vi mode. */
337 rl_vi_tilde_expand (ignore, key)
338 int ignore, key;
340 rl_tilde_expand (0, key);
341 rl_vi_start_inserting (key, 1, rl_arg_sign);
342 return (0);
345 /* Previous word in vi mode. */
347 rl_vi_prev_word (count, key)
348 int count, key;
350 if (count < 0)
351 return (rl_vi_next_word (-count, key));
353 if (rl_point == 0)
355 rl_ding ();
356 return (0);
359 if (_rl_uppercase_p (key))
360 rl_vi_bWord (count, key);
361 else
362 rl_vi_bword (count, key);
364 return (0);
367 /* Next word in vi mode. */
369 rl_vi_next_word (count, key)
370 int count, key;
372 if (count < 0)
373 return (rl_vi_prev_word (-count, key));
375 if (rl_point >= (rl_end - 1))
377 rl_ding ();
378 return (0);
381 if (_rl_uppercase_p (key))
382 rl_vi_fWord (count, key);
383 else
384 rl_vi_fword (count, key);
385 return (0);
388 /* Move to the end of the ?next? word. */
390 rl_vi_end_word (count, key)
391 int count, key;
393 if (count < 0)
395 rl_ding ();
396 return -1;
399 if (_rl_uppercase_p (key))
400 rl_vi_eWord (count, key);
401 else
402 rl_vi_eword (count, key);
403 return (0);
406 /* Move forward a word the way that 'W' does. */
408 rl_vi_fWord (count, ignore)
409 int count, ignore;
411 while (count-- && rl_point < (rl_end - 1))
413 /* Skip until whitespace. */
414 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
415 rl_point++;
417 /* Now skip whitespace. */
418 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
419 rl_point++;
421 return (0);
425 rl_vi_bWord (count, ignore)
426 int count, ignore;
428 while (count-- && rl_point > 0)
430 /* If we are at the start of a word, move back to whitespace so
431 we will go back to the start of the previous word. */
432 if (!whitespace (rl_line_buffer[rl_point]) &&
433 whitespace (rl_line_buffer[rl_point - 1]))
434 rl_point--;
436 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
437 rl_point--;
439 if (rl_point > 0)
441 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
442 rl_point++;
445 return (0);
449 rl_vi_eWord (count, ignore)
450 int count, ignore;
452 while (count-- && rl_point < (rl_end - 1))
454 if (!whitespace (rl_line_buffer[rl_point]))
455 rl_point++;
457 /* Move to the next non-whitespace character (to the start of the
458 next word). */
459 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
460 rl_point++;
462 if (rl_point && rl_point < rl_end)
464 /* Skip whitespace. */
465 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
466 rl_point++;
468 /* Skip until whitespace. */
469 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
470 rl_point++;
472 /* Move back to the last character of the word. */
473 rl_point--;
476 return (0);
480 rl_vi_fword (count, ignore)
481 int count, ignore;
483 while (count-- && rl_point < (rl_end - 1))
485 /* Move to white space (really non-identifer). */
486 if (_rl_isident (rl_line_buffer[rl_point]))
488 while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
489 rl_point++;
491 else /* if (!whitespace (rl_line_buffer[rl_point])) */
493 while (!_rl_isident (rl_line_buffer[rl_point]) &&
494 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
495 rl_point++;
498 /* Move past whitespace. */
499 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
500 rl_point++;
502 return (0);
506 rl_vi_bword (count, ignore)
507 int count, ignore;
509 while (count-- && rl_point > 0)
511 int last_is_ident;
513 /* If we are at the start of a word, move back to whitespace
514 so we will go back to the start of the previous word. */
515 if (!whitespace (rl_line_buffer[rl_point]) &&
516 whitespace (rl_line_buffer[rl_point - 1]))
517 rl_point--;
519 /* If this character and the previous character are `opposite', move
520 back so we don't get messed up by the rl_point++ down there in
521 the while loop. Without this code, words like `l;' screw up the
522 function. */
523 last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
524 if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
525 (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
526 rl_point--;
528 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
529 rl_point--;
531 if (rl_point > 0)
533 if (_rl_isident (rl_line_buffer[rl_point]))
534 while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
535 else
536 while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
537 !whitespace (rl_line_buffer[rl_point]));
538 rl_point++;
541 return (0);
545 rl_vi_eword (count, ignore)
546 int count, ignore;
548 while (count-- && rl_point < rl_end - 1)
550 if (!whitespace (rl_line_buffer[rl_point]))
551 rl_point++;
553 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
554 rl_point++;
556 if (rl_point < rl_end)
558 if (_rl_isident (rl_line_buffer[rl_point]))
559 while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
560 else
561 while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
562 && !whitespace (rl_line_buffer[rl_point]));
564 rl_point--;
566 return (0);
570 rl_vi_insert_beg (count, key)
571 int count, key;
573 rl_beg_of_line (1, key);
574 rl_vi_insertion_mode (1, key);
575 return (0);
579 rl_vi_append_mode (count, key)
580 int count, key;
582 if (rl_point < rl_end)
584 if (MB_CUR_MAX == 1 || rl_byte_oriented)
585 rl_point++;
586 else
588 int point = rl_point;
589 rl_forward_char (1, key);
590 if (point == rl_point)
591 rl_point = rl_end;
594 rl_vi_insertion_mode (1, key);
595 return (0);
599 rl_vi_append_eol (count, key)
600 int count, key;
602 rl_end_of_line (1, key);
603 rl_vi_append_mode (1, key);
604 return (0);
607 /* What to do in the case of C-d. */
609 rl_vi_eof_maybe (count, c)
610 int count, c;
612 return (rl_newline (1, '\n'));
615 /* Insertion mode stuff. */
617 /* Switching from one mode to the other really just involves
618 switching keymaps. */
620 rl_vi_insertion_mode (count, key)
621 int count, key;
623 _rl_keymap = vi_insertion_keymap;
624 _rl_vi_last_key_before_insert = key;
625 return (0);
628 static void
629 _rl_vi_save_insert (up)
630 UNDO_LIST *up;
632 int len, start, end;
634 if (up == 0)
636 if (vi_insert_buffer_size >= 1)
637 vi_insert_buffer[0] = '\0';
638 return;
641 start = up->start;
642 end = up->end;
643 len = end - start + 1;
644 if (len >= vi_insert_buffer_size)
646 vi_insert_buffer_size += (len + 32) - (len % 32);
647 vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
649 strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
650 vi_insert_buffer[len-1] = '\0';
653 void
654 _rl_vi_done_inserting ()
656 if (_rl_vi_doing_insert)
658 /* The `C', `s', and `S' commands set this. */
659 rl_end_undo_group ();
660 /* Now, the text between rl_undo_list->next->start and
661 rl_undo_list->next->end is what was inserted while in insert
662 mode. It gets copied to VI_INSERT_BUFFER because it depends
663 on absolute indices into the line which may change (though they
664 probably will not). */
665 _rl_vi_doing_insert = 0;
666 _rl_vi_save_insert (rl_undo_list->next);
667 vi_continued_command = 1;
669 else
671 if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
672 _rl_vi_save_insert (rl_undo_list);
673 /* XXX - Other keys probably need to be checked. */
674 else if (_rl_vi_last_key_before_insert == 'C')
675 rl_end_undo_group ();
676 while (_rl_undo_group_level > 0)
677 rl_end_undo_group ();
678 vi_continued_command = 0;
683 rl_vi_movement_mode (count, key)
684 int count, key;
686 if (rl_point > 0)
687 rl_backward_char (1, key);
689 _rl_keymap = vi_movement_keymap;
690 _rl_vi_done_inserting ();
692 /* This is how POSIX.2 says `U' should behave -- everything up until the
693 first time you go into command mode should not be undone. */
694 if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
695 rl_free_undo_list ();
697 RL_SETSTATE (RL_STATE_VICMDONCE);
698 return (0);
702 rl_vi_arg_digit (count, c)
703 int count, c;
705 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
706 return (rl_beg_of_line (1, c));
707 else
708 return (rl_digit_argument (count, c));
711 /* Change the case of the next COUNT characters. */
712 #if defined (HANDLE_MULTIBYTE)
713 static int
714 _rl_vi_change_mbchar_case (count)
715 int count;
717 wchar_t wc;
718 char mb[MB_LEN_MAX+1];
719 int mblen, p;
720 mbstate_t ps;
722 memset (&ps, 0, sizeof (mbstate_t));
723 if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
724 count--;
725 while (count-- && rl_point < rl_end)
727 mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
728 if (iswupper (wc))
729 wc = towlower (wc);
730 else if (iswlower (wc))
731 wc = towupper (wc);
732 else
734 /* Just skip over chars neither upper nor lower case */
735 rl_forward_char (1, 0);
736 continue;
739 /* Vi is kind of strange here. */
740 if (wc)
742 p = rl_point;
743 mblen = wcrtomb (mb, wc, &ps);
744 if (mblen >= 0)
745 mb[mblen] = '\0';
746 rl_begin_undo_group ();
747 rl_vi_delete (1, 0);
748 if (rl_point < p) /* Did we retreat at EOL? */
749 rl_point++; /* XXX - should we advance more than 1 for mbchar? */
750 rl_insert_text (mb);
751 rl_end_undo_group ();
752 rl_vi_check ();
754 else
755 rl_forward_char (1, 0);
758 return 0;
760 #endif
763 rl_vi_change_case (count, ignore)
764 int count, ignore;
766 int c, p;
768 /* Don't try this on an empty line. */
769 if (rl_point >= rl_end)
770 return (0);
772 c = 0;
773 #if defined (HANDLE_MULTIBYTE)
774 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
775 return (_rl_vi_change_mbchar_case (count));
776 #endif
778 while (count-- && rl_point < rl_end)
780 if (_rl_uppercase_p (rl_line_buffer[rl_point]))
781 c = _rl_to_lower (rl_line_buffer[rl_point]);
782 else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
783 c = _rl_to_upper (rl_line_buffer[rl_point]);
784 else
786 /* Just skip over characters neither upper nor lower case. */
787 rl_forward_char (1, c);
788 continue;
791 /* Vi is kind of strange here. */
792 if (c)
794 p = rl_point;
795 rl_begin_undo_group ();
796 rl_vi_delete (1, c);
797 if (rl_point < p) /* Did we retreat at EOL? */
798 rl_point++;
799 _rl_insert_char (1, c);
800 rl_end_undo_group ();
801 rl_vi_check ();
803 else
804 rl_forward_char (1, c);
806 return (0);
810 rl_vi_put (count, key)
811 int count, key;
813 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
814 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
816 while (count--)
817 rl_yank (1, key);
819 rl_backward_char (1, key);
820 return (0);
824 rl_vi_check ()
826 if (rl_point && rl_point == rl_end)
828 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
829 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
830 else
831 rl_point--;
833 return (0);
837 rl_vi_column (count, key)
838 int count, key;
840 if (count > rl_end)
841 rl_end_of_line (1, key);
842 else
843 rl_point = count - 1;
844 return (0);
848 rl_vi_domove (key, nextkey)
849 int key, *nextkey;
851 int c, save;
852 int old_end;
854 rl_mark = rl_point;
855 RL_SETSTATE(RL_STATE_MOREINPUT);
856 c = rl_read_key ();
857 RL_UNSETSTATE(RL_STATE_MOREINPUT);
858 *nextkey = c;
860 if (!member (c, vi_motion))
862 if (_rl_digit_p (c))
864 save = rl_numeric_arg;
865 rl_numeric_arg = _rl_digit_value (c);
866 rl_explicit_arg = 1;
867 RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
868 rl_digit_loop1 ();
869 RL_UNSETSTATE (RL_STATE_VIMOTION);
870 rl_numeric_arg *= save;
871 RL_SETSTATE(RL_STATE_MOREINPUT);
872 c = rl_read_key (); /* real command */
873 RL_UNSETSTATE(RL_STATE_MOREINPUT);
874 *nextkey = c;
876 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
878 rl_mark = rl_end;
879 rl_beg_of_line (1, c);
880 _rl_vi_last_motion = c;
881 return (0);
883 else
884 return (-1);
887 _rl_vi_last_motion = c;
889 /* Append a blank character temporarily so that the motion routines
890 work right at the end of the line. */
891 old_end = rl_end;
892 rl_line_buffer[rl_end++] = ' ';
893 rl_line_buffer[rl_end] = '\0';
895 _rl_dispatch (c, _rl_keymap);
897 /* Remove the blank that we added. */
898 rl_end = old_end;
899 rl_line_buffer[rl_end] = '\0';
900 if (rl_point > rl_end)
901 rl_point = rl_end;
903 /* No change in position means the command failed. */
904 if (rl_mark == rl_point)
905 return (-1);
907 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
908 word. If we are not at the end of the line, and we are on a
909 non-whitespace character, move back one (presumably to whitespace). */
910 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
911 !whitespace (rl_line_buffer[rl_point]))
912 rl_point--;
914 /* If cw or cW, back up to the end of a word, so the behaviour of ce
915 or cE is the actual result. Brute-force, no subtlety. */
916 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
918 /* Don't move farther back than where we started. */
919 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
920 rl_point--;
922 /* Posix.2 says that if cw or cW moves the cursor towards the end of
923 the line, the character under the cursor should be deleted. */
924 if (rl_point == rl_mark)
925 rl_point++;
926 else
928 /* Move past the end of the word so that the kill doesn't
929 remove the last letter of the previous word. Only do this
930 if we are not at the end of the line. */
931 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
932 rl_point++;
936 if (rl_mark < rl_point)
937 SWAP (rl_point, rl_mark);
939 return (0);
942 /* Process C as part of the current numeric argument. Return -1 if the
943 argument should be aborted, 0 if we should not read any more chars, and
944 1 if we should continue to read chars. */
945 static int
946 _rl_vi_arg_dispatch (c)
947 int c;
949 int key;
951 key = c;
952 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
954 rl_numeric_arg *= 4;
955 return 1;
958 c = UNMETA (c);
960 if (_rl_digit_p (c))
962 if (rl_explicit_arg)
963 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
964 else
965 rl_numeric_arg = _rl_digit_value (c);
966 rl_explicit_arg = 1;
967 return 1;
969 else
971 rl_clear_message ();
972 rl_stuff_char (key);
973 return 0;
977 /* A simplified loop for vi. Don't dispatch key at end.
978 Don't recognize minus sign?
979 Should this do rl_save_prompt/rl_restore_prompt? */
980 static int
981 rl_digit_loop1 ()
983 int c, r;
985 while (1)
987 if (_rl_arg_overflow ())
988 return 1;
990 c = _rl_arg_getchar ();
992 r = _rl_vi_arg_dispatch (c);
993 if (r <= 0)
994 break;
997 RL_UNSETSTATE(RL_STATE_NUMERICARG);
998 return (0);
1002 rl_vi_delete_to (count, key)
1003 int count, key;
1005 int c;
1007 if (_rl_uppercase_p (key))
1008 rl_stuff_char ('$');
1009 else if (vi_redoing)
1010 rl_stuff_char (_rl_vi_last_motion);
1012 if (rl_vi_domove (key, &c))
1014 rl_ding ();
1015 return -1;
1018 /* These are the motion commands that do not require adjusting the
1019 mark. */
1020 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
1021 rl_mark++;
1023 rl_kill_text (rl_point, rl_mark);
1024 return (0);
1028 rl_vi_change_to (count, key)
1029 int count, key;
1031 int c, start_pos;
1033 if (_rl_uppercase_p (key))
1034 rl_stuff_char ('$');
1035 else if (vi_redoing)
1036 rl_stuff_char (_rl_vi_last_motion);
1038 start_pos = rl_point;
1040 if (rl_vi_domove (key, &c))
1042 rl_ding ();
1043 return -1;
1046 /* These are the motion commands that do not require adjusting the
1047 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1048 and already leave the mark at the correct location. */
1049 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
1050 rl_mark++;
1052 /* The cursor never moves with c[wW]. */
1053 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
1054 rl_point = start_pos;
1056 if (vi_redoing)
1058 if (vi_insert_buffer && *vi_insert_buffer)
1059 rl_begin_undo_group ();
1060 rl_delete_text (rl_point, rl_mark);
1061 if (vi_insert_buffer && *vi_insert_buffer)
1063 rl_insert_text (vi_insert_buffer);
1064 rl_end_undo_group ();
1067 else
1069 rl_begin_undo_group (); /* to make the `u' command work */
1070 rl_kill_text (rl_point, rl_mark);
1071 /* `C' does not save the text inserted for undoing or redoing. */
1072 if (_rl_uppercase_p (key) == 0)
1073 _rl_vi_doing_insert = 1;
1074 rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
1077 return (0);
1081 rl_vi_yank_to (count, key)
1082 int count, key;
1084 int c, save;
1086 save = rl_point;
1087 if (_rl_uppercase_p (key))
1088 rl_stuff_char ('$');
1090 if (rl_vi_domove (key, &c))
1092 rl_ding ();
1093 return -1;
1096 /* These are the motion commands that do not require adjusting the
1097 mark. */
1098 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
1099 rl_mark++;
1101 rl_begin_undo_group ();
1102 rl_kill_text (rl_point, rl_mark);
1103 rl_end_undo_group ();
1104 rl_do_undo ();
1105 rl_point = save;
1107 return (0);
1111 rl_vi_rubout (count, key)
1112 int count, key;
1114 int p, opoint;
1116 if (count < 0)
1117 return (rl_vi_delete (-count, key));
1119 if (rl_point == 0)
1121 rl_ding ();
1122 return -1;
1125 opoint = rl_point;
1126 if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1127 rl_backward_char (count, key);
1128 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1129 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1130 else
1131 rl_point -= count;
1133 if (rl_point < 0)
1134 rl_point = 0;
1136 rl_kill_text (rl_point, opoint);
1138 return (0);
1142 rl_vi_delete (count, key)
1143 int count, key;
1145 int end;
1147 if (count < 0)
1148 return (rl_vi_rubout (-count, key));
1150 if (rl_end == 0)
1152 rl_ding ();
1153 return -1;
1156 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1157 end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1158 else
1159 end = rl_point + count;
1161 if (end >= rl_end)
1162 end = rl_end;
1164 rl_kill_text (rl_point, end);
1166 if (rl_point > 0 && rl_point == rl_end)
1167 rl_backward_char (1, key);
1169 return (0);
1173 rl_vi_back_to_indent (count, key)
1174 int count, key;
1176 rl_beg_of_line (1, key);
1177 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1178 rl_point++;
1179 return (0);
1183 rl_vi_first_print (count, key)
1184 int count, key;
1186 return (rl_vi_back_to_indent (1, key));
1189 static int _rl_cs_dir, _rl_cs_orig_dir;
1191 #if defined (READLINE_CALLBACKS)
1192 static int
1193 _rl_vi_callback_char_search (data)
1194 _rl_callback_generic_arg *data;
1196 #if defined (HANDLE_MULTIBYTE)
1197 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1198 #else
1199 RL_SETSTATE(RL_STATE_MOREINPUT);
1200 _rl_vi_last_search_char = rl_read_key ();
1201 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1202 #endif
1204 _rl_callback_func = 0;
1205 _rl_want_redisplay = 1;
1207 #if defined (HANDLE_MULTIBYTE)
1208 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
1209 #else
1210 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
1211 #endif
1213 #endif
1216 rl_vi_char_search (count, key)
1217 int count, key;
1219 #if defined (HANDLE_MULTIBYTE)
1220 static char *target;
1221 static int tlen;
1222 #else
1223 static char target;
1224 #endif
1226 if (key == ';' || key == ',')
1227 _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
1228 else
1230 switch (key)
1232 case 't':
1233 _rl_cs_orig_dir = _rl_cs_dir = FTO;
1234 break;
1236 case 'T':
1237 _rl_cs_orig_dir = _rl_cs_dir = BTO;
1238 break;
1240 case 'f':
1241 _rl_cs_orig_dir = _rl_cs_dir = FFIND;
1242 break;
1244 case 'F':
1245 _rl_cs_orig_dir = _rl_cs_dir = BFIND;
1246 break;
1249 if (vi_redoing)
1251 /* set target and tlen below */
1253 #if defined (READLINE_CALLBACKS)
1254 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1256 _rl_callback_data = _rl_callback_data_alloc (count);
1257 _rl_callback_data->i1 = _rl_cs_dir;
1258 _rl_callback_func = _rl_vi_callback_char_search;
1259 return (0);
1261 #endif
1262 else
1264 #if defined (HANDLE_MULTIBYTE)
1265 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1266 #else
1267 RL_SETSTATE(RL_STATE_MOREINPUT);
1268 _rl_vi_last_search_char = rl_read_key ();
1269 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1270 #endif
1274 #if defined (HANDLE_MULTIBYTE)
1275 target = _rl_vi_last_search_mbchar;
1276 tlen = _rl_vi_last_search_mblen;
1277 #else
1278 target = _rl_vi_last_search_char;
1279 #endif
1281 #if defined (HANDLE_MULTIBYTE)
1282 return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
1283 #else
1284 return (_rl_char_search_internal (count, _rl_cs_dir, target));
1285 #endif
1288 /* Match brackets */
1290 rl_vi_match (ignore, key)
1291 int ignore, key;
1293 int count = 1, brack, pos, tmp, pre;
1295 pos = rl_point;
1296 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1298 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1300 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1302 pre = rl_point;
1303 rl_forward_char (1, key);
1304 if (pre == rl_point)
1305 break;
1308 else
1309 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1310 rl_point < rl_end - 1)
1311 rl_forward_char (1, key);
1313 if (brack <= 0)
1315 rl_point = pos;
1316 rl_ding ();
1317 return -1;
1321 pos = rl_point;
1323 if (brack < 0)
1325 while (count)
1327 tmp = pos;
1328 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1329 pos--;
1330 else
1332 pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1333 if (tmp == pos)
1334 pos--;
1336 if (pos >= 0)
1338 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1339 if (b == -brack)
1340 count--;
1341 else if (b == brack)
1342 count++;
1344 else
1346 rl_ding ();
1347 return -1;
1351 else
1352 { /* brack > 0 */
1353 while (count)
1355 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1356 pos++;
1357 else
1358 pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
1360 if (pos < rl_end)
1362 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1363 if (b == -brack)
1364 count--;
1365 else if (b == brack)
1366 count++;
1368 else
1370 rl_ding ();
1371 return -1;
1375 rl_point = pos;
1376 return (0);
1380 rl_vi_bracktype (c)
1381 int c;
1383 switch (c)
1385 case '(': return 1;
1386 case ')': return -1;
1387 case '[': return 2;
1388 case ']': return -2;
1389 case '{': return 3;
1390 case '}': return -3;
1391 default: return 0;
1395 static int
1396 _rl_vi_change_char (count, c, mb)
1397 int count, c;
1398 char *mb;
1400 int p;
1402 if (c == '\033' || c == CTRL ('C'))
1403 return -1;
1405 rl_begin_undo_group ();
1406 while (count-- && rl_point < rl_end)
1408 p = rl_point;
1409 rl_vi_delete (1, c);
1410 if (rl_point < p) /* Did we retreat at EOL? */
1411 rl_point++;
1412 #if defined (HANDLE_MULTIBYTE)
1413 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1414 rl_insert_text (mb);
1415 else
1416 #endif
1417 _rl_insert_char (1, c);
1420 /* The cursor shall be left on the last character changed. */
1421 rl_backward_char (1, c);
1423 rl_end_undo_group ();
1425 return (0);
1428 static int
1429 _rl_vi_callback_getchar (mb, mblen)
1430 char *mb;
1431 int mblen;
1433 int c;
1435 RL_SETSTATE(RL_STATE_MOREINPUT);
1436 c = rl_read_key ();
1437 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1439 #if defined (HANDLE_MULTIBYTE)
1440 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1441 c = _rl_read_mbstring (c, mb, mblen);
1442 #endif
1444 return c;
1447 #if defined (READLINE_CALLBACKS)
1448 static int
1449 _rl_vi_callback_change_char (data)
1450 _rl_callback_generic_arg *data;
1452 int c;
1453 char mb[MB_LEN_MAX];
1455 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1457 _rl_callback_func = 0;
1458 _rl_want_redisplay = 1;
1460 return (_rl_vi_change_char (data->count, c, mb));
1462 #endif
1465 rl_vi_change_char (count, key)
1466 int count, key;
1468 int c;
1469 char mb[MB_LEN_MAX];
1471 if (vi_redoing)
1473 c = _rl_vi_last_replacement;
1474 mb[0] = c;
1475 mb[1] = '\0';
1477 #if defined (READLINE_CALLBACKS)
1478 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1480 _rl_callback_data = _rl_callback_data_alloc (count);
1481 _rl_callback_func = _rl_vi_callback_change_char;
1482 return (0);
1484 #endif
1485 else
1486 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1488 return (_rl_vi_change_char (count, c, mb));
1492 rl_vi_subst (count, key)
1493 int count, key;
1495 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1496 if (vi_redoing == 0)
1497 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1499 return (rl_vi_change_to (count, 'c'));
1503 rl_vi_overstrike (count, key)
1504 int count, key;
1506 if (_rl_vi_doing_insert == 0)
1508 _rl_vi_doing_insert = 1;
1509 rl_begin_undo_group ();
1512 if (count > 0)
1514 _rl_overwrite_char (count, key);
1515 vi_replace_count += count;
1518 return (0);
1522 rl_vi_overstrike_delete (count, key)
1523 int count, key;
1525 int i, s;
1527 for (i = 0; i < count; i++)
1529 if (vi_replace_count == 0)
1531 rl_ding ();
1532 break;
1534 s = rl_point;
1536 if (rl_do_undo ())
1537 vi_replace_count--;
1539 if (rl_point == s)
1540 rl_backward_char (1, key);
1543 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1545 rl_end_undo_group ();
1546 rl_do_undo ();
1547 _rl_vi_doing_insert = 0;
1549 return (0);
1553 rl_vi_replace (count, key)
1554 int count, key;
1556 int i;
1558 vi_replace_count = 0;
1560 if (!vi_replace_map)
1562 vi_replace_map = rl_make_bare_keymap ();
1564 for (i = ' '; i < KEYMAP_SIZE; i++)
1565 vi_replace_map[i].function = rl_vi_overstrike;
1567 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1568 vi_replace_map[ESC].function = rl_vi_movement_mode;
1569 vi_replace_map[RETURN].function = rl_newline;
1570 vi_replace_map[NEWLINE].function = rl_newline;
1572 /* If the normal vi insertion keymap has ^H bound to erase, do the
1573 same here. Probably should remove the assignment to RUBOUT up
1574 there, but I don't think it will make a difference in real life. */
1575 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1576 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1577 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1580 _rl_keymap = vi_replace_map;
1581 return (0);
1584 #if 0
1585 /* Try to complete the word we are standing on or the word that ends with
1586 the previous character. A space matches everything. Word delimiters are
1587 space and ;. */
1589 rl_vi_possible_completions()
1591 int save_pos = rl_point;
1593 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1595 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1596 rl_line_buffer[rl_point] != ';')
1597 rl_point++;
1599 else if (rl_line_buffer[rl_point - 1] == ';')
1601 rl_ding ();
1602 return (0);
1605 rl_possible_completions ();
1606 rl_point = save_pos;
1608 return (0);
1610 #endif
1612 /* Functions to save and restore marks. */
1613 static int
1614 _rl_vi_set_mark ()
1616 int ch;
1618 RL_SETSTATE(RL_STATE_MOREINPUT);
1619 ch = rl_read_key ();
1620 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1622 if (ch < 'a' || ch > 'z')
1624 rl_ding ();
1625 return -1;
1627 ch -= 'a';
1628 vi_mark_chars[ch] = rl_point;
1629 return 0;
1632 #if defined (READLINE_CALLBACKS)
1633 static int
1634 _rl_vi_callback_set_mark (data)
1635 _rl_callback_generic_arg *data;
1637 _rl_callback_func = 0;
1638 _rl_want_redisplay = 1;
1640 return (_rl_vi_set_mark ());
1642 #endif
1645 rl_vi_set_mark (count, key)
1646 int count, key;
1648 #if defined (READLINE_CALLBACKS)
1649 if (RL_ISSTATE (RL_STATE_CALLBACK))
1651 _rl_callback_data = 0;
1652 _rl_callback_func = _rl_vi_callback_set_mark;
1653 return (0);
1655 #endif
1657 return (_rl_vi_set_mark ());
1660 static int
1661 _rl_vi_goto_mark ()
1663 int ch;
1665 RL_SETSTATE(RL_STATE_MOREINPUT);
1666 ch = rl_read_key ();
1667 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1669 if (ch == '`')
1671 rl_point = rl_mark;
1672 return 0;
1674 else if (ch < 'a' || ch > 'z')
1676 rl_ding ();
1677 return -1;
1680 ch -= 'a';
1681 if (vi_mark_chars[ch] == -1)
1683 rl_ding ();
1684 return -1;
1686 rl_point = vi_mark_chars[ch];
1687 return 0;
1690 #if defined (READLINE_CALLBACKS)
1691 static int
1692 _rl_vi_callback_goto_mark (data)
1693 _rl_callback_generic_arg *data;
1695 _rl_callback_func = 0;
1696 _rl_want_redisplay = 1;
1698 return (_rl_vi_goto_mark ());
1700 #endif
1703 rl_vi_goto_mark (count, key)
1704 int count, key;
1706 #if defined (READLINE_CALLBACKS)
1707 if (RL_ISSTATE (RL_STATE_CALLBACK))
1709 _rl_callback_data = 0;
1710 _rl_callback_func = _rl_vi_callback_goto_mark;
1711 return (0);
1713 #endif
1715 return (_rl_vi_goto_mark ());
1717 #endif /* VI_MODE */