Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libedit/common.c
39476 views
1
/* $NetBSD: common.c,v 1.50 2024/06/30 16:29:42 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. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include "config.h"
36
#if !defined(lint) && !defined(SCCSID)
37
#if 0
38
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
39
#else
40
__RCSID("$NetBSD: common.c,v 1.50 2024/06/30 16:29:42 christos Exp $");
41
#endif
42
#endif /* not lint && not SCCSID */
43
44
/*
45
* common.c: Common Editor functions
46
*/
47
#include <ctype.h>
48
#include <string.h>
49
50
#include "el.h"
51
#include "common.h"
52
#include "fcns.h"
53
#include "parse.h"
54
#include "vi.h"
55
56
/* ed_end_of_file():
57
* Indicate end of file
58
* [^D]
59
*/
60
libedit_private el_action_t
61
/*ARGSUSED*/
62
ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
63
{
64
65
re_goto_bottom(el);
66
*el->el_line.lastchar = '\0';
67
return CC_EOF;
68
}
69
70
71
/* ed_insert():
72
* Add character to the line
73
* Insert a character [bound to all insert keys]
74
*/
75
libedit_private el_action_t
76
ed_insert(EditLine *el, wint_t c)
77
{
78
int count = el->el_state.argument;
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
/* end of buffer space, try to allocate more */
86
if (!ch_enlargebufs(el, (size_t) count))
87
return CC_ERROR; /* error allocating more */
88
}
89
90
if (count == 1) {
91
if (el->el_state.inputmode == MODE_INSERT
92
|| el->el_line.cursor >= el->el_line.lastchar)
93
c_insert(el, 1);
94
95
*el->el_line.cursor++ = c;
96
re_fastaddc(el); /* fast refresh for one char. */
97
} else {
98
if (el->el_state.inputmode != MODE_REPLACE_1)
99
c_insert(el, el->el_state.argument);
100
101
while (count-- && el->el_line.cursor < el->el_line.lastchar)
102
*el->el_line.cursor++ = c;
103
re_refresh(el);
104
}
105
106
if (el->el_state.inputmode == MODE_REPLACE_1)
107
return vi_command_mode(el, 0);
108
109
return CC_NORM;
110
}
111
112
113
/* ed_delete_prev_word():
114
* Delete from beginning of current word to cursor
115
* [M-^?] [^W]
116
*/
117
libedit_private el_action_t
118
/*ARGSUSED*/
119
ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
120
{
121
wchar_t *cp, *p, *kp;
122
123
if (el->el_line.cursor == el->el_line.buffer)
124
return CC_ERROR;
125
126
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
127
el->el_state.argument, ce__isword);
128
129
for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
130
*kp++ = *p;
131
el->el_chared.c_kill.last = kp;
132
133
c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
134
el->el_line.cursor = cp;
135
if (el->el_line.cursor < el->el_line.buffer)
136
el->el_line.cursor = el->el_line.buffer; /* bounds check */
137
return CC_REFRESH;
138
}
139
140
141
/* ed_delete_next_char():
142
* Delete character under cursor
143
* [^D] [x]
144
*/
145
libedit_private el_action_t
146
/*ARGSUSED*/
147
ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
148
{
149
#ifdef DEBUG_EDIT
150
#define EL el->el_line
151
(void) fprintf(el->el_errfile,
152
"\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
153
EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
154
EL.lastchar, EL.limit, EL.limit);
155
#endif
156
if (el->el_line.cursor == el->el_line.lastchar) {
157
/* if I'm at the end */
158
if (el->el_map.type == MAP_VI) {
159
if (el->el_line.cursor == el->el_line.buffer) {
160
/* if I'm also at the beginning */
161
#ifdef KSHVI
162
return CC_ERROR;
163
#else
164
/* then do an EOF */
165
terminal_writec(el, c);
166
return CC_EOF;
167
#endif
168
} else {
169
#ifdef KSHVI
170
el->el_line.cursor--;
171
#else
172
return CC_ERROR;
173
#endif
174
}
175
} else
176
return CC_ERROR;
177
}
178
c_delafter(el, el->el_state.argument); /* delete after dot */
179
if (el->el_map.type == MAP_VI &&
180
el->el_line.cursor >= el->el_line.lastchar &&
181
el->el_line.cursor > el->el_line.buffer)
182
/* bounds check */
183
el->el_line.cursor = el->el_line.lastchar - 1;
184
return CC_REFRESH;
185
}
186
187
188
/* ed_kill_line():
189
* Cut to the end of line
190
* [^K] [^K]
191
*/
192
libedit_private el_action_t
193
/*ARGSUSED*/
194
ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
195
{
196
wchar_t *kp, *cp;
197
198
cp = el->el_line.cursor;
199
kp = el->el_chared.c_kill.buf;
200
while (cp < el->el_line.lastchar)
201
*kp++ = *cp++; /* copy it */
202
el->el_chared.c_kill.last = kp;
203
/* zap! -- delete to end */
204
el->el_line.lastchar = el->el_line.cursor;
205
return CC_REFRESH;
206
}
207
208
209
/* ed_move_to_end():
210
* Move cursor to the end of line
211
* [^E] [^E]
212
*/
213
libedit_private el_action_t
214
/*ARGSUSED*/
215
ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
216
{
217
218
el->el_line.cursor = el->el_line.lastchar;
219
if (el->el_map.type == MAP_VI) {
220
if (el->el_chared.c_vcmd.action != NOP) {
221
cv_delfini(el);
222
return CC_REFRESH;
223
}
224
#ifdef VI_MOVE
225
if (el->el_line.cursor > el->el_line.buffer)
226
el->el_line.cursor--;
227
#endif
228
}
229
return CC_CURSOR;
230
}
231
232
233
/* ed_move_to_beg():
234
* Move cursor to the beginning of line
235
* [^A] [^A]
236
*/
237
libedit_private el_action_t
238
/*ARGSUSED*/
239
ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
240
{
241
242
el->el_line.cursor = el->el_line.buffer;
243
244
if (el->el_map.type == MAP_VI) {
245
/* We want FIRST non space character */
246
while (iswspace(*el->el_line.cursor))
247
el->el_line.cursor++;
248
if (el->el_chared.c_vcmd.action != NOP) {
249
cv_delfini(el);
250
return CC_REFRESH;
251
}
252
}
253
return CC_CURSOR;
254
}
255
256
257
/* ed_transpose_chars():
258
* Exchange the character to the left of the cursor with the one under it
259
* [^T] [^T]
260
*/
261
libedit_private el_action_t
262
ed_transpose_chars(EditLine *el, wint_t c)
263
{
264
265
if (el->el_line.cursor < el->el_line.lastchar) {
266
if (el->el_line.lastchar <= &el->el_line.buffer[1])
267
return CC_ERROR;
268
else
269
el->el_line.cursor++;
270
}
271
if (el->el_line.cursor > &el->el_line.buffer[1]) {
272
/* must have at least two chars entered */
273
c = el->el_line.cursor[-2];
274
el->el_line.cursor[-2] = el->el_line.cursor[-1];
275
el->el_line.cursor[-1] = c;
276
return CC_REFRESH;
277
} else
278
return CC_ERROR;
279
}
280
281
282
/* ed_next_char():
283
* Move to the right one character
284
* [^F] [^F]
285
*/
286
libedit_private el_action_t
287
/*ARGSUSED*/
288
ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
289
{
290
wchar_t *lim = el->el_line.lastchar;
291
292
if (el->el_line.cursor >= lim ||
293
(el->el_line.cursor == lim - 1 &&
294
el->el_map.type == MAP_VI &&
295
el->el_chared.c_vcmd.action == NOP))
296
return CC_ERROR;
297
298
el->el_line.cursor += el->el_state.argument;
299
if (el->el_line.cursor > lim)
300
el->el_line.cursor = lim;
301
302
if (el->el_map.type == MAP_VI)
303
if (el->el_chared.c_vcmd.action != NOP) {
304
cv_delfini(el);
305
return CC_REFRESH;
306
}
307
return CC_CURSOR;
308
}
309
310
311
/* ed_prev_word():
312
* Move to the beginning of the current word
313
* [M-b] [b]
314
*/
315
libedit_private el_action_t
316
/*ARGSUSED*/
317
ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
318
{
319
320
if (el->el_line.cursor == el->el_line.buffer)
321
return CC_ERROR;
322
323
el->el_line.cursor = c__prev_word(el->el_line.cursor,
324
el->el_line.buffer,
325
el->el_state.argument,
326
ce__isword);
327
328
if (el->el_map.type == MAP_VI)
329
if (el->el_chared.c_vcmd.action != NOP) {
330
cv_delfini(el);
331
return CC_REFRESH;
332
}
333
return CC_CURSOR;
334
}
335
336
337
/* ed_prev_char():
338
* Move to the left one character
339
* [^B] [^B]
340
*/
341
libedit_private el_action_t
342
/*ARGSUSED*/
343
ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
344
{
345
346
if (el->el_line.cursor > el->el_line.buffer) {
347
el->el_line.cursor -= el->el_state.argument;
348
if (el->el_line.cursor < el->el_line.buffer)
349
el->el_line.cursor = el->el_line.buffer;
350
351
if (el->el_map.type == MAP_VI)
352
if (el->el_chared.c_vcmd.action != NOP) {
353
cv_delfini(el);
354
return CC_REFRESH;
355
}
356
return CC_CURSOR;
357
} else
358
return CC_ERROR;
359
}
360
361
362
/* ed_quoted_insert():
363
* Add the next character typed verbatim
364
* [^V] [^V]
365
*/
366
libedit_private el_action_t
367
/*ARGSUSED*/
368
ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__)))
369
{
370
int num;
371
wchar_t ch;
372
373
tty_quotemode(el);
374
num = el_wgetc(el, &ch);
375
tty_noquotemode(el);
376
if (num == 1)
377
return ed_insert(el, ch);
378
else
379
return ed_end_of_file(el, 0);
380
}
381
382
383
/* ed_digit():
384
* Adds to argument or enters a digit
385
*/
386
libedit_private el_action_t
387
ed_digit(EditLine *el, wint_t c)
388
{
389
390
if (!iswdigit(c))
391
return CC_ERROR;
392
393
if (el->el_state.doingarg) {
394
/* if doing an arg, add this in... */
395
if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
396
el->el_state.argument = c - '0';
397
else {
398
if (el->el_state.argument > 1000000)
399
return CC_ERROR;
400
el->el_state.argument =
401
(el->el_state.argument * 10) + (c - '0');
402
}
403
return CC_ARGHACK;
404
}
405
406
return ed_insert(el, c);
407
}
408
409
410
/* ed_argument_digit():
411
* Digit that starts argument
412
* For ESC-n
413
*/
414
libedit_private el_action_t
415
ed_argument_digit(EditLine *el, wint_t c)
416
{
417
418
if (!iswdigit(c))
419
return CC_ERROR;
420
421
if (el->el_state.doingarg) {
422
if (el->el_state.argument > 1000000)
423
return CC_ERROR;
424
el->el_state.argument = (el->el_state.argument * 10) +
425
(c - '0');
426
} else { /* else starting an argument */
427
el->el_state.argument = c - '0';
428
el->el_state.doingarg = 1;
429
}
430
return CC_ARGHACK;
431
}
432
433
434
/* ed_unassigned():
435
* Indicates unbound character
436
* Bound to keys that are not assigned
437
*/
438
libedit_private el_action_t
439
/*ARGSUSED*/
440
ed_unassigned(EditLine *el __attribute__((__unused__)),
441
wint_t c __attribute__((__unused__)))
442
{
443
444
return CC_ERROR;
445
}
446
447
448
/* ed_ignore():
449
* Input characters that have no effect
450
* [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
451
*/
452
libedit_private el_action_t
453
/*ARGSUSED*/
454
ed_ignore(EditLine *el __attribute__((__unused__)),
455
wint_t c __attribute__((__unused__)))
456
{
457
458
return CC_NORM;
459
}
460
461
462
/* ed_newline():
463
* Execute command
464
* [^J]
465
*/
466
libedit_private el_action_t
467
/*ARGSUSED*/
468
ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
469
{
470
471
re_goto_bottom(el);
472
*el->el_line.lastchar++ = '\n';
473
*el->el_line.lastchar = '\0';
474
return CC_NEWLINE;
475
}
476
477
478
/* ed_delete_prev_char():
479
* Delete the character to the left of the cursor
480
* [^?]
481
*/
482
libedit_private el_action_t
483
/*ARGSUSED*/
484
ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
485
{
486
487
if (el->el_line.cursor <= el->el_line.buffer)
488
return CC_ERROR;
489
490
c_delbefore(el, el->el_state.argument);
491
el->el_line.cursor -= el->el_state.argument;
492
if (el->el_line.cursor < el->el_line.buffer)
493
el->el_line.cursor = el->el_line.buffer;
494
return CC_REFRESH;
495
}
496
497
498
/* ed_clear_screen():
499
* Clear screen leaving current line at the top
500
* [^L]
501
*/
502
libedit_private el_action_t
503
/*ARGSUSED*/
504
ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
505
{
506
507
terminal_clear_screen(el); /* clear the whole real screen */
508
re_clear_display(el); /* reset everything */
509
return CC_REFRESH;
510
}
511
512
513
/* ed_redisplay():
514
* Redisplay everything
515
* ^R
516
*/
517
libedit_private el_action_t
518
/*ARGSUSED*/
519
ed_redisplay(EditLine *el __attribute__((__unused__)),
520
wint_t c __attribute__((__unused__)))
521
{
522
523
return CC_REDISPLAY;
524
}
525
526
527
/* ed_start_over():
528
* Erase current line and start from scratch
529
* [^G]
530
*/
531
libedit_private el_action_t
532
/*ARGSUSED*/
533
ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
534
{
535
536
ch_reset(el);
537
return CC_REFRESH;
538
}
539
540
541
/* ed_sequence_lead_in():
542
* First character in a bound sequence
543
* Placeholder for external keys
544
*/
545
libedit_private el_action_t
546
/*ARGSUSED*/
547
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
548
wint_t c __attribute__((__unused__)))
549
{
550
551
return CC_NORM;
552
}
553
554
555
/* ed_prev_history():
556
* Move to the previous history line
557
* [^P] [k]
558
*/
559
libedit_private el_action_t
560
/*ARGSUSED*/
561
ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
562
{
563
char beep = 0;
564
int sv_event = el->el_history.eventno;
565
566
el->el_chared.c_undo.len = -1;
567
*el->el_line.lastchar = '\0'; /* just in case */
568
569
if (el->el_history.eventno == 0) { /* save the current buffer
570
* away */
571
(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
572
EL_BUFSIZ);
573
el->el_history.last = el->el_history.buf +
574
(el->el_line.lastchar - el->el_line.buffer);
575
}
576
el->el_history.eventno += el->el_state.argument;
577
578
if (hist_get(el) == CC_ERROR) {
579
if (el->el_map.type == MAP_VI) {
580
el->el_history.eventno = sv_event;
581
}
582
beep = 1;
583
/* el->el_history.eventno was fixed by first call */
584
(void) hist_get(el);
585
}
586
if (beep)
587
return CC_REFRESH_BEEP;
588
return CC_REFRESH;
589
}
590
591
592
/* ed_next_history():
593
* Move to the next history line
594
* [^N] [j]
595
*/
596
libedit_private el_action_t
597
/*ARGSUSED*/
598
ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
599
{
600
el_action_t beep = CC_REFRESH, rval;
601
602
el->el_chared.c_undo.len = -1;
603
*el->el_line.lastchar = '\0'; /* just in case */
604
605
el->el_history.eventno -= el->el_state.argument;
606
607
if (el->el_history.eventno < 0) {
608
el->el_history.eventno = 0;
609
beep = CC_REFRESH_BEEP;
610
}
611
rval = hist_get(el);
612
if (rval == CC_REFRESH)
613
return beep;
614
return rval;
615
616
}
617
618
619
/* ed_search_prev_history():
620
* Search previous in history for a line matching the current
621
* next search history [M-P] [K]
622
*/
623
libedit_private el_action_t
624
/*ARGSUSED*/
625
ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
626
{
627
const wchar_t *hp;
628
int h;
629
int found = 0;
630
631
el->el_chared.c_vcmd.action = NOP;
632
el->el_chared.c_undo.len = -1;
633
*el->el_line.lastchar = '\0'; /* just in case */
634
if (el->el_history.eventno < 0) {
635
#ifdef DEBUG_EDIT
636
(void) fprintf(el->el_errfile,
637
"e_prev_search_hist(): eventno < 0;\n");
638
#endif
639
el->el_history.eventno = 0;
640
return CC_ERROR;
641
}
642
if (el->el_history.eventno == 0) {
643
(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
644
EL_BUFSIZ);
645
el->el_history.last = el->el_history.buf +
646
(el->el_line.lastchar - el->el_line.buffer);
647
}
648
if (el->el_history.ref == NULL)
649
return CC_ERROR;
650
651
hp = HIST_FIRST(el);
652
if (hp == NULL)
653
return CC_ERROR;
654
655
c_setpat(el); /* Set search pattern !! */
656
657
for (h = 1; h <= el->el_history.eventno; h++)
658
hp = HIST_NEXT(el);
659
660
while (hp != NULL) {
661
#ifdef SDEBUG
662
(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
663
#endif
664
if ((wcsncmp(hp, el->el_line.buffer, (size_t)
665
(el->el_line.lastchar - el->el_line.buffer)) ||
666
hp[el->el_line.lastchar - el->el_line.buffer]) &&
667
c_hmatch(el, hp)) {
668
found = 1;
669
break;
670
}
671
h++;
672
hp = HIST_NEXT(el);
673
}
674
675
if (!found) {
676
#ifdef SDEBUG
677
(void) fprintf(el->el_errfile, "not found\n");
678
#endif
679
return CC_ERROR;
680
}
681
el->el_history.eventno = h;
682
683
return hist_get(el);
684
}
685
686
687
/* ed_search_next_history():
688
* Search next in history for a line matching the current
689
* [M-N] [J]
690
*/
691
libedit_private el_action_t
692
/*ARGSUSED*/
693
ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
694
{
695
const wchar_t *hp;
696
int h;
697
int found = 0;
698
699
el->el_chared.c_vcmd.action = NOP;
700
el->el_chared.c_undo.len = -1;
701
*el->el_line.lastchar = '\0'; /* just in case */
702
703
if (el->el_history.eventno == 0)
704
return CC_ERROR;
705
706
if (el->el_history.ref == NULL)
707
return CC_ERROR;
708
709
hp = HIST_FIRST(el);
710
if (hp == NULL)
711
return CC_ERROR;
712
713
c_setpat(el); /* Set search pattern !! */
714
715
for (h = 1; h < el->el_history.eventno && hp; h++) {
716
#ifdef SDEBUG
717
(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
718
#endif
719
if ((wcsncmp(hp, el->el_line.buffer, (size_t)
720
(el->el_line.lastchar - el->el_line.buffer)) ||
721
hp[el->el_line.lastchar - el->el_line.buffer]) &&
722
c_hmatch(el, hp))
723
found = h;
724
hp = HIST_NEXT(el);
725
}
726
727
if (!found) { /* is it the current history number? */
728
if (!c_hmatch(el, el->el_history.buf)) {
729
#ifdef SDEBUG
730
(void) fprintf(el->el_errfile, "not found\n");
731
#endif
732
return CC_ERROR;
733
}
734
}
735
el->el_history.eventno = found;
736
737
return hist_get(el);
738
}
739
740
741
/* ed_prev_line():
742
* Move up one line
743
* Could be [k] [^p]
744
*/
745
libedit_private el_action_t
746
/*ARGSUSED*/
747
ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
748
{
749
wchar_t *ptr;
750
int nchars = c_hpos(el);
751
752
/*
753
* Move to the line requested
754
*/
755
if (*(ptr = el->el_line.cursor) == '\n')
756
ptr--;
757
758
for (; ptr >= el->el_line.buffer; ptr--)
759
if (*ptr == '\n' && --el->el_state.argument <= 0)
760
break;
761
762
if (el->el_state.argument > 0)
763
return CC_ERROR;
764
765
/*
766
* Move to the beginning of the line
767
*/
768
for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
769
continue;
770
771
/*
772
* Move to the character requested
773
*/
774
for (ptr++;
775
nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
776
ptr++)
777
continue;
778
779
el->el_line.cursor = ptr;
780
return CC_CURSOR;
781
}
782
783
784
/* ed_next_line():
785
* Move down one line
786
* Could be [j] [^n]
787
*/
788
libedit_private el_action_t
789
/*ARGSUSED*/
790
ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
791
{
792
wchar_t *ptr;
793
int nchars = c_hpos(el);
794
795
/*
796
* Move to the line requested
797
*/
798
for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
799
if (*ptr == '\n' && --el->el_state.argument <= 0)
800
break;
801
802
if (el->el_state.argument > 0)
803
return CC_ERROR;
804
805
/*
806
* Move to the character requested
807
*/
808
for (ptr++;
809
nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
810
ptr++)
811
continue;
812
813
el->el_line.cursor = ptr;
814
return CC_CURSOR;
815
}
816
817
818
/* ed_command():
819
* Editline extended command
820
* [M-X] [:]
821
*/
822
libedit_private el_action_t
823
/*ARGSUSED*/
824
ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
825
{
826
wchar_t tmpbuf[EL_BUFSIZ];
827
int tmplen;
828
829
tmplen = c_gets(el, tmpbuf, L"\n: ");
830
terminal__putc(el, '\n');
831
832
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
833
terminal_beep(el);
834
835
el->el_map.current = el->el_map.key;
836
re_clear_display(el);
837
return CC_REFRESH;
838
}
839
840