vi.c revision 1.10 1 /* $NetBSD: vi.c,v 1.10 2002/10/27 21:41:50 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #include "config.h"
40 #if !defined(lint) && !defined(SCCSID)
41 #if 0
42 static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
43 #else
44 __RCSID("$NetBSD: vi.c,v 1.10 2002/10/27 21:41:50 christos Exp $");
45 #endif
46 #endif /* not lint && not SCCSID */
47
48 /*
49 * vi.c: Vi mode commands.
50 */
51 #include "el.h"
52
53 private el_action_t cv_action(EditLine *, int);
54 private el_action_t cv_paste(EditLine *, int);
55
56 /* cv_action():
57 * Handle vi actions.
58 */
59 private el_action_t
60 cv_action(EditLine *el, int c)
61 {
62
63 if (el->el_chared.c_vcmd.action & DELETE) {
64 /* 'dd' and (possibly) friends */
65 el->el_chared.c_vcmd.action = NOP;
66 el->el_chared.c_vcmd.pos = 0;
67
68 cv_undo(el, el->el_line.lastchar - el->el_line.buffer,
69 el->el_line.buffer );
70 el->el_line.lastchar = el->el_line.buffer;
71 el->el_line.cursor = el->el_line.buffer;
72 if (c & INSERT)
73 el->el_map.current = el->el_map.key;
74
75 return (CC_REFRESH);
76 }
77 el->el_chared.c_vcmd.pos = el->el_line.cursor;
78 el->el_chared.c_vcmd.action = c;
79 return (CC_ARGHACK);
80
81 #ifdef notdef
82 /*
83 * I don't think that this is needed. But we keep it for now
84 */
85 else
86 if (el_chared.c_vcmd.action == NOP) {
87 el->el_chared.c_vcmd.pos = el->el_line.cursor;
88 el->el_chared.c_vcmd.action = c;
89 return (CC_ARGHACK);
90 } else {
91 el->el_chared.c_vcmd.action = 0;
92 el->el_chared.c_vcmd.pos = 0;
93 return (CC_ERROR);
94 }
95 #endif
96 }
97
98 /* cv_paste():
99 * Paste previous deletion before or after the cursor
100 */
101 private el_action_t
102 cv_paste(EditLine *el, int c)
103 {
104 char *ptr;
105 c_undo_t *un = &el->el_chared.c_undo;
106
107 #ifdef DEBUG_PASTE
108 (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n",
109 (int)un->paste_len, un->paste ? un->paste : "<null>" );
110 #endif
111 if (!un->paste || !un->paste_len)
112 return (CC_ERROR);
113
114 cv_undo(el, 0, 0);
115
116 if (!c && el->el_line.cursor < el->el_line.lastchar)
117 el->el_line.cursor++;
118 ptr = el->el_line.cursor;
119
120 c_insert(el, (int) un->paste_len);
121 if (el->el_line.cursor + un->paste_len > el->el_line.lastchar)
122 return (CC_ERROR);
123 (void) memcpy(ptr, un->paste, un->paste_len);
124 return (CC_REFRESH);
125 }
126
127
128 /* vi_paste_next():
129 * Vi paste previous deletion to the right of the cursor
130 * [p]
131 */
132 protected el_action_t
133 /*ARGSUSED*/
134 vi_paste_next(EditLine *el, int c)
135 {
136
137 return (cv_paste(el, 0));
138 }
139
140
141 /* vi_paste_prev():
142 * Vi paste previous deletion to the left of the cursor
143 * [P]
144 */
145 protected el_action_t
146 /*ARGSUSED*/
147 vi_paste_prev(EditLine *el, int c)
148 {
149
150 return (cv_paste(el, 1));
151 }
152
153
154 /* vi_prev_big_word():
155 * Vi move to the previous space delimited word
156 * [B]
157 */
158 protected el_action_t
159 /*ARGSUSED*/
160 vi_prev_big_word(EditLine *el, int c)
161 {
162
163 if (el->el_line.cursor == el->el_line.buffer)
164 return (CC_ERROR);
165
166 el->el_line.cursor = cv_prev_word(el->el_line.cursor,
167 el->el_line.buffer,
168 el->el_state.argument,
169 cv__isWord);
170
171 if (el->el_chared.c_vcmd.action & DELETE) {
172 cv_delfini(el);
173 return (CC_REFRESH);
174 }
175 return (CC_CURSOR);
176 }
177
178
179 /* vi_prev_word():
180 * Vi move to the previous word
181 * [b]
182 */
183 protected el_action_t
184 /*ARGSUSED*/
185 vi_prev_word(EditLine *el, int c)
186 {
187
188 if (el->el_line.cursor == el->el_line.buffer)
189 return (CC_ERROR);
190
191 el->el_line.cursor = cv_prev_word(el->el_line.cursor,
192 el->el_line.buffer,
193 el->el_state.argument,
194 cv__isword);
195
196 if (el->el_chared.c_vcmd.action & DELETE) {
197 cv_delfini(el);
198 return (CC_REFRESH);
199 }
200 return (CC_CURSOR);
201 }
202
203
204 /* vi_next_big_word():
205 * Vi move to the next space delimited word
206 * [W]
207 */
208 protected el_action_t
209 /*ARGSUSED*/
210 vi_next_big_word(EditLine *el, int c)
211 {
212
213 if (el->el_line.cursor == el->el_line.lastchar)
214 return (CC_ERROR);
215
216 el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
217 el->el_line.lastchar,
218 el->el_state.argument,
219 cv__isWord);
220
221 if (el->el_map.type == MAP_VI)
222 if (el->el_chared.c_vcmd.action & DELETE) {
223 cv_delfini(el);
224 return (CC_REFRESH);
225 }
226 return (CC_CURSOR);
227 }
228
229
230 /* vi_next_word():
231 * Vi move to the next word
232 * [w]
233 */
234 protected el_action_t
235 /*ARGSUSED*/
236 vi_next_word(EditLine *el, int c)
237 {
238
239 if (el->el_line.cursor == el->el_line.lastchar)
240 return (CC_ERROR);
241
242 el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
243 el->el_line.lastchar,
244 el->el_state.argument,
245 cv__isword);
246
247 if (el->el_map.type == MAP_VI)
248 if (el->el_chared.c_vcmd.action & DELETE) {
249 cv_delfini(el);
250 return (CC_REFRESH);
251 }
252 return (CC_CURSOR);
253 }
254
255
256 /* vi_change_case():
257 * Vi change case of character under the cursor and advance one character
258 * [~]
259 */
260 protected el_action_t
261 vi_change_case(EditLine *el, int c)
262 {
263 int i;
264
265 if (el->el_line.cursor >= el->el_line.lastchar)
266 return (CC_ERROR);
267 cv_undo(el, 0, 0);
268 for (i = 0; i < el->el_state.argument; i++) {
269 if (el->el_line.cursor >= el->el_line.lastchar)
270 break;
271
272 c = *el->el_line.cursor;
273 if (isupper(c))
274 *el->el_line.cursor++ = tolower(c);
275 else if (islower(c))
276 *el->el_line.cursor++ = toupper(c);
277 else
278 el->el_line.cursor++;
279 re_fastaddc(el);
280 }
281 return (CC_NORM);
282 }
283
284
285 /* vi_change_meta():
286 * Vi change prefix command
287 * [c]
288 */
289 protected el_action_t
290 /*ARGSUSED*/
291 vi_change_meta(EditLine *el, int c)
292 {
293
294 /*
295 * Delete with insert == change: first we delete and then we leave in
296 * insert mode.
297 */
298 return (cv_action(el, DELETE | INSERT));
299 }
300
301
302 /* vi_insert_at_bol():
303 * Vi enter insert mode at the beginning of line
304 * [I]
305 */
306 protected el_action_t
307 /*ARGSUSED*/
308 vi_insert_at_bol(EditLine *el, int c)
309 {
310
311 el->el_line.cursor = el->el_line.buffer;
312 cv_undo(el, 0, 0);
313 el->el_map.current = el->el_map.key;
314 return (CC_CURSOR);
315 }
316
317
318 /* vi_replace_char():
319 * Vi replace character under the cursor with the next character typed
320 * [r]
321 */
322 protected el_action_t
323 /*ARGSUSED*/
324 vi_replace_char(EditLine *el, int c)
325 {
326
327 if (el->el_state.argument > el->el_line.lastchar - el->el_line.cursor)
328 return CC_ERROR;
329
330 el->el_map.current = el->el_map.key;
331 el->el_state.inputmode = MODE_REPLACE_1;
332 cv_undo(el, 0, 0);
333 return (CC_ARGHACK);
334 }
335
336
337 /* vi_replace_mode():
338 * Vi enter replace mode
339 * [R]
340 */
341 protected el_action_t
342 /*ARGSUSED*/
343 vi_replace_mode(EditLine *el, int c)
344 {
345
346 el->el_map.current = el->el_map.key;
347 el->el_state.inputmode = MODE_REPLACE;
348 cv_undo(el, 0, 0);
349 return (CC_NORM);
350 }
351
352
353 /* vi_substitute_char():
354 * Vi replace character under the cursor and enter insert mode
355 * [s]
356 */
357 protected el_action_t
358 /*ARGSUSED*/
359 vi_substitute_char(EditLine *el, int c)
360 {
361
362 c_delafter(el, el->el_state.argument);
363 el->el_map.current = el->el_map.key;
364 return (CC_REFRESH);
365 }
366
367
368 /* vi_substitute_line():
369 * Vi substitute entire line
370 * [S]
371 */
372 protected el_action_t
373 /*ARGSUSED*/
374 vi_substitute_line(EditLine *el, int c)
375 {
376
377 cv_undo(el, el->el_line.lastchar - el->el_line.buffer,
378 el->el_line.buffer);
379 (void) em_kill_line(el, 0);
380 el->el_map.current = el->el_map.key;
381 return (CC_REFRESH);
382 }
383
384
385 /* vi_change_to_eol():
386 * Vi change to end of line
387 * [C]
388 */
389 protected el_action_t
390 /*ARGSUSED*/
391 vi_change_to_eol(EditLine *el, int c)
392 {
393
394 cv_undo(el, el->el_line.lastchar - el->el_line.cursor,
395 el->el_line.cursor);
396 (void) ed_kill_line(el, 0);
397 el->el_map.current = el->el_map.key;
398 return (CC_REFRESH);
399 }
400
401
402 /* vi_insert():
403 * Vi enter insert mode
404 * [i]
405 */
406 protected el_action_t
407 /*ARGSUSED*/
408 vi_insert(EditLine *el, int c)
409 {
410
411 el->el_map.current = el->el_map.key;
412 cv_undo(el, 0, 0);
413 return (CC_NORM);
414 }
415
416
417 /* vi_add():
418 * Vi enter insert mode after the cursor
419 * [a]
420 */
421 protected el_action_t
422 /*ARGSUSED*/
423 vi_add(EditLine *el, int c)
424 {
425 int ret;
426
427 el->el_map.current = el->el_map.key;
428 if (el->el_line.cursor < el->el_line.lastchar) {
429 el->el_line.cursor++;
430 if (el->el_line.cursor > el->el_line.lastchar)
431 el->el_line.cursor = el->el_line.lastchar;
432 ret = CC_CURSOR;
433 } else
434 ret = CC_NORM;
435
436 cv_undo(el, 0, 0);
437
438 return (ret);
439 }
440
441
442 /* vi_add_at_eol():
443 * Vi enter insert mode at end of line
444 * [A]
445 */
446 protected el_action_t
447 /*ARGSUSED*/
448 vi_add_at_eol(EditLine *el, int c)
449 {
450
451 el->el_map.current = el->el_map.key;
452 el->el_line.cursor = el->el_line.lastchar;
453 cv_undo(el, 0, 0);
454 return (CC_CURSOR);
455 }
456
457
458 /* vi_delete_meta():
459 * Vi delete prefix command
460 * [d]
461 */
462 protected el_action_t
463 /*ARGSUSED*/
464 vi_delete_meta(EditLine *el, int c)
465 {
466
467 return (cv_action(el, DELETE));
468 }
469
470
471 /* vi_end_big_word():
472 * Vi move to the end of the current space delimited word
473 * [E]
474 */
475 protected el_action_t
476 /*ARGSUSED*/
477 vi_end_big_word(EditLine *el, int c)
478 {
479
480 if (el->el_line.cursor == el->el_line.lastchar)
481 return (CC_ERROR);
482
483 el->el_line.cursor = cv__endword(el->el_line.cursor,
484 el->el_line.lastchar, el->el_state.argument, cv__isWord);
485
486 if (el->el_chared.c_vcmd.action & DELETE) {
487 el->el_line.cursor++;
488 cv_delfini(el);
489 return (CC_REFRESH);
490 }
491 return (CC_CURSOR);
492 }
493
494
495 /* vi_end_word():
496 * Vi move to the end of the current word
497 * [e]
498 */
499 protected el_action_t
500 /*ARGSUSED*/
501 vi_end_word(EditLine *el, int c)
502 {
503
504 if (el->el_line.cursor == el->el_line.lastchar)
505 return (CC_ERROR);
506
507 el->el_line.cursor = cv__endword(el->el_line.cursor,
508 el->el_line.lastchar, el->el_state.argument, cv__isword);
509
510 if (el->el_chared.c_vcmd.action & DELETE) {
511 el->el_line.cursor++;
512 cv_delfini(el);
513 return (CC_REFRESH);
514 }
515 return (CC_CURSOR);
516 }
517
518
519 /* vi_undo():
520 * Vi undo last change
521 * [u]
522 */
523 protected el_action_t
524 /*ARGSUSED*/
525 vi_undo(EditLine *el, int c)
526 {
527 c_undo_t un = el->el_chared.c_undo;
528
529 if (un.len == -1)
530 return CC_ERROR;
531
532 /* switch line buffer and undo buffer */
533 el->el_chared.c_undo.buf = el->el_line.buffer;
534 el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
535 el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer;
536 el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
537 el->el_line.buffer = un.buf;
538 el->el_line.cursor = un.buf + un.cursor;
539 el->el_line.lastchar = un.buf + un.len;
540
541 return (CC_REFRESH);
542 }
543
544
545 /* vi_command_mode():
546 * Vi enter command mode (use alternative key bindings)
547 * [<ESC>]
548 */
549 protected el_action_t
550 /*ARGSUSED*/
551 vi_command_mode(EditLine *el, int c)
552 {
553
554 /* [Esc] cancels pending action */
555 el->el_chared.c_vcmd.action = NOP;
556 el->el_chared.c_vcmd.pos = 0;
557
558 el->el_state.doingarg = 0;
559
560 el->el_state.inputmode = MODE_INSERT;
561 el->el_map.current = el->el_map.alt;
562 #ifdef VI_MOVE
563 if (el->el_line.cursor > el->el_line.buffer)
564 el->el_line.cursor--;
565 #endif
566 return (CC_CURSOR);
567 }
568
569
570 /* vi_zero():
571 * Vi move to the beginning of line
572 * [0]
573 */
574 protected el_action_t
575 vi_zero(EditLine *el, int c)
576 {
577
578 if (el->el_state.doingarg) {
579 if (el->el_state.argument > 1000000)
580 return (CC_ERROR);
581 el->el_state.argument =
582 (el->el_state.argument * 10) + (c - '0');
583 return (CC_ARGHACK);
584 } else {
585 el->el_line.cursor = el->el_line.buffer;
586 if (el->el_chared.c_vcmd.action & DELETE) {
587 cv_delfini(el);
588 return (CC_REFRESH);
589 }
590 return (CC_CURSOR);
591 }
592 }
593
594
595 /* vi_delete_prev_char():
596 * Vi move to previous character (backspace)
597 * [^H] in insert mode only
598 */
599 protected el_action_t
600 /*ARGSUSED*/
601 vi_delete_prev_char(EditLine *el, int c)
602 {
603 char *cp;
604
605 cp = el->el_line.cursor;
606 if (cp <= el->el_line.buffer)
607 return (CC_ERROR);
608
609 /* do the delete here so we dont mess up the undo and paste buffers */
610 el->el_line.cursor = --cp;
611 for (; cp < el->el_line.lastchar; cp++)
612 cp[0] = cp[1];
613 el->el_line.lastchar = cp - 1;
614
615 return (CC_REFRESH);
616 }
617
618
619 /* vi_list_or_eof():
620 * Vi list choices for completion or indicate end of file if empty line
621 * [^D]
622 */
623 protected el_action_t
624 /*ARGSUSED*/
625 vi_list_or_eof(EditLine *el, int c)
626 {
627
628 #ifdef notyet
629 if (el->el_line.cursor == el->el_line.lastchar &&
630 el->el_line.cursor == el->el_line.buffer) {
631 #endif
632 term_overwrite(el, STReof, 4); /* then do a EOF */
633 term__flush();
634 return (CC_EOF);
635 #ifdef notyet
636 } else {
637 re_goto_bottom(el);
638 *el->el_line.lastchar = '\0'; /* just in case */
639 return (CC_LIST_CHOICES);
640 }
641 #endif
642 }
643
644
645 /* vi_kill_line_prev():
646 * Vi cut from beginning of line to cursor
647 * [^U]
648 */
649 protected el_action_t
650 /*ARGSUSED*/
651 vi_kill_line_prev(EditLine *el, int c)
652 {
653 char *kp, *cp;
654
655 cp = el->el_line.buffer;
656 kp = el->el_chared.c_kill.buf;
657 while (cp < el->el_line.cursor)
658 *kp++ = *cp++; /* copy it */
659 el->el_chared.c_kill.last = kp;
660 c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
661 el->el_line.cursor = el->el_line.buffer; /* zap! */
662 return (CC_REFRESH);
663 }
664
665
666 /* vi_search_prev():
667 * Vi search history previous
668 * [?]
669 */
670 protected el_action_t
671 /*ARGSUSED*/
672 vi_search_prev(EditLine *el, int c)
673 {
674
675 return (cv_search(el, ED_SEARCH_PREV_HISTORY));
676 }
677
678
679 /* vi_search_next():
680 * Vi search history next
681 * [/]
682 */
683 protected el_action_t
684 /*ARGSUSED*/
685 vi_search_next(EditLine *el, int c)
686 {
687
688 return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
689 }
690
691
692 /* vi_repeat_search_next():
693 * Vi repeat current search in the same search direction
694 * [n]
695 */
696 protected el_action_t
697 /*ARGSUSED*/
698 vi_repeat_search_next(EditLine *el, int c)
699 {
700
701 if (el->el_search.patlen == 0)
702 return (CC_ERROR);
703 else
704 return (cv_repeat_srch(el, el->el_search.patdir));
705 }
706
707
708 /* vi_repeat_search_prev():
709 * Vi repeat current search in the opposite search direction
710 * [N]
711 */
712 /*ARGSUSED*/
713 protected el_action_t
714 vi_repeat_search_prev(EditLine *el, int c)
715 {
716
717 if (el->el_search.patlen == 0)
718 return (CC_ERROR);
719 else
720 return (cv_repeat_srch(el,
721 el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
722 ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
723 }
724
725
726 /* vi_next_char():
727 * Vi move to the character specified next
728 * [f]
729 */
730 protected el_action_t
731 /*ARGSUSED*/
732 vi_next_char(EditLine *el, int c)
733 {
734 char ch;
735
736 if (el_getc(el, &ch) != 1)
737 return (ed_end_of_file(el, 0));
738
739 el->el_search.chadir = CHAR_FWD;
740 el->el_search.chacha = ch;
741
742 return (cv_csearch_fwd(el, ch, el->el_state.argument, 0));
743
744 }
745
746
747 /* vi_prev_char():
748 * Vi move to the character specified previous
749 * [F]
750 */
751 protected el_action_t
752 /*ARGSUSED*/
753 vi_prev_char(EditLine *el, int c)
754 {
755 char ch;
756
757 if (el_getc(el, &ch) != 1)
758 return (ed_end_of_file(el, 0));
759
760 el->el_search.chadir = CHAR_BACK;
761 el->el_search.chacha = ch;
762
763 return (cv_csearch_back(el, ch, el->el_state.argument, 0));
764 }
765
766
767 /* vi_to_next_char():
768 * Vi move up to the character specified next
769 * [t]
770 */
771 protected el_action_t
772 /*ARGSUSED*/
773 vi_to_next_char(EditLine *el, int c)
774 {
775 char ch;
776
777 if (el_getc(el, &ch) != 1)
778 return (ed_end_of_file(el, 0));
779
780 return (cv_csearch_fwd(el, ch, el->el_state.argument, 1));
781
782 }
783
784
785 /* vi_to_prev_char():
786 * Vi move up to the character specified previous
787 * [T]
788 */
789 protected el_action_t
790 /*ARGSUSED*/
791 vi_to_prev_char(EditLine *el, int c)
792 {
793 char ch;
794
795 if (el_getc(el, &ch) != 1)
796 return (ed_end_of_file(el, 0));
797
798 return (cv_csearch_back(el, ch, el->el_state.argument, 1));
799 }
800
801
802 /* vi_repeat_next_char():
803 * Vi repeat current character search in the same search direction
804 * [;]
805 */
806 protected el_action_t
807 /*ARGSUSED*/
808 vi_repeat_next_char(EditLine *el, int c)
809 {
810
811 if (el->el_search.chacha == 0)
812 return (CC_ERROR);
813
814 return (el->el_search.chadir == CHAR_FWD
815 ? cv_csearch_fwd(el, el->el_search.chacha,
816 el->el_state.argument, 0)
817 : cv_csearch_back(el, el->el_search.chacha,
818 el->el_state.argument, 0));
819 }
820
821
822 /* vi_repeat_prev_char():
823 * Vi repeat current character search in the opposite search direction
824 * [,]
825 */
826 protected el_action_t
827 /*ARGSUSED*/
828 vi_repeat_prev_char(EditLine *el, int c)
829 {
830
831 if (el->el_search.chacha == 0)
832 return (CC_ERROR);
833
834 return el->el_search.chadir == CHAR_BACK ?
835 cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
836 cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
837 }
838