common.c revision 1.3 1 /* $NetBSD: common.c,v 1.3 1997/01/14 04:17:22 lukem 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 #if !defined(lint) && !defined(SCCSID)
40 #if 0
41 static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
42 #else
43 static char rcsid[] = "$NetBSD: common.c,v 1.3 1997/01/14 04:17:22 lukem Exp $";
44 #endif
45 #endif /* not lint && not SCCSID */
46
47 /*
48 * common.c: Common Editor functions
49 */
50 #include "sys.h"
51 #include "el.h"
52
53 /* ed_end_of_file():
54 * Indicate end of file
55 * [^D]
56 */
57 protected el_action_t
58 /*ARGSUSED*/
59 ed_end_of_file(el, c)
60 EditLine *el;
61 int c;
62 {
63 re_goto_bottom(el);
64 *el->el_line.lastchar = '\0';
65 return CC_EOF;
66 }
67
68
69 /* ed_insert():
70 * Add character to the line
71 * Insert a character [bound to all insert keys]
72 */
73 protected el_action_t
74 ed_insert(el, c)
75 EditLine *el;
76 int c;
77 {
78 int i;
79
80 if (c == '\0')
81 return CC_ERROR;
82
83 if (el->el_line.lastchar + el->el_state.argument >=
84 el->el_line.limit)
85 return CC_ERROR; /* end of buffer space */
86
87 if (el->el_state.argument == 1) {
88 if (el->el_state.inputmode != MODE_INSERT) {
89 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
90 *el->el_line.cursor;
91 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
92 c_delafter(el, 1);
93 }
94
95 c_insert(el, 1);
96
97 *el->el_line.cursor++ = c;
98 el->el_state.doingarg = 0; /* just in case */
99 re_fastaddc(el); /* fast refresh for one char. */
100 }
101 else {
102 if (el->el_state.inputmode != MODE_INSERT) {
103
104 for(i = 0;i < el->el_state.argument; i++)
105 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
106 el->el_line.cursor[i];
107
108 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
109 c_delafter(el, el->el_state.argument);
110 }
111
112 c_insert(el, el->el_state.argument);
113
114 while (el->el_state.argument--)
115 *el->el_line.cursor++ = c;
116 re_refresh(el);
117 }
118
119 if (el->el_state.inputmode == MODE_REPLACE_1)
120 (void) vi_command_mode(el, 0);
121
122 return CC_NORM;
123 }
124
125
126 /* ed_delete_prev_word():
127 * Delete from beginning of current word to cursor
128 * [M-^?] [^W]
129 */
130 protected el_action_t
131 /*ARGSUSED*/
132 ed_delete_prev_word(el, c)
133 EditLine *el;
134 int c;
135 {
136 char *cp, *p, *kp;
137
138 if (el->el_line.cursor == el->el_line.buffer)
139 return CC_ERROR;
140
141 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
142 el->el_state.argument, ce__isword);
143
144 for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
145 *kp++ = *p;
146 el->el_chared.c_kill.last = kp;
147
148 c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
149 el->el_line.cursor = cp;
150 if (el->el_line.cursor < el->el_line.buffer)
151 el->el_line.cursor = el->el_line.buffer; /* bounds check */
152 return CC_REFRESH;
153 }
154
155
156 /* ed_delete_next_char():
157 * Delete character under cursor
158 * [^D] [x]
159 */
160 protected el_action_t
161 /*ARGSUSED*/
162 ed_delete_next_char(el, c)
163 EditLine *el;
164 int c;
165 {
166 #ifdef notdef /* XXX */
167 #define EL el->el_line
168 fprintf(stderr, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
169 EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, EL.lastchar, EL.limit, EL.limit);
170 #endif
171 if (el->el_line.cursor == el->el_line.lastchar) {/* if I'm at the end */
172 if (el->el_map.type == MAP_VI) {
173 if (el->el_line.cursor == el->el_line.buffer) {
174 /* if I'm also at the beginning */
175 #ifdef KSHVI
176 return CC_ERROR;
177 #else
178 term_overwrite(el, STReof, 4);/* then do a EOF */
179 term__flush();
180 return CC_EOF;
181 #endif
182 }
183 else {
184 #ifdef KSHVI
185 el->el_line.cursor--;
186 #else
187 return CC_ERROR;
188 #endif
189 }
190 }
191 else {
192 if (el->el_line.cursor != el->el_line.buffer)
193 el->el_line.cursor--;
194 else
195 return CC_ERROR;
196 }
197 }
198 c_delafter(el, el->el_state.argument); /* delete after dot */
199 if (el->el_line.cursor >= el->el_line.lastchar && el->el_line.cursor > el->el_line.buffer)
200 el->el_line.cursor = el->el_line.lastchar - 1; /* bounds check */
201 return CC_REFRESH;
202 }
203
204
205 /* ed_kill_line():
206 * Cut to the end of line
207 * [^K] [^K]
208 */
209 protected el_action_t
210 /*ARGSUSED*/
211 ed_kill_line(el, c)
212 EditLine *el;
213 int c;
214 {
215 char *kp, *cp;
216
217 cp = el->el_line.cursor;
218 kp = el->el_chared.c_kill.buf;
219 while (cp < el->el_line.lastchar)
220 *kp++ = *cp++; /* copy it */
221 el->el_chared.c_kill.last = kp;
222 el->el_line.lastchar = el->el_line.cursor; /* zap! -- delete to end */
223 return CC_REFRESH;
224 }
225
226
227 /* ed_move_to_end():
228 * Move cursor to the end of line
229 * [^E] [^E]
230 */
231 protected el_action_t
232 /*ARGSUSED*/
233 ed_move_to_end(el, c)
234 EditLine *el;
235 int c;
236 {
237 el->el_line.cursor = el->el_line.lastchar;
238 if (el->el_map.type == MAP_VI) {
239 #ifdef VI_MOVE
240 el->el_line.cursor--;
241 #endif
242 if (el->el_chared.c_vcmd.action & DELETE) {
243 cv_delfini(el);
244 return CC_REFRESH;
245 }
246 }
247 return CC_CURSOR;
248 }
249
250
251 /* ed_move_to_beg():
252 * Move cursor to the beginning of line
253 * [^A] [^A]
254 */
255 protected el_action_t
256 /*ARGSUSED*/
257 ed_move_to_beg(el, c)
258 EditLine *el;
259 int c;
260 {
261 el->el_line.cursor = el->el_line.buffer;
262
263 if (el->el_map.type == MAP_VI) {
264 /* We want FIRST non space character */
265 while (isspace(*el->el_line.cursor))
266 el->el_line.cursor++;
267 if (el->el_chared.c_vcmd.action & DELETE) {
268 cv_delfini(el);
269 return CC_REFRESH;
270 }
271 }
272
273 return CC_CURSOR;
274 }
275
276
277 /* ed_transpose_chars():
278 * Exchange the character to the left of the cursor with the one under it
279 * [^T] [^T]
280 */
281 protected el_action_t
282 ed_transpose_chars(el, c)
283 EditLine *el;
284 int c;
285 {
286 if (el->el_line.cursor < el->el_line.lastchar) {
287 if (el->el_line.lastchar <= &el->el_line.buffer[1])
288 return CC_ERROR;
289 else
290 el->el_line.cursor++;
291 }
292 if (el->el_line.cursor > &el->el_line.buffer[1]) {
293 /* must have at least two chars entered */
294 c = el->el_line.cursor[-2];
295 el->el_line.cursor[-2] = el->el_line.cursor[-1];
296 el->el_line.cursor[-1] = c;
297 return CC_REFRESH;
298 }
299 else
300 return CC_ERROR;
301 }
302
303
304 /* ed_next_char():
305 * Move to the right one character
306 * [^F] [^F]
307 */
308 protected el_action_t
309 /*ARGSUSED*/
310 ed_next_char(el, c)
311 EditLine *el;
312 int c;
313 {
314 if (el->el_line.cursor >= el->el_line.lastchar)
315 return CC_ERROR;
316
317 el->el_line.cursor += el->el_state.argument;
318 if (el->el_line.cursor > el->el_line.lastchar)
319 el->el_line.cursor = el->el_line.lastchar;
320
321 if (el->el_map.type == MAP_VI)
322 if (el->el_chared.c_vcmd.action & DELETE) {
323 cv_delfini(el);
324 return CC_REFRESH;
325 }
326
327 return CC_CURSOR;
328 }
329
330
331 /* ed_prev_word():
332 * Move to the beginning of the current word
333 * [M-b] [b]
334 */
335 protected el_action_t
336 /*ARGSUSED*/
337 ed_prev_word(el, c)
338 EditLine *el;
339 int c;
340 {
341 if (el->el_line.cursor == el->el_line.buffer)
342 return CC_ERROR;
343
344 el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer,
345 el->el_state.argument,
346 ce__isword);
347
348 if (el->el_map.type == MAP_VI)
349 if (el->el_chared.c_vcmd.action & DELETE) {
350 cv_delfini(el);
351 return CC_REFRESH;
352 }
353
354 return CC_CURSOR;
355 }
356
357
358 /* ed_prev_char():
359 * Move to the left one character
360 * [^B] [^B]
361 */
362 protected el_action_t
363 /*ARGSUSED*/
364 ed_prev_char(el, c)
365 EditLine *el;
366 int c;
367 {
368 if (el->el_line.cursor > el->el_line.buffer) {
369 el->el_line.cursor -= el->el_state.argument;
370 if (el->el_line.cursor < el->el_line.buffer)
371 el->el_line.cursor = el->el_line.buffer;
372
373 if (el->el_map.type == MAP_VI)
374 if (el->el_chared.c_vcmd.action & DELETE) {
375 cv_delfini(el);
376 return CC_REFRESH;
377 }
378
379 return CC_CURSOR;
380 }
381 else
382 return CC_ERROR;
383 }
384
385
386 /* ed_quoted_insert():
387 * Add the next character typed verbatim
388 * [^V] [^V]
389 */
390 protected el_action_t
391 ed_quoted_insert(el, c)
392 EditLine *el;
393 int c;
394 {
395 int num;
396 char tc;
397
398 tty_quotemode(el);
399 num = el_getc(el, &tc);
400 c = (unsigned char) tc;
401 tty_noquotemode(el);
402 if (num == 1)
403 return ed_insert(el, c);
404 else
405 return ed_end_of_file(el, 0);
406 }
407
408
409 /* ed_digit():
410 * Adds to argument or enters a digit
411 */
412 protected el_action_t
413 ed_digit(el, c)
414 EditLine *el;
415 int c;
416 {
417 if (!isdigit(c))
418 return CC_ERROR;
419
420 if (el->el_state.doingarg) {
421 /* if doing an arg, add this in... */
422 if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
423 el->el_state.argument = c - '0';
424 else {
425 if (el->el_state.argument > 1000000)
426 return CC_ERROR;
427 el->el_state.argument =
428 (el->el_state.argument * 10) + (c - '0');
429 }
430 return CC_ARGHACK;
431 }
432 else {
433 if (el->el_line.lastchar + 1 >= el->el_line.limit)
434 return CC_ERROR;
435
436 if (el->el_state.inputmode != MODE_INSERT) {
437 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
438 *el->el_line.cursor;
439 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
440 c_delafter(el, 1);
441 }
442 c_insert(el, 1);
443 *el->el_line.cursor++ = c;
444 el->el_state.doingarg = 0;
445 re_fastaddc(el);
446 }
447 return CC_NORM;
448 }
449
450
451 /* ed_argument_digit():
452 * Digit that starts argument
453 * For ESC-n
454 */
455 protected el_action_t
456 ed_argument_digit(el, c)
457 EditLine *el;
458 register int c;
459 {
460 if (!isdigit(c))
461 return CC_ERROR;
462
463 if (el->el_state.doingarg) {
464 if (el->el_state.argument > 1000000)
465 return CC_ERROR;
466 el->el_state.argument = (el->el_state.argument * 10) + (c - '0');
467 }
468 else { /* else starting an argument */
469 el->el_state.argument = c - '0';
470 el->el_state.doingarg = 1;
471 }
472 return CC_ARGHACK;
473 }
474
475
476 /* ed_unassigned():
477 * Indicates unbound character
478 * Bound to keys that are not assigned
479 */
480 protected el_action_t
481 /*ARGSUSED*/
482 ed_unassigned(el, c)
483 EditLine *el;
484 int c;
485 {
486 term_beep(el);
487 term__flush();
488 return CC_NORM;
489 }
490
491
492 /**
493 ** TTY key handling.
494 **/
495
496 /* ed_tty_sigint():
497 * Tty interrupt character
498 * [^C]
499 */
500 protected el_action_t
501 /*ARGSUSED*/
502 ed_tty_sigint(el, c)
503 EditLine *el;
504 int c;
505 {
506 return CC_NORM;
507 }
508
509
510 /* ed_tty_dsusp():
511 * Tty delayed suspend character
512 * [^Y]
513 */
514 protected el_action_t
515 /*ARGSUSED*/
516 ed_tty_dsusp(el, c)
517 EditLine *el;
518 int c;
519 {
520 return CC_NORM;
521 }
522
523
524 /* ed_tty_flush_output():
525 * Tty flush output characters
526 * [^O]
527 */
528 protected el_action_t
529 /*ARGSUSED*/
530 ed_tty_flush_output(el, c)
531 EditLine *el;
532 int c;
533 {
534 return CC_NORM;
535 }
536
537
538 /* ed_tty_sigquit():
539 * Tty quit character
540 * [^\]
541 */
542 protected el_action_t
543 /*ARGSUSED*/
544 ed_tty_sigquit(el, c)
545 EditLine *el;
546 int c;
547 {
548 return CC_NORM;
549 }
550
551
552 /* ed_tty_sigtstp():
553 * Tty suspend character
554 * [^Z]
555 */
556 protected el_action_t
557 /*ARGSUSED*/
558 ed_tty_sigtstp(el, c)
559 EditLine *el;
560 int c;
561 {
562 return CC_NORM;
563 }
564
565
566 /* ed_tty_stop_output():
567 * Tty disallow output characters
568 * [^S]
569 */
570 protected el_action_t
571 /*ARGSUSED*/
572 ed_tty_stop_output(el, c)
573 EditLine *el;
574 int c;
575 {
576 return CC_NORM;
577 }
578
579
580 /* ed_tty_start_output():
581 * Tty allow output characters
582 * [^Q]
583 */
584 protected el_action_t
585 /*ARGSUSED*/
586 ed_tty_start_output(el, c)
587 EditLine *el;
588 int c;
589 {
590 return CC_NORM;
591 }
592
593
594 /* ed_newline():
595 * Execute command
596 * [^J]
597 */
598 protected el_action_t
599 /*ARGSUSED*/
600 ed_newline(el, c)
601 EditLine *el;
602 int c;
603 {
604 re_goto_bottom(el);
605 *el->el_line.lastchar++ = '\n';
606 *el->el_line.lastchar = '\0';
607 if (el->el_map.type == MAP_VI)
608 el->el_chared.c_vcmd.ins = el->el_line.buffer;
609 return CC_NEWLINE;
610 }
611
612
613 /* ed_delete_prev_char():
614 * Delete the character to the left of the cursor
615 * [^?]
616 */
617 protected el_action_t
618 /*ARGSUSED*/
619 ed_delete_prev_char(el, c)
620 EditLine *el;
621 int c;
622 {
623 if (el->el_line.cursor <= el->el_line.buffer)
624 return CC_ERROR;
625
626 c_delbefore(el, el->el_state.argument);
627 el->el_line.cursor -= el->el_state.argument;
628 if (el->el_line.cursor < el->el_line.buffer)
629 el->el_line.cursor = el->el_line.buffer;
630 return CC_REFRESH;
631 }
632
633
634 /* ed_clear_screen():
635 * Clear screen leaving current line at the top
636 * [^L]
637 */
638 protected el_action_t
639 /*ARGSUSED*/
640 ed_clear_screen(el, c)
641 EditLine *el;
642 int c;
643 {
644 term_clear_screen(el); /* clear the whole real screen */
645 re_clear_display(el); /* reset everything */
646 return CC_REFRESH;
647 }
648
649
650 /* ed_redisplay():
651 * Redisplay everything
652 * ^R
653 */
654 protected el_action_t
655 /*ARGSUSED*/
656 ed_redisplay(el, c)
657 EditLine *el;
658 int c;
659 {
660 return CC_REDISPLAY;
661 }
662
663
664 /* ed_start_over():
665 * Erase current line and start from scratch
666 * [^G]
667 */
668 protected el_action_t
669 /*ARGSUSED*/
670 ed_start_over(el, c)
671 EditLine *el;
672 int c;
673 {
674 ch_reset(el);
675 return CC_REFRESH;
676 }
677
678
679 /* ed_sequence_lead_in():
680 * First character in a bound sequence
681 * Placeholder for external keys
682 */
683 protected el_action_t
684 /*ARGSUSED*/
685 ed_sequence_lead_in(el, c)
686 EditLine *el;
687 int c;
688 {
689 return CC_NORM;
690 }
691
692
693 /* ed_prev_history():
694 * Move to the previous history line
695 * [^P] [k]
696 */
697 protected el_action_t
698 /*ARGSUSED*/
699 ed_prev_history(el, c)
700 EditLine *el;
701 int c;
702 {
703 char beep = 0;
704
705 el->el_chared.c_undo.action = NOP;
706 *el->el_line.lastchar = '\0'; /* just in case */
707
708 if (el->el_history.eventno == 0) { /* save the current buffer away */
709 (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
710 el->el_history.last = el->el_history.buf +
711 (el->el_line.lastchar - el->el_line.buffer);
712 }
713
714 el->el_history.eventno += el->el_state.argument;
715
716 if (hist_get(el) == CC_ERROR) {
717 beep = 1;
718 /* el->el_history.eventno was fixed by first call */
719 (void) hist_get(el);
720 }
721
722 re_refresh(el);
723 if (beep)
724 return CC_ERROR;
725 else
726 return CC_NORM; /* was CC_UP_HIST */
727 }
728
729
730 /* ed_next_history():
731 * Move to the next history line
732 * [^N] [j]
733 */
734 protected el_action_t
735 /*ARGSUSED*/
736 ed_next_history(el, c)
737 EditLine *el;
738 int c;
739 {
740 el->el_chared.c_undo.action = NOP;
741 *el->el_line.lastchar = '\0'; /* just in case */
742
743 el->el_history.eventno -= el->el_state.argument;
744
745 if (el->el_history.eventno < 0) {
746 el->el_history.eventno = 0;
747 return CC_ERROR; /* make it beep */
748 }
749
750 return hist_get(el);
751 }
752
753
754 /* ed_search_prev_history():
755 * Search previous in history for a line matching the current
756 * next search history [M-P] [K]
757 */
758 protected el_action_t
759 /*ARGSUSED*/
760 ed_search_prev_history(el, c)
761 EditLine *el;
762 int c;
763 {
764 const char *hp;
765 int h;
766 bool_t found = 0;
767
768 el->el_chared.c_vcmd.action = NOP;
769 el->el_chared.c_undo.action = NOP;
770 *el->el_line.lastchar = '\0'; /* just in case */
771 if (el->el_history.eventno < 0) {
772 #ifdef DEBUG_EDIT
773 (void) fprintf(el->el_errfile, "e_prev_search_hist(): eventno < 0;\n");
774 #endif
775 el->el_history.eventno = 0;
776 return CC_ERROR;
777 }
778
779 if (el->el_history.eventno == 0) {
780 (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
781 el->el_history.last = el->el_history.buf +
782 (el->el_line.lastchar - el->el_line.buffer);
783 }
784
785
786 if (el->el_history.ref == NULL)
787 return CC_ERROR;
788
789 hp = HIST_FIRST(el);
790 if (hp == NULL)
791 return CC_ERROR;
792
793 c_setpat(el); /* Set search pattern !! */
794
795 for (h = 1; h <= el->el_history.eventno; h++)
796 hp = HIST_NEXT(el);
797
798 while (hp != NULL) {
799 #ifdef SDEBUG
800 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
801 #endif
802 if ((strncmp(hp, el->el_line.buffer,
803 el->el_line.lastchar - el->el_line.buffer) ||
804 hp[el->el_line.lastchar-el->el_line.buffer]) &&
805 c_hmatch(el, hp)) {
806 found++;
807 break;
808 }
809 h++;
810 hp = HIST_NEXT(el);
811 }
812
813 if (!found) {
814 #ifdef SDEBUG
815 (void) fprintf(el->el_errfile, "not found\n");
816 #endif
817 return CC_ERROR;
818 }
819
820 el->el_history.eventno = h;
821
822 return hist_get(el);
823 }
824
825
826 /* ed_search_next_history():
827 * Search next in history for a line matching the current
828 * [M-N] [J]
829 */
830 protected el_action_t
831 /*ARGSUSED*/
832 ed_search_next_history(el, c)
833 EditLine *el;
834 int c;
835 {
836 const char *hp;
837 int h;
838 bool_t found = 0;
839
840 el->el_chared.c_vcmd.action = NOP;
841 el->el_chared.c_undo.action = NOP;
842 *el->el_line.lastchar = '\0'; /* just in case */
843
844 if (el->el_history.eventno == 0)
845 return CC_ERROR;
846
847 if (el->el_history.ref == NULL)
848 return CC_ERROR;
849
850 hp = HIST_FIRST(el);
851 if (hp == NULL)
852 return CC_ERROR;
853
854 c_setpat(el); /* Set search pattern !! */
855
856 for (h = 1; h < el->el_history.eventno && hp; h++) {
857 #ifdef SDEBUG
858 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
859 #endif
860 if ((strncmp(hp, el->el_line.buffer,
861 el->el_line.lastchar - el->el_line.buffer) ||
862 hp[el->el_line.lastchar-el->el_line.buffer]) &&
863 c_hmatch(el, hp))
864 found = h;
865 hp = HIST_NEXT(el);
866 }
867
868 if (!found) { /* is it the current history number? */
869 if (!c_hmatch(el, el->el_history.buf)) {
870 #ifdef SDEBUG
871 (void) fprintf(el->el_errfile, "not found\n");
872 #endif
873 return CC_ERROR;
874 }
875 }
876
877 el->el_history.eventno = found;
878
879 return hist_get(el);
880 }
881
882
883 /* ed_prev_line():
884 * Move up one line
885 * Could be [k] [^p]
886 */
887 protected el_action_t
888 /*ARGSUSED*/
889 ed_prev_line(el, c)
890 EditLine *el;
891 int c;
892 {
893 char *ptr;
894 int nchars = c_hpos(el);
895
896 /*
897 * Move to the line requested
898 */
899 if (*(ptr = el->el_line.cursor) == '\n')
900 ptr--;
901
902 for (; ptr >= el->el_line.buffer; ptr--)
903 if (*ptr == '\n' && --el->el_state.argument <= 0)
904 break;
905
906 if (el->el_state.argument > 0)
907 return CC_ERROR;
908
909 /*
910 * Move to the beginning of the line
911 */
912 for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
913 continue;
914
915 /*
916 * Move to the character requested
917 */
918 for (ptr++;
919 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
920 ptr++)
921 continue;
922
923 el->el_line.cursor = ptr;
924 return CC_CURSOR;
925 }
926
927
928 /* ed_next_line():
929 * Move down one line
930 * Could be [j] [^n]
931 */
932 protected el_action_t
933 /*ARGSUSED*/
934 ed_next_line(el, c)
935 EditLine *el;
936 int c;
937 {
938 char *ptr;
939 int nchars = c_hpos(el);
940
941 /*
942 * Move to the line requested
943 */
944 for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
945 if (*ptr == '\n' && --el->el_state.argument <= 0)
946 break;
947
948 if (el->el_state.argument > 0)
949 return CC_ERROR;
950
951 /*
952 * Move to the character requested
953 */
954 for (ptr++;
955 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
956 ptr++)
957 continue;
958
959 el->el_line.cursor = ptr;
960 return CC_CURSOR;
961 }
962
963
964 /* ed_command():
965 * Editline extended command
966 * [M-X] [:]
967 */
968 protected el_action_t
969 /*ARGSUSED*/
970 ed_command(el, c)
971 EditLine *el;
972 int c;
973 {
974 char tmpbuf[EL_BUFSIZ];
975 int tmplen;
976
977 el->el_line.buffer[0] = '\0';
978 el->el_line.lastchar = el->el_line.buffer;
979 el->el_line.cursor = el->el_line.buffer;
980
981 c_insert(el, 3); /* prompt + ": " */
982 *el->el_line.cursor++ = '\n';
983 *el->el_line.cursor++ = ':';
984 *el->el_line.cursor++ = ' ';
985 re_refresh(el);
986
987 tmplen = c_gets(el, tmpbuf);
988 tmpbuf[tmplen] = '\0';
989
990 el->el_line.buffer[0] = '\0';
991 el->el_line.lastchar = el->el_line.buffer;
992 el->el_line.cursor = el->el_line.buffer;
993
994 if (parse_line(el, tmpbuf) == -1)
995 return CC_ERROR;
996 else
997 return CC_REFRESH;
998 }
999