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