Deleted Added
full compact
vi_mode.c (125665) vi_mode.c (136759)
1/* $FreeBSD: head/contrib/libreadline/vi_mode.c 125665 2004-02-10 20:17:58Z ache $ */
1/* $FreeBSD: head/contrib/libreadline/vi_mode.c 136759 2004-10-21 20:10:14Z peter $ */
2
2/* vi_mode.c -- A vi emulation mode for Bash.
3 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
4
3/* vi_mode.c -- A vi emulation mode for Bash.
4 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
5
5/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
6/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
6
7 This file is part of the GNU Readline Library, a library for
8 reading lines of text with interactive input and history editing.
9
10 The GNU Readline Library is free software; you can redistribute it
11 and/or modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2, or
13 (at your option) any later version.

--- 45 unchanged lines hidden (view full) ---

59
60#include "rlprivate.h"
61#include "xmalloc.h"
62
63#ifndef member
64#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
65#endif
66
7
8 This file is part of the GNU Readline Library, a library for
9 reading lines of text with interactive input and history editing.
10
11 The GNU Readline Library is free software; you can redistribute it
12 and/or modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2, or
14 (at your option) any later version.

--- 45 unchanged lines hidden (view full) ---

60
61#include "rlprivate.h"
62#include "xmalloc.h"
63
64#ifndef member
65#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
66#endif
67
68int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
69
67/* Non-zero means enter insertion mode. */
68static int _rl_vi_doing_insert;
69
70/* Command keys which do movement for xxx_to commands. */
71static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
72
73/* Keymap used for vi replace characters. Created dynamically since
74 rarely used. */

--- 4 unchanged lines hidden (view full) ---

79
80/* If non-zero, we have text inserted after a c[motion] command that put
81 us implicitly into insert mode. Some people want this text to be
82 attached to the command so that it is `redoable' with `.'. */
83static int vi_continued_command;
84static char *vi_insert_buffer;
85static int vi_insert_buffer_size;
86
70/* Non-zero means enter insertion mode. */
71static int _rl_vi_doing_insert;
72
73/* Command keys which do movement for xxx_to commands. */
74static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
75
76/* Keymap used for vi replace characters. Created dynamically since
77 rarely used. */

--- 4 unchanged lines hidden (view full) ---

82
83/* If non-zero, we have text inserted after a c[motion] command that put
84 us implicitly into insert mode. Some people want this text to be
85 attached to the command so that it is `redoable' with `.'. */
86static int vi_continued_command;
87static char *vi_insert_buffer;
88static int vi_insert_buffer_size;
89
87static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
88static int _rl_vi_last_repeat = 1;
89static int _rl_vi_last_arg_sign = 1;
90static int _rl_vi_last_motion;
91#if defined (HANDLE_MULTIBYTE)
92static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
93#else
94static int _rl_vi_last_search_char;
95#endif

--- 35 unchanged lines hidden (view full) ---

131_rl_vi_set_last (key, repeat, sign)
132 int key, repeat, sign;
133{
134 _rl_vi_last_command = key;
135 _rl_vi_last_repeat = repeat;
136 _rl_vi_last_arg_sign = sign;
137}
138
90static int _rl_vi_last_repeat = 1;
91static int _rl_vi_last_arg_sign = 1;
92static int _rl_vi_last_motion;
93#if defined (HANDLE_MULTIBYTE)
94static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
95#else
96static int _rl_vi_last_search_char;
97#endif

--- 35 unchanged lines hidden (view full) ---

133_rl_vi_set_last (key, repeat, sign)
134 int key, repeat, sign;
135{
136 _rl_vi_last_command = key;
137 _rl_vi_last_repeat = repeat;
138 _rl_vi_last_arg_sign = sign;
139}
140
141/* A convenience function that calls _rl_vi_set_last to save the last command
142 information and enters insertion mode. */
143void
144rl_vi_start_inserting (key, repeat, sign)
145 int key, repeat, sign;
146{
147 _rl_vi_set_last (key, repeat, sign);
148 rl_vi_insertion_mode (1, key);
149}
150
139/* Is the command C a VI mode text modification command? */
140int
141_rl_vi_textmod_command (c)
142 int c;
143{
144 return (member (c, vi_textmod));
145}
146

--- 110 unchanged lines hidden (view full) ---

257/* Do a vi style search. */
258int
259rl_vi_search (count, key)
260 int count, key;
261{
262 switch (key)
263 {
264 case '?':
151/* Is the command C a VI mode text modification command? */
152int
153_rl_vi_textmod_command (c)
154 int c;
155{
156 return (member (c, vi_textmod));
157}
158

--- 110 unchanged lines hidden (view full) ---

269/* Do a vi style search. */
270int
271rl_vi_search (count, key)
272 int count, key;
273{
274 switch (key)
275 {
276 case '?':
277 _rl_free_saved_history_line ();
265 rl_noninc_forward_search (count, key);
266 break;
267
268 case '/':
278 rl_noninc_forward_search (count, key);
279 break;
280
281 case '/':
282 _rl_free_saved_history_line ();
269 rl_noninc_reverse_search (count, key);
270 break;
271
272 default:
273 rl_ding ();
274 break;
275 }
276 return (0);

--- 16 unchanged lines hidden (view full) ---

293 else if (key == '=')
294 rl_complete_internal ('?'); /* List possible completions. */
295 else if (key == '\\')
296 rl_complete_internal (TAB); /* Standard Readline completion. */
297 else
298 rl_complete (0, key);
299
300 if (key == '*' || key == '\\')
283 rl_noninc_reverse_search (count, key);
284 break;
285
286 default:
287 rl_ding ();
288 break;
289 }
290 return (0);

--- 16 unchanged lines hidden (view full) ---

307 else if (key == '=')
308 rl_complete_internal ('?'); /* List possible completions. */
309 else if (key == '\\')
310 rl_complete_internal (TAB); /* Standard Readline completion. */
311 else
312 rl_complete (0, key);
313
314 if (key == '*' || key == '\\')
301 {
302 _rl_vi_set_last (key, 1, rl_arg_sign);
303 rl_vi_insertion_mode (1, key);
304 }
315 rl_vi_start_inserting (key, 1, rl_arg_sign);
316
305 return (0);
306}
307
308/* Tilde expansion for vi mode. */
309int
310rl_vi_tilde_expand (ignore, key)
311 int ignore, key;
312{
313 rl_tilde_expand (0, key);
317 return (0);
318}
319
320/* Tilde expansion for vi mode. */
321int
322rl_vi_tilde_expand (ignore, key)
323 int ignore, key;
324{
325 rl_tilde_expand (0, key);
314 _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
315 rl_vi_insertion_mode (1, key);
326 rl_vi_start_inserting (key, 1, rl_arg_sign);
316 return (0);
317}
318
319/* Previous word in vi mode. */
320int
321rl_vi_prev_word (count, key)
322 int count, key;
323{

--- 101 unchanged lines hidden (view full) ---

425{
426 while (count-- && rl_point < (rl_end - 1))
427 {
428 if (!whitespace (rl_line_buffer[rl_point]))
429 rl_point++;
430
431 /* Move to the next non-whitespace character (to the start of the
432 next word). */
327 return (0);
328}
329
330/* Previous word in vi mode. */
331int
332rl_vi_prev_word (count, key)
333 int count, key;
334{

--- 101 unchanged lines hidden (view full) ---

436{
437 while (count-- && rl_point < (rl_end - 1))
438 {
439 if (!whitespace (rl_line_buffer[rl_point]))
440 rl_point++;
441
442 /* Move to the next non-whitespace character (to the start of the
443 next word). */
433 while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
444 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
445 rl_point++;
434
435 if (rl_point && rl_point < rl_end)
436 {
437 /* Skip whitespace. */
438 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
439 rl_point++;
440
441 /* Skip until whitespace. */

--- 194 unchanged lines hidden (view full) ---

636 on absolute indices into the line which may change (though they
637 probably will not). */
638 _rl_vi_doing_insert = 0;
639 _rl_vi_save_insert (rl_undo_list->next);
640 vi_continued_command = 1;
641 }
642 else
643 {
446
447 if (rl_point && rl_point < rl_end)
448 {
449 /* Skip whitespace. */
450 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
451 rl_point++;
452
453 /* Skip until whitespace. */

--- 194 unchanged lines hidden (view full) ---

648 on absolute indices into the line which may change (though they
649 probably will not). */
650 _rl_vi_doing_insert = 0;
651 _rl_vi_save_insert (rl_undo_list->next);
652 vi_continued_command = 1;
653 }
654 else
655 {
644 if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
656 if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
645 _rl_vi_save_insert (rl_undo_list);
646 /* XXX - Other keys probably need to be checked. */
647 else if (_rl_vi_last_key_before_insert == 'C')
648 rl_end_undo_group ();
649 while (_rl_undo_group_level > 0)
650 rl_end_undo_group ();
651 vi_continued_command = 0;
652 }

--- 24 unchanged lines hidden (view full) ---

677/* Change the case of the next COUNT characters. */
678#if defined (HANDLE_MULTIBYTE)
679static int
680_rl_vi_change_mbchar_case (count)
681 int count;
682{
683 wchar_t wc;
684 char mb[MB_LEN_MAX+1];
657 _rl_vi_save_insert (rl_undo_list);
658 /* XXX - Other keys probably need to be checked. */
659 else if (_rl_vi_last_key_before_insert == 'C')
660 rl_end_undo_group ();
661 while (_rl_undo_group_level > 0)
662 rl_end_undo_group ();
663 vi_continued_command = 0;
664 }

--- 24 unchanged lines hidden (view full) ---

689/* Change the case of the next COUNT characters. */
690#if defined (HANDLE_MULTIBYTE)
691static int
692_rl_vi_change_mbchar_case (count)
693 int count;
694{
695 wchar_t wc;
696 char mb[MB_LEN_MAX+1];
685 int mblen;
697 int mblen, p;
686 mbstate_t ps;
687
688 memset (&ps, 0, sizeof (mbstate_t));
689 if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
690 count--;
691 while (count-- && rl_point < rl_end)
692 {
693 mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);

--- 6 unchanged lines hidden (view full) ---

700 /* Just skip over chars neither upper nor lower case */
701 rl_forward_char (1, 0);
702 continue;
703 }
704
705 /* Vi is kind of strange here. */
706 if (wc)
707 {
698 mbstate_t ps;
699
700 memset (&ps, 0, sizeof (mbstate_t));
701 if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
702 count--;
703 while (count-- && rl_point < rl_end)
704 {
705 mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);

--- 6 unchanged lines hidden (view full) ---

712 /* Just skip over chars neither upper nor lower case */
713 rl_forward_char (1, 0);
714 continue;
715 }
716
717 /* Vi is kind of strange here. */
718 if (wc)
719 {
708 mblen = wctomb (mb, wc);
720 p = rl_point;
721 mblen = wcrtomb (mb, wc, &ps);
709 if (mblen >= 0)
710 mb[mblen] = '\0';
711 rl_begin_undo_group ();
722 if (mblen >= 0)
723 mb[mblen] = '\0';
724 rl_begin_undo_group ();
712 rl_delete (1, 0);
725 rl_vi_delete (1, 0);
726 if (rl_point < p) /* Did we retreat at EOL? */
727 rl_point++; /* XXX - should we advance more than 1 for mbchar? */
713 rl_insert_text (mb);
714 rl_end_undo_group ();
715 rl_vi_check ();
716 }
717 else
718 rl_forward_char (1, 0);
719 }
720
721 return 0;
722}
723#endif
724
725int
726rl_vi_change_case (count, ignore)
727 int count, ignore;
728{
728 rl_insert_text (mb);
729 rl_end_undo_group ();
730 rl_vi_check ();
731 }
732 else
733 rl_forward_char (1, 0);
734 }
735
736 return 0;
737}
738#endif
739
740int
741rl_vi_change_case (count, ignore)
742 int count, ignore;
743{
729 char c = 0;
744 int c, p;
730
731 /* Don't try this on an empty line. */
732 if (rl_point >= rl_end)
733 return (0);
734
745
746 /* Don't try this on an empty line. */
747 if (rl_point >= rl_end)
748 return (0);
749
750 c = 0;
735#if defined (HANDLE_MULTIBYTE)
736 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
737 return (_rl_vi_change_mbchar_case (count));
738#endif
739
740 while (count-- && rl_point < rl_end)
741 {
742 if (_rl_uppercase_p (rl_line_buffer[rl_point]))

--- 5 unchanged lines hidden (view full) ---

748 /* Just skip over characters neither upper nor lower case. */
749 rl_forward_char (1, c);
750 continue;
751 }
752
753 /* Vi is kind of strange here. */
754 if (c)
755 {
751#if defined (HANDLE_MULTIBYTE)
752 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
753 return (_rl_vi_change_mbchar_case (count));
754#endif
755
756 while (count-- && rl_point < rl_end)
757 {
758 if (_rl_uppercase_p (rl_line_buffer[rl_point]))

--- 5 unchanged lines hidden (view full) ---

764 /* Just skip over characters neither upper nor lower case. */
765 rl_forward_char (1, c);
766 continue;
767 }
768
769 /* Vi is kind of strange here. */
770 if (c)
771 {
772 p = rl_point;
756 rl_begin_undo_group ();
773 rl_begin_undo_group ();
757 rl_delete (1, c);
774 rl_vi_delete (1, c);
775 if (rl_point < p) /* Did we retreat at EOL? */
776 rl_point++;
758 _rl_insert_char (1, c);
759 rl_end_undo_group ();
760 rl_vi_check ();
761 }
762 else
763 rl_forward_char (1, c);
764 }
765 return (0);
766}
767
768int
769rl_vi_put (count, key)
770 int count, key;
771{
772 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
773 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
774
777 _rl_insert_char (1, c);
778 rl_end_undo_group ();
779 rl_vi_check ();
780 }
781 else
782 rl_forward_char (1, c);
783 }
784 return (0);
785}
786
787int
788rl_vi_put (count, key)
789 int count, key;
790{
791 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
792 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
793
775 rl_yank (1, key);
794 while (count--)
795 rl_yank (1, key);
796
776 rl_backward_char (1, key);
777 return (0);
778}
779
780int
781rl_vi_check ()
782{
783 if (rl_point && rl_point == rl_end)

--- 31 unchanged lines hidden (view full) ---

815 *nextkey = c;
816
817 if (!member (c, vi_motion))
818 {
819 if (_rl_digit_p (c))
820 {
821 save = rl_numeric_arg;
822 rl_numeric_arg = _rl_digit_value (c);
797 rl_backward_char (1, key);
798 return (0);
799}
800
801int
802rl_vi_check ()
803{
804 if (rl_point && rl_point == rl_end)

--- 31 unchanged lines hidden (view full) ---

836 *nextkey = c;
837
838 if (!member (c, vi_motion))
839 {
840 if (_rl_digit_p (c))
841 {
842 save = rl_numeric_arg;
843 rl_numeric_arg = _rl_digit_value (c);
844 rl_explicit_arg = 1;
823 rl_digit_loop1 ();
824 rl_numeric_arg *= save;
825 RL_SETSTATE(RL_STATE_MOREINPUT);
826 c = rl_read_key (); /* real command */
827 RL_UNSETSTATE(RL_STATE_MOREINPUT);
828 *nextkey = c;
829 }
830 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))

--- 182 unchanged lines hidden (view full) ---

1013 }
1014 else
1015 {
1016 rl_begin_undo_group (); /* to make the `u' command work */
1017 rl_kill_text (rl_point, rl_mark);
1018 /* `C' does not save the text inserted for undoing or redoing. */
1019 if (_rl_uppercase_p (key) == 0)
1020 _rl_vi_doing_insert = 1;
845 rl_digit_loop1 ();
846 rl_numeric_arg *= save;
847 RL_SETSTATE(RL_STATE_MOREINPUT);
848 c = rl_read_key (); /* real command */
849 RL_UNSETSTATE(RL_STATE_MOREINPUT);
850 *nextkey = c;
851 }
852 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))

--- 182 unchanged lines hidden (view full) ---

1035 }
1036 else
1037 {
1038 rl_begin_undo_group (); /* to make the `u' command work */
1039 rl_kill_text (rl_point, rl_mark);
1040 /* `C' does not save the text inserted for undoing or redoing. */
1041 if (_rl_uppercase_p (key) == 0)
1042 _rl_vi_doing_insert = 1;
1021 _rl_vi_set_last (key, count, rl_arg_sign);
1022 rl_vi_insertion_mode (1, key);
1043 rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
1023 }
1024
1025 return (0);
1026}
1027
1028int
1029rl_vi_yank_to (count, key)
1030 int count, key;

--- 232 unchanged lines hidden (view full) ---

1263 case '{': return 3;
1264 case '}': return -3;
1265 default: return 0;
1266 }
1267}
1268
1269/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
1270 inserting it in one bunch instead of the loop below (like in
1044 }
1045
1046 return (0);
1047}
1048
1049int
1050rl_vi_yank_to (count, key)
1051 int count, key;

--- 232 unchanged lines hidden (view full) ---

1284 case '{': return 3;
1285 case '}': return -3;
1286 default: return 0;
1287 }
1288}
1289
1290/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
1291 inserting it in one bunch instead of the loop below (like in
1271 rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
1292 rl_vi_char_search or _rl_vi_change_mbchar_case). Set c to mbchar[0]
1272 for test against 033 or ^C. Make sure that _rl_read_mbchar does
1273 this right. */
1274int
1275rl_vi_change_char (count, key)
1276 int count, key;
1277{
1293 for test against 033 or ^C. Make sure that _rl_read_mbchar does
1294 this right. */
1295int
1296rl_vi_change_char (count, key)
1297 int count, key;
1298{
1278 int c;
1299 int c, p;
1279
1280 if (vi_redoing)
1281 c = _rl_vi_last_replacement;
1282 else
1283 {
1284 RL_SETSTATE(RL_STATE_MOREINPUT);
1285 _rl_vi_last_replacement = c = rl_read_key ();
1286 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1287 }
1288
1289 if (c == '\033' || c == CTRL ('C'))
1290 return -1;
1291
1300
1301 if (vi_redoing)
1302 c = _rl_vi_last_replacement;
1303 else
1304 {
1305 RL_SETSTATE(RL_STATE_MOREINPUT);
1306 _rl_vi_last_replacement = c = rl_read_key ();
1307 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1308 }
1309
1310 if (c == '\033' || c == CTRL ('C'))
1311 return -1;
1312
1313 rl_begin_undo_group ();
1292 while (count-- && rl_point < rl_end)
1293 {
1314 while (count-- && rl_point < rl_end)
1315 {
1294 rl_begin_undo_group ();
1295
1296 rl_delete (1, c);
1316 p = rl_point;
1317 rl_vi_delete (1, c);
1297#if defined (HANDLE_MULTIBYTE)
1298 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1318#if defined (HANDLE_MULTIBYTE)
1319 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1299 while (_rl_insert_char (1, c))
1300 {
1301 RL_SETSTATE (RL_STATE_MOREINPUT);
1302 c = rl_read_key ();
1303 RL_UNSETSTATE (RL_STATE_MOREINPUT);
1304 }
1320 {
1321 if (rl_point < p) /* Did we retreat at EOL? */
1322 rl_point++;
1323 while (_rl_insert_char (1, c))
1324 {
1325 RL_SETSTATE (RL_STATE_MOREINPUT);
1326 c = rl_read_key ();
1327 RL_UNSETSTATE (RL_STATE_MOREINPUT);
1328 }
1329 }
1305 else
1306#endif
1330 else
1331#endif
1307 _rl_insert_char (1, c);
1308 if (count == 0)
1309 rl_backward_char (1, c);
1310
1311 rl_end_undo_group ();
1332 {
1333 if (rl_point < p) /* Did we retreat at EOL? */
1334 rl_point++;
1335 _rl_insert_char (1, c);
1336 }
1312 }
1337 }
1338 rl_end_undo_group ();
1339
1313 return (0);
1314}
1315
1316int
1317rl_vi_subst (count, key)
1318 int count, key;
1319{
1320 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1321 if (vi_redoing == 0)
1340 return (0);
1341}
1342
1343int
1344rl_vi_subst (count, key)
1345 int count, key;
1346{
1347 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1348 if (vi_redoing == 0)
1322 rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
1349 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1323
1324 return (rl_vi_change_to (count, 'c'));
1325}
1326
1327int
1328rl_vi_overstrike (count, key)
1329 int count, key;
1330{

--- 159 unchanged lines hidden ---
1350
1351 return (rl_vi_change_to (count, 'c'));
1352}
1353
1354int
1355rl_vi_overstrike (count, key)
1356 int count, key;
1357{

--- 159 unchanged lines hidden ---