1 /* $OpenBSD: vi.c,v 1.25 2016/05/06 13:12:52 schwarze Exp $ */
2 /* $NetBSD: vi.c,v 1.33 2011/02/17 16:44:48 joerg Exp $ */
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Christos Zoulas of Cornell University.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * vi.c: Vi mode commands.
54 static el_action_t
cv_action(EditLine
*, wint_t);
55 static el_action_t
cv_paste(EditLine
*, wint_t);
61 cv_action(EditLine
*el
, wint_t c
)
64 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
65 /* 'cc', 'dd' and (possibly) friends */
66 if (c
!= (wint_t)el
->el_chared
.c_vcmd
.action
)
71 cv_yank(el
, el
->el_line
.buffer
,
72 (int)(el
->el_line
.lastchar
- el
->el_line
.buffer
));
73 el
->el_chared
.c_vcmd
.action
= NOP
;
74 el
->el_chared
.c_vcmd
.pos
= 0;
76 el
->el_line
.lastchar
= el
->el_line
.buffer
;
77 el
->el_line
.cursor
= el
->el_line
.buffer
;
80 el
->el_map
.current
= el
->el_map
.key
;
84 el
->el_chared
.c_vcmd
.pos
= el
->el_line
.cursor
;
85 el
->el_chared
.c_vcmd
.action
= c
;
90 * Paste previous deletion before or after the cursor
93 cv_paste(EditLine
*el
, wint_t c
)
95 c_kill_t
*k
= &el
->el_chared
.c_kill
;
96 size_t len
= (size_t)(k
->last
- k
->buf
);
98 if (k
->buf
== NULL
|| len
== 0)
101 (void) fprintf(el
->el_errfile
, "Paste: \"%.*ls\"\n", (int)len
,
107 if (!c
&& el
->el_line
.cursor
< el
->el_line
.lastchar
)
108 el
->el_line
.cursor
++;
110 c_insert(el
, (int)len
);
111 if (el
->el_line
.cursor
+ len
> el
->el_line
.lastchar
)
113 (void) memcpy(el
->el_line
.cursor
, k
->buf
, len
*
114 sizeof(*el
->el_line
.cursor
));
121 * Vi paste previous deletion to the right of the cursor
124 protected el_action_t
126 vi_paste_next(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
129 return cv_paste(el
, 0);
134 * Vi paste previous deletion to the left of the cursor
137 protected el_action_t
139 vi_paste_prev(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
142 return cv_paste(el
, 1);
146 /* vi_prev_big_word():
147 * Vi move to the previous space delimited word
150 protected el_action_t
152 vi_prev_big_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
155 if (el
->el_line
.cursor
== el
->el_line
.buffer
)
158 el
->el_line
.cursor
= cv_prev_word(el
->el_line
.cursor
,
160 el
->el_state
.argument
,
163 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
172 * Vi move to the previous word
175 protected el_action_t
177 vi_prev_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
180 if (el
->el_line
.cursor
== el
->el_line
.buffer
)
183 el
->el_line
.cursor
= cv_prev_word(el
->el_line
.cursor
,
185 el
->el_state
.argument
,
188 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
196 /* vi_next_big_word():
197 * Vi move to the next space delimited word
200 protected el_action_t
202 vi_next_big_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
205 if (el
->el_line
.cursor
>= el
->el_line
.lastchar
- 1)
208 el
->el_line
.cursor
= cv_next_word(el
, el
->el_line
.cursor
,
209 el
->el_line
.lastchar
, el
->el_state
.argument
, cv__isWord
);
211 if (el
->el_map
.type
== MAP_VI
)
212 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
221 * Vi move to the next word
224 protected el_action_t
226 vi_next_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
229 if (el
->el_line
.cursor
>= el
->el_line
.lastchar
- 1)
232 el
->el_line
.cursor
= cv_next_word(el
, el
->el_line
.cursor
,
233 el
->el_line
.lastchar
, el
->el_state
.argument
, cv__isword
);
235 if (el
->el_map
.type
== MAP_VI
)
236 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
245 * Vi change case of character under the cursor and advance one character
248 protected el_action_t
249 vi_change_case(EditLine
*el
, wint_t c
)
253 if (el
->el_line
.cursor
>= el
->el_line
.lastchar
)
256 for (i
= 0; i
< el
->el_state
.argument
; i
++) {
258 c
= *el
->el_line
.cursor
;
260 *el
->el_line
.cursor
= towlower(c
);
261 else if (iswlower(c
))
262 *el
->el_line
.cursor
= towupper(c
);
264 if (++el
->el_line
.cursor
>= el
->el_line
.lastchar
) {
265 el
->el_line
.cursor
--;
276 * Vi change prefix command
279 protected el_action_t
281 vi_change_meta(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
285 * Delete with insert == change: first we delete and then we leave in
288 return cv_action(el
, DELETE
| INSERT
);
292 /* vi_insert_at_bol():
293 * Vi enter insert mode at the beginning of line
296 protected el_action_t
298 vi_insert_at_bol(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
301 el
->el_line
.cursor
= el
->el_line
.buffer
;
303 el
->el_map
.current
= el
->el_map
.key
;
308 /* vi_replace_char():
309 * Vi replace character under the cursor with the next character typed
312 protected el_action_t
314 vi_replace_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
317 if (el
->el_line
.cursor
>= el
->el_line
.lastchar
)
320 el
->el_map
.current
= el
->el_map
.key
;
321 el
->el_state
.inputmode
= MODE_REPLACE_1
;
327 /* vi_replace_mode():
328 * Vi enter replace mode
331 protected el_action_t
333 vi_replace_mode(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
336 el
->el_map
.current
= el
->el_map
.key
;
337 el
->el_state
.inputmode
= MODE_REPLACE
;
343 /* vi_substitute_char():
344 * Vi replace character under the cursor and enter insert mode
347 protected el_action_t
349 vi_substitute_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
352 c_delafter(el
, el
->el_state
.argument
);
353 el
->el_map
.current
= el
->el_map
.key
;
358 /* vi_substitute_line():
359 * Vi substitute entire line
362 protected el_action_t
364 vi_substitute_line(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
368 cv_yank(el
, el
->el_line
.buffer
,
369 (int)(el
->el_line
.lastchar
- el
->el_line
.buffer
));
370 (void) em_kill_line(el
, 0);
371 el
->el_map
.current
= el
->el_map
.key
;
376 /* vi_change_to_eol():
377 * Vi change to end of line
380 protected el_action_t
382 vi_change_to_eol(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
386 cv_yank(el
, el
->el_line
.cursor
,
387 (int)(el
->el_line
.lastchar
- el
->el_line
.cursor
));
388 (void) ed_kill_line(el
, 0);
389 el
->el_map
.current
= el
->el_map
.key
;
395 * Vi enter insert mode
398 protected el_action_t
400 vi_insert(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
403 el
->el_map
.current
= el
->el_map
.key
;
410 * Vi enter insert mode after the cursor
413 protected el_action_t
415 vi_add(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
419 el
->el_map
.current
= el
->el_map
.key
;
420 if (el
->el_line
.cursor
< el
->el_line
.lastchar
) {
421 el
->el_line
.cursor
++;
422 if (el
->el_line
.cursor
> el
->el_line
.lastchar
)
423 el
->el_line
.cursor
= el
->el_line
.lastchar
;
435 * Vi enter insert mode at end of line
438 protected el_action_t
440 vi_add_at_eol(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
443 el
->el_map
.current
= el
->el_map
.key
;
444 el
->el_line
.cursor
= el
->el_line
.lastchar
;
451 * Vi delete prefix command
454 protected el_action_t
456 vi_delete_meta(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
459 return cv_action(el
, DELETE
);
463 /* vi_end_big_word():
464 * Vi move to the end of the current space delimited word
467 protected el_action_t
469 vi_end_big_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
472 if (el
->el_line
.cursor
== el
->el_line
.lastchar
)
475 el
->el_line
.cursor
= cv__endword(el
->el_line
.cursor
,
476 el
->el_line
.lastchar
, el
->el_state
.argument
, cv__isWord
);
478 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
479 el
->el_line
.cursor
++;
488 * Vi move to the end of the current word
491 protected el_action_t
493 vi_end_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
496 if (el
->el_line
.cursor
== el
->el_line
.lastchar
)
499 el
->el_line
.cursor
= cv__endword(el
->el_line
.cursor
,
500 el
->el_line
.lastchar
, el
->el_state
.argument
, cv__isword
);
502 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
503 el
->el_line
.cursor
++;
512 * Vi undo last change
515 protected el_action_t
517 vi_undo(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
519 c_undo_t un
= el
->el_chared
.c_undo
;
524 /* switch line buffer and undo buffer */
525 el
->el_chared
.c_undo
.buf
= el
->el_line
.buffer
;
526 el
->el_chared
.c_undo
.len
= el
->el_line
.lastchar
- el
->el_line
.buffer
;
527 el
->el_chared
.c_undo
.cursor
=
528 (int)(el
->el_line
.cursor
- el
->el_line
.buffer
);
529 el
->el_line
.limit
= un
.buf
+ (el
->el_line
.limit
- el
->el_line
.buffer
);
530 el
->el_line
.buffer
= un
.buf
;
531 el
->el_line
.cursor
= un
.buf
+ un
.cursor
;
532 el
->el_line
.lastchar
= un
.buf
+ un
.len
;
538 /* vi_command_mode():
539 * Vi enter command mode (use alternative key bindings)
542 protected el_action_t
544 vi_command_mode(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
547 /* [Esc] cancels pending action */
548 el
->el_chared
.c_vcmd
.action
= NOP
;
549 el
->el_chared
.c_vcmd
.pos
= 0;
551 el
->el_state
.doingarg
= 0;
553 el
->el_state
.inputmode
= MODE_INSERT
;
554 el
->el_map
.current
= el
->el_map
.alt
;
556 if (el
->el_line
.cursor
> el
->el_line
.buffer
)
557 el
->el_line
.cursor
--;
564 * Vi move to the beginning of line
567 protected el_action_t
568 vi_zero(EditLine
*el
, wint_t c
)
571 if (el
->el_state
.doingarg
)
572 return ed_argument_digit(el
, c
);
574 el
->el_line
.cursor
= el
->el_line
.buffer
;
575 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
583 /* vi_delete_prev_char():
584 * Vi move to previous character (backspace)
585 * [^H] in insert mode only
587 protected el_action_t
589 vi_delete_prev_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
592 if (el
->el_line
.cursor
<= el
->el_line
.buffer
)
596 el
->el_line
.cursor
--;
602 * Vi list choices for completion or indicate end of file if empty line
605 protected el_action_t
607 vi_list_or_eof(EditLine
*el
, wint_t c
)
610 if (el
->el_line
.cursor
== el
->el_line
.lastchar
) {
611 if (el
->el_line
.cursor
== el
->el_line
.buffer
) {
612 terminal_writec(el
, c
); /* then do a EOF */
616 * Here we could list completions, but it is an
625 *el
->el_line
.lastchar
= '\0'; /* just in case */
626 return CC_LIST_CHOICES
;
629 * Just complain for now.
638 /* vi_kill_line_prev():
639 * Vi cut from beginning of line to cursor
642 protected el_action_t
644 vi_kill_line_prev(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
648 cp
= el
->el_line
.buffer
;
649 kp
= el
->el_chared
.c_kill
.buf
;
650 while (cp
< el
->el_line
.cursor
)
651 *kp
++ = *cp
++; /* copy it */
652 el
->el_chared
.c_kill
.last
= kp
;
653 c_delbefore(el
, (int)(el
->el_line
.cursor
- el
->el_line
.buffer
));
654 el
->el_line
.cursor
= el
->el_line
.buffer
; /* zap! */
660 * Vi search history previous
663 protected el_action_t
665 vi_search_prev(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
668 return cv_search(el
, ED_SEARCH_PREV_HISTORY
);
673 * Vi search history next
676 protected el_action_t
678 vi_search_next(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
681 return cv_search(el
, ED_SEARCH_NEXT_HISTORY
);
685 /* vi_repeat_search_next():
686 * Vi repeat current search in the same search direction
689 protected el_action_t
691 vi_repeat_search_next(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
694 if (el
->el_search
.patlen
== 0)
697 return cv_repeat_srch(el
, el
->el_search
.patdir
);
701 /* vi_repeat_search_prev():
702 * Vi repeat current search in the opposite search direction
706 protected el_action_t
707 vi_repeat_search_prev(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
710 if (el
->el_search
.patlen
== 0)
713 return (cv_repeat_srch(el
,
714 el
->el_search
.patdir
== ED_SEARCH_PREV_HISTORY
?
715 ED_SEARCH_NEXT_HISTORY
: ED_SEARCH_PREV_HISTORY
));
720 * Vi move to the character specified next
723 protected el_action_t
725 vi_next_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
727 return cv_csearch(el
, CHAR_FWD
, -1, el
->el_state
.argument
, 0);
732 * Vi move to the character specified previous
735 protected el_action_t
737 vi_prev_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
739 return cv_csearch(el
, CHAR_BACK
, -1, el
->el_state
.argument
, 0);
743 /* vi_to_next_char():
744 * Vi move up to the character specified next
747 protected el_action_t
749 vi_to_next_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
751 return cv_csearch(el
, CHAR_FWD
, -1, el
->el_state
.argument
, 1);
755 /* vi_to_prev_char():
756 * Vi move up to the character specified previous
759 protected el_action_t
761 vi_to_prev_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
763 return cv_csearch(el
, CHAR_BACK
, -1, el
->el_state
.argument
, 1);
767 /* vi_repeat_next_char():
768 * Vi repeat current character search in the same search direction
771 protected el_action_t
773 vi_repeat_next_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
776 return cv_csearch(el
, el
->el_search
.chadir
, el
->el_search
.chacha
,
777 el
->el_state
.argument
, el
->el_search
.chatflg
);
781 /* vi_repeat_prev_char():
782 * Vi repeat current character search in the opposite search direction
785 protected el_action_t
787 vi_repeat_prev_char(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
790 int dir
= el
->el_search
.chadir
;
792 r
= cv_csearch(el
, -dir
, el
->el_search
.chacha
,
793 el
->el_state
.argument
, el
->el_search
.chatflg
);
794 el
->el_search
.chadir
= dir
;
800 * Vi go to matching () {} or []
803 protected el_action_t
805 vi_match(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
807 const wchar_t match_chars
[] = L
"()[]{}";
809 size_t delta
, i
, count
;
812 *el
->el_line
.lastchar
= '\0'; /* just in case */
814 i
= wcscspn(el
->el_line
.cursor
, match_chars
);
815 o_ch
= el
->el_line
.cursor
[i
];
818 delta
= wcschr(match_chars
, o_ch
) - match_chars
;
819 c_ch
= match_chars
[delta
^ 1];
821 delta
= 1 - (delta
& 1) * 2;
823 for (cp
= &el
->el_line
.cursor
[i
]; count
; ) {
825 if (cp
< el
->el_line
.buffer
|| cp
>= el
->el_line
.lastchar
)
829 else if (*cp
== c_ch
)
833 el
->el_line
.cursor
= cp
;
835 if (el
->el_chared
.c_vcmd
.action
!= NOP
) {
836 /* NB posix says char under cursor should NOT be deleted
837 for -ve delta - this is different to netbsd vi. */
839 el
->el_line
.cursor
++;
847 * Vi undo all changes to line
850 protected el_action_t
852 vi_undo_line(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
860 * Vi go to specified column
862 * NB netbsd vi goes to screen column 'n', posix says nth character
864 protected el_action_t
866 vi_to_column(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
869 el
->el_line
.cursor
= el
->el_line
.buffer
;
870 el
->el_state
.argument
--;
871 return ed_next_char(el
, 0);
875 * Vi yank to end of line
878 protected el_action_t
880 vi_yank_end(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
883 cv_yank(el
, el
->el_line
.cursor
,
884 (int)(el
->el_line
.lastchar
- el
->el_line
.cursor
));
892 protected el_action_t
894 vi_yank(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
897 return cv_action(el
, YANK
);
901 * Vi comment out current command
904 protected el_action_t
906 vi_comment_out(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
909 el
->el_line
.cursor
= el
->el_line
.buffer
;
911 *el
->el_line
.cursor
= '#';
913 return ed_newline(el
, 0);
917 * Vi include shell alias
919 * NB: posix implies that we should enter insert mode, however
920 * this is against historical precedent...
922 #ifdef __weak_reference
923 __weakref_visible
char *my_get_alias_text(const char *)
924 __weak_reference(get_alias_text
);
926 protected el_action_t
928 vi_alias(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
930 #ifdef __weak_reference
934 if (my_get_alias_text
== 0) {
940 if (el_getc(el
, &alias_name
[1]) != 1)
943 alias_text
= my_get_alias_text(alias_name
);
944 if (alias_text
!= NULL
)
945 el_wpush(el
, ct_decode_string(alias_text
, &el
->el_scratch
));
952 /* vi_to_history_line():
953 * Vi go to specified history file line.
956 protected el_action_t
958 vi_to_history_line(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
960 int sv_event_no
= el
->el_history
.eventno
;
964 if (el
->el_history
.eventno
== 0) {
965 (void) wcsncpy(el
->el_history
.buf
, el
->el_line
.buffer
,
967 el
->el_history
.last
= el
->el_history
.buf
+
968 (el
->el_line
.lastchar
- el
->el_line
.buffer
);
971 /* Lack of a 'count' means oldest, not 1 */
972 if (!el
->el_state
.doingarg
) {
973 el
->el_history
.eventno
= 0x7fffffff;
976 /* This is brain dead, all the rest of this code counts
977 * upwards going into the past. Here we need count in the
978 * other direction (to match the output of fc -l).
979 * I could change the world, but this seems to suffice.
981 el
->el_history
.eventno
= 1;
982 if (hist_get(el
) == CC_ERROR
)
984 el
->el_history
.eventno
= 1 + el
->el_history
.ev
.num
985 - el
->el_state
.argument
;
986 if (el
->el_history
.eventno
< 0) {
987 el
->el_history
.eventno
= sv_event_no
;
992 if (rval
== CC_ERROR
)
993 el
->el_history
.eventno
= sv_event_no
;
998 * Vi edit history line with vi
1001 protected el_action_t
1003 vi_histedit(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
1009 char tempfile
[] = "/tmp/histedit.XXXXXXXXXX";
1014 if (el
->el_state
.doingarg
) {
1015 if (vi_to_history_line(el
, 0) == CC_ERROR
)
1019 fd
= mkstemp(tempfile
);
1022 len
= (size_t)(el
->el_line
.lastchar
- el
->el_line
.buffer
);
1023 #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
1024 cp
= malloc(TMP_BUFSIZ
);
1030 line
= reallocarray(NULL
, len
, sizeof(*line
));
1037 wcsncpy(line
, el
->el_line
.buffer
, len
);
1039 wcstombs(cp
, line
, TMP_BUFSIZ
- 1);
1040 cp
[TMP_BUFSIZ
- 1] = '\0';
1054 execlp("vi", "vi", tempfile
, (char *)NULL
);
1058 while (waitpid(pid
, &status
, 0) != pid
)
1060 lseek(fd
, (off_t
)0, SEEK_SET
);
1061 st
= read(fd
, cp
, TMP_BUFSIZ
);
1063 len
= (size_t)(el
->el_line
.lastchar
-
1064 el
->el_line
.buffer
);
1065 len
= mbstowcs(el
->el_line
.buffer
, cp
, len
);
1066 if (len
> 0 && el
->el_line
.buffer
[len
-1] == '\n')
1071 el
->el_line
.cursor
= el
->el_line
.buffer
;
1072 el
->el_line
.lastchar
= el
->el_line
.buffer
+ len
;
1080 /* return CC_REFRESH; */
1081 return ed_newline(el
, 0);
1084 /* vi_history_word():
1085 * Vi append word from previous input line
1087 * Who knows where this one came from!
1088 * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
1090 protected el_action_t
1092 vi_history_word(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
1094 const wchar_t *wp
= HIST_FIRST(el
);
1095 const wchar_t *wep
, *wsp
;
1105 while (iswspace(*wp
))
1110 while (*wp
&& !iswspace(*wp
))
1113 } while ((!el
->el_state
.doingarg
|| --el
->el_state
.argument
> 0)
1116 if (wsp
== NULL
|| (el
->el_state
.doingarg
&& el
->el_state
.argument
!= 0))
1120 len
= (int)(wep
- wsp
);
1121 if (el
->el_line
.cursor
< el
->el_line
.lastchar
)
1122 el
->el_line
.cursor
++;
1123 c_insert(el
, len
+ 1);
1124 cp
= el
->el_line
.cursor
;
1125 lim
= el
->el_line
.limit
;
1128 while (wsp
< wep
&& cp
< lim
)
1130 el
->el_line
.cursor
= cp
;
1132 el
->el_map
.current
= el
->el_map
.key
;
1137 * Vi redo last non-motion command
1140 protected el_action_t
1142 vi_redo(EditLine
*el
, wint_t c
__attribute__((__unused__
)))
1144 c_redo_t
*r
= &el
->el_chared
.c_redo
;
1146 if (!el
->el_state
.doingarg
&& r
->count
) {
1147 el
->el_state
.doingarg
= 1;
1148 el
->el_state
.argument
= r
->count
;
1151 el
->el_chared
.c_vcmd
.pos
= el
->el_line
.cursor
;
1152 el
->el_chared
.c_vcmd
.action
= r
->action
;
1153 if (r
->pos
!= r
->buf
) {
1154 if (r
->pos
+ 1 > r
->lim
)
1156 r
->pos
= r
->lim
- 1;
1158 el_wpush(el
, r
->buf
);
1161 el
->el_state
.thiscmd
= r
->cmd
;
1162 el
->el_state
.thisch
= r
->ch
;
1163 return (*el
->el_map
.func
[r
->cmd
])(el
, r
->ch
);