Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libedit/chared.c
39536 views
1
/* $NetBSD: chared.c,v 1.64 2024/06/29 14:13:14 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[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
39
#else
40
__RCSID("$NetBSD: chared.c,v 1.64 2024/06/29 14:13:14 christos Exp $");
41
#endif
42
#endif /* not lint && not SCCSID */
43
44
/*
45
* chared.c: Character editor utilities
46
*/
47
#include <ctype.h>
48
#include <stdlib.h>
49
#include <string.h>
50
51
#include "el.h"
52
#include "common.h"
53
#include "fcns.h"
54
55
/* value to leave unused in line buffer */
56
#define EL_LEAVE 2
57
58
/* cv_undo():
59
* Handle state for the vi undo command
60
*/
61
libedit_private void
62
cv_undo(EditLine *el)
63
{
64
c_undo_t *vu = &el->el_chared.c_undo;
65
c_redo_t *r = &el->el_chared.c_redo;
66
size_t size;
67
68
/* Save entire line for undo */
69
size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
70
vu->len = (ssize_t)size;
71
vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
72
(void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
73
74
/* save command info for redo */
75
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
76
r->action = el->el_chared.c_vcmd.action;
77
r->pos = r->buf;
78
r->cmd = el->el_state.thiscmd;
79
r->ch = el->el_state.thisch;
80
}
81
82
/* cv_yank():
83
* Save yank/delete data for paste
84
*/
85
libedit_private void
86
cv_yank(EditLine *el, const wchar_t *ptr, int size)
87
{
88
c_kill_t *k = &el->el_chared.c_kill;
89
90
(void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
91
k->last = k->buf + size;
92
}
93
94
95
/* c_insert():
96
* Insert num characters
97
*/
98
libedit_private void
99
c_insert(EditLine *el, int num)
100
{
101
wchar_t *cp;
102
103
if (el->el_line.lastchar + num >= el->el_line.limit) {
104
if (!ch_enlargebufs(el, (size_t)num))
105
return; /* can't go past end of buffer */
106
}
107
108
if (el->el_line.cursor < el->el_line.lastchar) {
109
/* if I must move chars */
110
for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
111
cp[num] = *cp;
112
}
113
el->el_line.lastchar += num;
114
}
115
116
117
/* c_delafter():
118
* Delete num characters after the cursor
119
*/
120
libedit_private void
121
c_delafter(EditLine *el, int num)
122
{
123
124
if (el->el_line.cursor + num > el->el_line.lastchar)
125
num = (int)(el->el_line.lastchar - el->el_line.cursor);
126
127
if (el->el_map.current != el->el_map.emacs) {
128
cv_undo(el);
129
cv_yank(el, el->el_line.cursor, num);
130
}
131
132
if (num > 0) {
133
wchar_t *cp;
134
135
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
136
*cp = cp[num];
137
138
el->el_line.lastchar -= num;
139
}
140
}
141
142
143
/* c_delafter1():
144
* Delete the character after the cursor, do not yank
145
*/
146
libedit_private void
147
c_delafter1(EditLine *el)
148
{
149
wchar_t *cp;
150
151
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
152
*cp = cp[1];
153
154
el->el_line.lastchar--;
155
}
156
157
158
/* c_delbefore():
159
* Delete num characters before the cursor
160
*/
161
libedit_private void
162
c_delbefore(EditLine *el, int num)
163
{
164
165
if (el->el_line.cursor - num < el->el_line.buffer)
166
num = (int)(el->el_line.cursor - el->el_line.buffer);
167
168
if (el->el_map.current != el->el_map.emacs) {
169
cv_undo(el);
170
cv_yank(el, el->el_line.cursor - num, num);
171
}
172
173
if (num > 0) {
174
wchar_t *cp;
175
176
for (cp = el->el_line.cursor - num;
177
&cp[num] <= el->el_line.lastchar;
178
cp++)
179
*cp = cp[num];
180
181
el->el_line.lastchar -= num;
182
}
183
}
184
185
186
/* c_delbefore1():
187
* Delete the character before the cursor, do not yank
188
*/
189
libedit_private void
190
c_delbefore1(EditLine *el)
191
{
192
wchar_t *cp;
193
194
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
195
*cp = cp[1];
196
197
el->el_line.lastchar--;
198
}
199
200
201
/* ce__isword():
202
* Return if p is part of a word according to emacs
203
*/
204
libedit_private int
205
ce__isword(wint_t p)
206
{
207
return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
208
}
209
210
211
/* cv__isword():
212
* Return if p is part of a word according to vi
213
*/
214
libedit_private int
215
cv__isword(wint_t p)
216
{
217
if (iswalnum(p) || p == L'_')
218
return 1;
219
if (iswgraph(p))
220
return 2;
221
return 0;
222
}
223
224
225
/* cv__isWord():
226
* Return if p is part of a big word according to vi
227
*/
228
libedit_private int
229
cv__isWord(wint_t p)
230
{
231
return !iswspace(p);
232
}
233
234
235
/* c__prev_word():
236
* Find the previous word
237
*/
238
libedit_private wchar_t *
239
c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
240
{
241
p--;
242
243
while (n--) {
244
while ((p >= low) && !(*wtest)(*p))
245
p--;
246
while ((p >= low) && (*wtest)(*p))
247
p--;
248
}
249
250
/* cp now points to one character before the word */
251
p++;
252
if (p < low)
253
p = low;
254
/* cp now points where we want it */
255
return p;
256
}
257
258
259
/* c__next_word():
260
* Find the next word
261
*/
262
libedit_private wchar_t *
263
c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
264
{
265
while (n--) {
266
while ((p < high) && !(*wtest)(*p))
267
p++;
268
while ((p < high) && (*wtest)(*p))
269
p++;
270
}
271
if (p > high)
272
p = high;
273
/* p now points where we want it */
274
return p;
275
}
276
277
/* cv_next_word():
278
* Find the next word vi style
279
*/
280
libedit_private wchar_t *
281
cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
282
int (*wtest)(wint_t))
283
{
284
int test;
285
286
while (n--) {
287
test = (*wtest)(*p);
288
while ((p < high) && (*wtest)(*p) == test)
289
p++;
290
/*
291
* vi historically deletes with cw only the word preserving the
292
* trailing whitespace! This is not what 'w' does..
293
*/
294
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
295
while ((p < high) && iswspace(*p))
296
p++;
297
}
298
299
/* p now points where we want it */
300
if (p > high)
301
return high;
302
else
303
return p;
304
}
305
306
307
/* cv_prev_word():
308
* Find the previous word vi style
309
*/
310
libedit_private wchar_t *
311
cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
312
{
313
int test;
314
315
p--;
316
while (n--) {
317
while ((p > low) && iswspace(*p))
318
p--;
319
test = (*wtest)(*p);
320
while ((p >= low) && (*wtest)(*p) == test)
321
p--;
322
if (p < low)
323
return low;
324
}
325
p++;
326
327
/* p now points where we want it */
328
if (p < low)
329
return low;
330
else
331
return p;
332
}
333
334
335
/* cv_delfini():
336
* Finish vi delete action
337
*/
338
libedit_private void
339
cv_delfini(EditLine *el)
340
{
341
int size;
342
int action = el->el_chared.c_vcmd.action;
343
344
if (action & INSERT)
345
el->el_map.current = el->el_map.key;
346
347
if (el->el_chared.c_vcmd.pos == 0)
348
/* sanity */
349
return;
350
351
size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
352
if (size == 0)
353
size = 1;
354
el->el_line.cursor = el->el_chared.c_vcmd.pos;
355
if (action & YANK) {
356
if (size > 0)
357
cv_yank(el, el->el_line.cursor, size);
358
else
359
cv_yank(el, el->el_line.cursor + size, -size);
360
} else {
361
if (size > 0) {
362
c_delafter(el, size);
363
re_refresh_cursor(el);
364
} else {
365
c_delbefore(el, -size);
366
el->el_line.cursor += size;
367
}
368
}
369
el->el_chared.c_vcmd.action = NOP;
370
}
371
372
373
/* cv__endword():
374
* Go to the end of this word according to vi
375
*/
376
libedit_private wchar_t *
377
cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
378
{
379
int test;
380
381
p++;
382
383
while (n--) {
384
while ((p < high) && iswspace(*p))
385
p++;
386
387
test = (*wtest)(*p);
388
while ((p < high) && (*wtest)(*p) == test)
389
p++;
390
}
391
p--;
392
return p;
393
}
394
395
/* ch_init():
396
* Initialize the character editor
397
*/
398
libedit_private int
399
ch_init(EditLine *el)
400
{
401
el->el_line.buffer = el_calloc(EL_BUFSIZ,
402
sizeof(*el->el_line.buffer));
403
if (el->el_line.buffer == NULL)
404
return -1;
405
406
el->el_line.cursor = el->el_line.buffer;
407
el->el_line.lastchar = el->el_line.buffer;
408
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
409
410
el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ,
411
sizeof(*el->el_chared.c_undo.buf));
412
if (el->el_chared.c_undo.buf == NULL)
413
return -1;
414
el->el_chared.c_undo.len = -1;
415
el->el_chared.c_undo.cursor = 0;
416
el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ,
417
sizeof(*el->el_chared.c_redo.buf));
418
if (el->el_chared.c_redo.buf == NULL)
419
goto out;
420
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
421
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
422
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
423
424
el->el_chared.c_vcmd.action = NOP;
425
el->el_chared.c_vcmd.pos = el->el_line.buffer;
426
427
el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ,
428
sizeof(*el->el_chared.c_kill.buf));
429
if (el->el_chared.c_kill.buf == NULL)
430
goto out;
431
el->el_chared.c_kill.mark = el->el_line.buffer;
432
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
433
el->el_chared.c_resizefun = NULL;
434
el->el_chared.c_resizearg = NULL;
435
el->el_chared.c_aliasfun = NULL;
436
el->el_chared.c_aliasarg = NULL;
437
438
el->el_map.current = el->el_map.key;
439
440
el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
441
el->el_state.doingarg = 0;
442
el->el_state.metanext = 0;
443
el->el_state.argument = 1;
444
el->el_state.lastcmd = ED_UNASSIGNED;
445
446
return 0;
447
out:
448
ch_end(el);
449
return -1;
450
}
451
452
/* ch_reset():
453
* Reset the character editor
454
*/
455
libedit_private void
456
ch_reset(EditLine *el)
457
{
458
el->el_line.cursor = el->el_line.buffer;
459
el->el_line.lastchar = el->el_line.buffer;
460
461
el->el_chared.c_undo.len = -1;
462
el->el_chared.c_undo.cursor = 0;
463
464
el->el_chared.c_vcmd.action = NOP;
465
el->el_chared.c_vcmd.pos = el->el_line.buffer;
466
467
el->el_chared.c_kill.mark = el->el_line.buffer;
468
469
el->el_map.current = el->el_map.key;
470
471
el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
472
el->el_state.doingarg = 0;
473
el->el_state.metanext = 0;
474
el->el_state.argument = 1;
475
el->el_state.lastcmd = ED_UNASSIGNED;
476
477
el->el_history.eventno = 0;
478
}
479
480
/* ch_enlargebufs():
481
* Enlarge line buffer to be able to hold twice as much characters.
482
* Returns 1 if successful, 0 if not.
483
*/
484
libedit_private int
485
ch_enlargebufs(EditLine *el, size_t addlen)
486
{
487
size_t sz, newsz;
488
wchar_t *newbuffer, *oldbuf, *oldkbuf;
489
490
sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
491
newsz = sz * 2;
492
/*
493
* If newly required length is longer than current buffer, we need
494
* to make the buffer big enough to hold both old and new stuff.
495
*/
496
if (addlen > sz) {
497
while(newsz - sz < addlen)
498
newsz *= 2;
499
}
500
501
/*
502
* Reallocate line buffer.
503
*/
504
newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
505
if (!newbuffer)
506
return 0;
507
508
/* zero the newly added memory, leave old data in */
509
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
510
511
oldbuf = el->el_line.buffer;
512
513
el->el_line.buffer = newbuffer;
514
el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
515
el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
516
/* don't set new size until all buffers are enlarged */
517
el->el_line.limit = &newbuffer[sz - EL_LEAVE];
518
519
/*
520
* Reallocate kill buffer.
521
*/
522
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
523
sizeof(*newbuffer));
524
if (!newbuffer)
525
return 0;
526
527
/* zero the newly added memory, leave old data in */
528
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
529
530
oldkbuf = el->el_chared.c_kill.buf;
531
532
el->el_chared.c_kill.buf = newbuffer;
533
el->el_chared.c_kill.last = newbuffer +
534
(el->el_chared.c_kill.last - oldkbuf);
535
el->el_chared.c_kill.mark = el->el_line.buffer +
536
(el->el_chared.c_kill.mark - oldbuf);
537
538
/*
539
* Reallocate undo buffer.
540
*/
541
newbuffer = el_realloc(el->el_chared.c_undo.buf,
542
newsz * sizeof(*newbuffer));
543
if (!newbuffer)
544
return 0;
545
546
/* zero the newly added memory, leave old data in */
547
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
548
el->el_chared.c_undo.buf = newbuffer;
549
550
newbuffer = el_realloc(el->el_chared.c_redo.buf,
551
newsz * sizeof(*newbuffer));
552
if (!newbuffer)
553
return 0;
554
el->el_chared.c_redo.pos = newbuffer +
555
(el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
556
el->el_chared.c_redo.lim = newbuffer +
557
(el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
558
el->el_chared.c_redo.buf = newbuffer;
559
560
if (!hist_enlargebuf(el, sz, newsz))
561
return 0;
562
563
/* Safe to set enlarged buffer size */
564
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
565
if (el->el_chared.c_resizefun)
566
(*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
567
return 1;
568
}
569
570
/* ch_end():
571
* Free the data structures used by the editor
572
*/
573
libedit_private void
574
ch_end(EditLine *el)
575
{
576
el_free(el->el_line.buffer);
577
el->el_line.buffer = NULL;
578
el->el_line.limit = NULL;
579
el_free(el->el_chared.c_undo.buf);
580
el->el_chared.c_undo.buf = NULL;
581
el_free(el->el_chared.c_redo.buf);
582
el->el_chared.c_redo.buf = NULL;
583
el->el_chared.c_redo.pos = NULL;
584
el->el_chared.c_redo.lim = NULL;
585
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
586
el_free(el->el_chared.c_kill.buf);
587
el->el_chared.c_kill.buf = NULL;
588
ch_reset(el);
589
}
590
591
592
/* el_insertstr():
593
* Insert string at cursor
594
*/
595
int
596
el_winsertstr(EditLine *el, const wchar_t *s)
597
{
598
size_t len;
599
600
if (s == NULL || (len = wcslen(s)) == 0)
601
return -1;
602
if (el->el_line.lastchar + len >= el->el_line.limit) {
603
if (!ch_enlargebufs(el, len))
604
return -1;
605
}
606
607
c_insert(el, (int)len);
608
while (*s)
609
*el->el_line.cursor++ = *s++;
610
return 0;
611
}
612
613
614
/* el_deletestr():
615
* Delete num characters before the cursor
616
*/
617
void
618
el_deletestr(EditLine *el, int n)
619
{
620
if (n <= 0)
621
return;
622
623
if (el->el_line.cursor < &el->el_line.buffer[n])
624
return;
625
626
c_delbefore(el, n); /* delete before dot */
627
el->el_line.cursor -= n;
628
if (el->el_line.cursor < el->el_line.buffer)
629
el->el_line.cursor = el->el_line.buffer;
630
}
631
632
/* el_deletestr1():
633
* Delete characters between start and end
634
*/
635
int
636
el_deletestr1(EditLine *el, int start, int end)
637
{
638
size_t line_length, len;
639
wchar_t *p1, *p2;
640
641
if (end <= start)
642
return 0;
643
644
line_length = (size_t)(el->el_line.lastchar - el->el_line.buffer);
645
646
if (start >= (int)line_length || end >= (int)line_length)
647
return 0;
648
649
len = (size_t)(end - start);
650
if (len > line_length - (size_t)end)
651
len = line_length - (size_t)end;
652
653
p1 = el->el_line.buffer + start;
654
p2 = el->el_line.buffer + end;
655
for (size_t i = 0; i < len; i++) {
656
*p1++ = *p2++;
657
el->el_line.lastchar--;
658
}
659
660
if (el->el_line.cursor < el->el_line.buffer)
661
el->el_line.cursor = el->el_line.buffer;
662
663
return end - start;
664
}
665
666
/* el_wreplacestr():
667
* Replace the contents of the line with the provided string
668
*/
669
int
670
el_wreplacestr(EditLine *el, const wchar_t *s)
671
{
672
size_t len;
673
wchar_t * p;
674
675
if (s == NULL || (len = wcslen(s)) == 0)
676
return -1;
677
678
if (el->el_line.buffer + len >= el->el_line.limit) {
679
if (!ch_enlargebufs(el, len))
680
return -1;
681
}
682
683
p = el->el_line.buffer;
684
for (size_t i = 0; i < len; i++)
685
*p++ = *s++;
686
687
el->el_line.buffer[len] = '\0';
688
el->el_line.lastchar = el->el_line.buffer + len;
689
if (el->el_line.cursor > el->el_line.lastchar)
690
el->el_line.cursor = el->el_line.lastchar;
691
692
return 0;
693
}
694
695
/* el_cursor():
696
* Move the cursor to the left or the right of the current position
697
*/
698
int
699
el_cursor(EditLine *el, int n)
700
{
701
if (n == 0)
702
goto out;
703
704
el->el_line.cursor += n;
705
706
if (el->el_line.cursor < el->el_line.buffer)
707
el->el_line.cursor = el->el_line.buffer;
708
if (el->el_line.cursor > el->el_line.lastchar)
709
el->el_line.cursor = el->el_line.lastchar;
710
out:
711
return (int)(el->el_line.cursor - el->el_line.buffer);
712
}
713
714
/* c_gets():
715
* Get a string
716
*/
717
libedit_private int
718
c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
719
{
720
ssize_t len;
721
wchar_t *cp = el->el_line.buffer, ch;
722
723
if (prompt) {
724
len = (ssize_t)wcslen(prompt);
725
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
726
cp += len;
727
}
728
len = 0;
729
730
for (;;) {
731
el->el_line.cursor = cp;
732
*cp = ' ';
733
el->el_line.lastchar = cp + 1;
734
re_refresh(el);
735
736
if (el_wgetc(el, &ch) != 1) {
737
ed_end_of_file(el, 0);
738
len = -1;
739
break;
740
}
741
742
switch (ch) {
743
744
case L'\b': /* Delete and backspace */
745
case 0177:
746
if (len == 0) {
747
len = -1;
748
break;
749
}
750
len--;
751
cp--;
752
continue;
753
754
case 0033: /* ESC */
755
case L'\r': /* Newline */
756
case L'\n':
757
buf[len] = ch;
758
break;
759
760
default:
761
if (len >= (ssize_t)(EL_BUFSIZ - 16))
762
terminal_beep(el);
763
else {
764
buf[len++] = ch;
765
*cp++ = ch;
766
}
767
continue;
768
}
769
break;
770
}
771
772
el->el_line.buffer[0] = '\0';
773
el->el_line.lastchar = el->el_line.buffer;
774
el->el_line.cursor = el->el_line.buffer;
775
return (int)len;
776
}
777
778
779
/* c_hpos():
780
* Return the current horizontal position of the cursor
781
*/
782
libedit_private int
783
c_hpos(EditLine *el)
784
{
785
wchar_t *ptr;
786
787
/*
788
* Find how many characters till the beginning of this line.
789
*/
790
if (el->el_line.cursor == el->el_line.buffer)
791
return 0;
792
else {
793
for (ptr = el->el_line.cursor - 1;
794
ptr >= el->el_line.buffer && *ptr != '\n';
795
ptr--)
796
continue;
797
return (int)(el->el_line.cursor - ptr - 1);
798
}
799
}
800
801
libedit_private int
802
ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
803
{
804
el->el_chared.c_resizefun = f;
805
el->el_chared.c_resizearg = a;
806
return 0;
807
}
808
809
libedit_private int
810
ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
811
{
812
el->el_chared.c_aliasfun = f;
813
el->el_chared.c_aliasarg = a;
814
return 0;
815
}
816
817