1*cdf8408cSAntonio Huete Jimenez /* $NetBSD: chared.c,v 1.62 2022/02/08 21:13:22 rillig Exp $ */
232fe07f8SJohn Marino
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino * Copyright (c) 1992, 1993
532fe07f8SJohn Marino * The Regents of the University of California. All rights reserved.
632fe07f8SJohn Marino *
732fe07f8SJohn Marino * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino *
1032fe07f8SJohn Marino * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino * are met:
1332fe07f8SJohn Marino * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino * documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino * may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino * without specific prior written permission.
2132fe07f8SJohn Marino *
2232fe07f8SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino * SUCH DAMAGE.
3332fe07f8SJohn Marino */
3432fe07f8SJohn Marino
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*cdf8408cSAntonio Huete Jimenez __RCSID("$NetBSD: chared.c,v 1.62 2022/02/08 21:13:22 rillig Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino * chared.c: Character editor utilities
4632fe07f8SJohn Marino */
4712db70c8Szrj #include <ctype.h>
4832fe07f8SJohn Marino #include <stdlib.h>
4912db70c8Szrj #include <string.h>
5032fe07f8SJohn Marino
5112db70c8Szrj #include "el.h"
5212db70c8Szrj #include "common.h"
5312db70c8Szrj #include "fcns.h"
5432fe07f8SJohn Marino
5532fe07f8SJohn Marino /* value to leave unused in line buffer */
5632fe07f8SJohn Marino #define EL_LEAVE 2
5732fe07f8SJohn Marino
5832fe07f8SJohn Marino /* cv_undo():
5932fe07f8SJohn Marino * Handle state for the vi undo command
6032fe07f8SJohn Marino */
6112db70c8Szrj libedit_private void
cv_undo(EditLine * el)6232fe07f8SJohn Marino cv_undo(EditLine *el)
6332fe07f8SJohn Marino {
6432fe07f8SJohn Marino c_undo_t *vu = &el->el_chared.c_undo;
6532fe07f8SJohn Marino c_redo_t *r = &el->el_chared.c_redo;
6632fe07f8SJohn Marino size_t size;
6732fe07f8SJohn Marino
6832fe07f8SJohn Marino /* Save entire line for undo */
6932fe07f8SJohn Marino size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
7032fe07f8SJohn Marino vu->len = (ssize_t)size;
7132fe07f8SJohn Marino vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
7232fe07f8SJohn Marino (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
7332fe07f8SJohn Marino
7432fe07f8SJohn Marino /* save command info for redo */
7532fe07f8SJohn Marino r->count = el->el_state.doingarg ? el->el_state.argument : 0;
7632fe07f8SJohn Marino r->action = el->el_chared.c_vcmd.action;
7732fe07f8SJohn Marino r->pos = r->buf;
7832fe07f8SJohn Marino r->cmd = el->el_state.thiscmd;
7932fe07f8SJohn Marino r->ch = el->el_state.thisch;
8032fe07f8SJohn Marino }
8132fe07f8SJohn Marino
8232fe07f8SJohn Marino /* cv_yank():
8332fe07f8SJohn Marino * Save yank/delete data for paste
8432fe07f8SJohn Marino */
8512db70c8Szrj libedit_private void
cv_yank(EditLine * el,const wchar_t * ptr,int size)8612db70c8Szrj cv_yank(EditLine *el, const wchar_t *ptr, int size)
8732fe07f8SJohn Marino {
8832fe07f8SJohn Marino c_kill_t *k = &el->el_chared.c_kill;
8932fe07f8SJohn Marino
9032fe07f8SJohn Marino (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
9132fe07f8SJohn Marino k->last = k->buf + size;
9232fe07f8SJohn Marino }
9332fe07f8SJohn Marino
9432fe07f8SJohn Marino
9532fe07f8SJohn Marino /* c_insert():
9632fe07f8SJohn Marino * Insert num characters
9732fe07f8SJohn Marino */
9812db70c8Szrj libedit_private void
c_insert(EditLine * el,int num)9932fe07f8SJohn Marino c_insert(EditLine *el, int num)
10032fe07f8SJohn Marino {
10112db70c8Szrj wchar_t *cp;
10232fe07f8SJohn Marino
10332fe07f8SJohn Marino if (el->el_line.lastchar + num >= el->el_line.limit) {
10432fe07f8SJohn Marino if (!ch_enlargebufs(el, (size_t)num))
10532fe07f8SJohn Marino return; /* can't go past end of buffer */
10632fe07f8SJohn Marino }
10732fe07f8SJohn Marino
10832fe07f8SJohn Marino if (el->el_line.cursor < el->el_line.lastchar) {
10932fe07f8SJohn Marino /* if I must move chars */
11032fe07f8SJohn Marino for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
11132fe07f8SJohn Marino cp[num] = *cp;
11232fe07f8SJohn Marino }
11332fe07f8SJohn Marino el->el_line.lastchar += num;
11432fe07f8SJohn Marino }
11532fe07f8SJohn Marino
11632fe07f8SJohn Marino
11732fe07f8SJohn Marino /* c_delafter():
11832fe07f8SJohn Marino * Delete num characters after the cursor
11932fe07f8SJohn Marino */
12012db70c8Szrj libedit_private void
c_delafter(EditLine * el,int num)12132fe07f8SJohn Marino c_delafter(EditLine *el, int num)
12232fe07f8SJohn Marino {
12332fe07f8SJohn Marino
12432fe07f8SJohn Marino if (el->el_line.cursor + num > el->el_line.lastchar)
12532fe07f8SJohn Marino num = (int)(el->el_line.lastchar - el->el_line.cursor);
12632fe07f8SJohn Marino
12732fe07f8SJohn Marino if (el->el_map.current != el->el_map.emacs) {
12832fe07f8SJohn Marino cv_undo(el);
12932fe07f8SJohn Marino cv_yank(el, el->el_line.cursor, num);
13032fe07f8SJohn Marino }
13132fe07f8SJohn Marino
13232fe07f8SJohn Marino if (num > 0) {
13312db70c8Szrj wchar_t *cp;
13432fe07f8SJohn Marino
13532fe07f8SJohn Marino for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
13632fe07f8SJohn Marino *cp = cp[num];
13732fe07f8SJohn Marino
13832fe07f8SJohn Marino el->el_line.lastchar -= num;
13932fe07f8SJohn Marino }
14032fe07f8SJohn Marino }
14132fe07f8SJohn Marino
14232fe07f8SJohn Marino
14332fe07f8SJohn Marino /* c_delafter1():
14432fe07f8SJohn Marino * Delete the character after the cursor, do not yank
14532fe07f8SJohn Marino */
14612db70c8Szrj libedit_private void
c_delafter1(EditLine * el)14732fe07f8SJohn Marino c_delafter1(EditLine *el)
14832fe07f8SJohn Marino {
14912db70c8Szrj wchar_t *cp;
15032fe07f8SJohn Marino
15132fe07f8SJohn Marino for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
15232fe07f8SJohn Marino *cp = cp[1];
15332fe07f8SJohn Marino
15432fe07f8SJohn Marino el->el_line.lastchar--;
15532fe07f8SJohn Marino }
15632fe07f8SJohn Marino
15732fe07f8SJohn Marino
15832fe07f8SJohn Marino /* c_delbefore():
15932fe07f8SJohn Marino * Delete num characters before the cursor
16032fe07f8SJohn Marino */
16112db70c8Szrj libedit_private void
c_delbefore(EditLine * el,int num)16232fe07f8SJohn Marino c_delbefore(EditLine *el, int num)
16332fe07f8SJohn Marino {
16432fe07f8SJohn Marino
16532fe07f8SJohn Marino if (el->el_line.cursor - num < el->el_line.buffer)
16632fe07f8SJohn Marino num = (int)(el->el_line.cursor - el->el_line.buffer);
16732fe07f8SJohn Marino
16832fe07f8SJohn Marino if (el->el_map.current != el->el_map.emacs) {
16932fe07f8SJohn Marino cv_undo(el);
17032fe07f8SJohn Marino cv_yank(el, el->el_line.cursor - num, num);
17132fe07f8SJohn Marino }
17232fe07f8SJohn Marino
17332fe07f8SJohn Marino if (num > 0) {
17412db70c8Szrj wchar_t *cp;
17532fe07f8SJohn Marino
17632fe07f8SJohn Marino for (cp = el->el_line.cursor - num;
17760ecde0cSDaniel Fojt &cp[num] <= el->el_line.lastchar;
17832fe07f8SJohn Marino cp++)
17932fe07f8SJohn Marino *cp = cp[num];
18032fe07f8SJohn Marino
18132fe07f8SJohn Marino el->el_line.lastchar -= num;
18232fe07f8SJohn Marino }
18332fe07f8SJohn Marino }
18432fe07f8SJohn Marino
18532fe07f8SJohn Marino
18632fe07f8SJohn Marino /* c_delbefore1():
18732fe07f8SJohn Marino * Delete the character before the cursor, do not yank
18832fe07f8SJohn Marino */
18912db70c8Szrj libedit_private void
c_delbefore1(EditLine * el)19032fe07f8SJohn Marino c_delbefore1(EditLine *el)
19132fe07f8SJohn Marino {
19212db70c8Szrj wchar_t *cp;
19332fe07f8SJohn Marino
19432fe07f8SJohn Marino for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
19532fe07f8SJohn Marino *cp = cp[1];
19632fe07f8SJohn Marino
19732fe07f8SJohn Marino el->el_line.lastchar--;
19832fe07f8SJohn Marino }
19932fe07f8SJohn Marino
20032fe07f8SJohn Marino
20132fe07f8SJohn Marino /* ce__isword():
20232fe07f8SJohn Marino * Return if p is part of a word according to emacs
20332fe07f8SJohn Marino */
20412db70c8Szrj libedit_private int
ce__isword(wint_t p)20512db70c8Szrj ce__isword(wint_t p)
20632fe07f8SJohn Marino {
20712db70c8Szrj return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
20832fe07f8SJohn Marino }
20932fe07f8SJohn Marino
21032fe07f8SJohn Marino
21132fe07f8SJohn Marino /* cv__isword():
21232fe07f8SJohn Marino * Return if p is part of a word according to vi
21332fe07f8SJohn Marino */
21412db70c8Szrj libedit_private int
cv__isword(wint_t p)21512db70c8Szrj cv__isword(wint_t p)
21632fe07f8SJohn Marino {
21712db70c8Szrj if (iswalnum(p) || p == L'_')
21832fe07f8SJohn Marino return 1;
21912db70c8Szrj if (iswgraph(p))
22032fe07f8SJohn Marino return 2;
22132fe07f8SJohn Marino return 0;
22232fe07f8SJohn Marino }
22332fe07f8SJohn Marino
22432fe07f8SJohn Marino
22532fe07f8SJohn Marino /* cv__isWord():
22632fe07f8SJohn Marino * Return if p is part of a big word according to vi
22732fe07f8SJohn Marino */
22812db70c8Szrj libedit_private int
cv__isWord(wint_t p)22912db70c8Szrj cv__isWord(wint_t p)
23032fe07f8SJohn Marino {
23112db70c8Szrj return !iswspace(p);
23232fe07f8SJohn Marino }
23332fe07f8SJohn Marino
23432fe07f8SJohn Marino
23532fe07f8SJohn Marino /* c__prev_word():
23632fe07f8SJohn Marino * Find the previous word
23732fe07f8SJohn Marino */
23812db70c8Szrj libedit_private wchar_t *
c__prev_word(wchar_t * p,wchar_t * low,int n,int (* wtest)(wint_t))23912db70c8Szrj c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
24032fe07f8SJohn Marino {
24132fe07f8SJohn Marino p--;
24232fe07f8SJohn Marino
24332fe07f8SJohn Marino while (n--) {
24432fe07f8SJohn Marino while ((p >= low) && !(*wtest)(*p))
24532fe07f8SJohn Marino p--;
24632fe07f8SJohn Marino while ((p >= low) && (*wtest)(*p))
24732fe07f8SJohn Marino p--;
24832fe07f8SJohn Marino }
24932fe07f8SJohn Marino
25032fe07f8SJohn Marino /* cp now points to one character before the word */
25132fe07f8SJohn Marino p++;
25232fe07f8SJohn Marino if (p < low)
25332fe07f8SJohn Marino p = low;
25432fe07f8SJohn Marino /* cp now points where we want it */
25532fe07f8SJohn Marino return p;
25632fe07f8SJohn Marino }
25732fe07f8SJohn Marino
25832fe07f8SJohn Marino
25932fe07f8SJohn Marino /* c__next_word():
26032fe07f8SJohn Marino * Find the next word
26132fe07f8SJohn Marino */
26212db70c8Szrj libedit_private wchar_t *
c__next_word(wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))26312db70c8Szrj c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
26432fe07f8SJohn Marino {
26532fe07f8SJohn Marino while (n--) {
26632fe07f8SJohn Marino while ((p < high) && !(*wtest)(*p))
26732fe07f8SJohn Marino p++;
26832fe07f8SJohn Marino while ((p < high) && (*wtest)(*p))
26932fe07f8SJohn Marino p++;
27032fe07f8SJohn Marino }
27132fe07f8SJohn Marino if (p > high)
27232fe07f8SJohn Marino p = high;
27332fe07f8SJohn Marino /* p now points where we want it */
27432fe07f8SJohn Marino return p;
27532fe07f8SJohn Marino }
27632fe07f8SJohn Marino
27732fe07f8SJohn Marino /* cv_next_word():
27832fe07f8SJohn Marino * Find the next word vi style
27932fe07f8SJohn Marino */
28012db70c8Szrj libedit_private wchar_t *
cv_next_word(EditLine * el,wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))28112db70c8Szrj cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
28212db70c8Szrj int (*wtest)(wint_t))
28332fe07f8SJohn Marino {
28432fe07f8SJohn Marino int test;
28532fe07f8SJohn Marino
28632fe07f8SJohn Marino while (n--) {
28732fe07f8SJohn Marino test = (*wtest)(*p);
28832fe07f8SJohn Marino while ((p < high) && (*wtest)(*p) == test)
28932fe07f8SJohn Marino p++;
29032fe07f8SJohn Marino /*
29132fe07f8SJohn Marino * vi historically deletes with cw only the word preserving the
29232fe07f8SJohn Marino * trailing whitespace! This is not what 'w' does..
29332fe07f8SJohn Marino */
29432fe07f8SJohn Marino if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
29512db70c8Szrj while ((p < high) && iswspace(*p))
29632fe07f8SJohn Marino p++;
29732fe07f8SJohn Marino }
29832fe07f8SJohn Marino
29932fe07f8SJohn Marino /* p now points where we want it */
30032fe07f8SJohn Marino if (p > high)
30132fe07f8SJohn Marino return high;
30232fe07f8SJohn Marino else
30332fe07f8SJohn Marino return p;
30432fe07f8SJohn Marino }
30532fe07f8SJohn Marino
30632fe07f8SJohn Marino
30732fe07f8SJohn Marino /* cv_prev_word():
30832fe07f8SJohn Marino * Find the previous word vi style
30932fe07f8SJohn Marino */
31012db70c8Szrj libedit_private wchar_t *
cv_prev_word(wchar_t * p,wchar_t * low,int n,int (* wtest)(wint_t))31112db70c8Szrj cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
31232fe07f8SJohn Marino {
31332fe07f8SJohn Marino int test;
31432fe07f8SJohn Marino
31532fe07f8SJohn Marino p--;
31632fe07f8SJohn Marino while (n--) {
31712db70c8Szrj while ((p > low) && iswspace(*p))
31832fe07f8SJohn Marino p--;
31932fe07f8SJohn Marino test = (*wtest)(*p);
32032fe07f8SJohn Marino while ((p >= low) && (*wtest)(*p) == test)
32132fe07f8SJohn Marino p--;
32232fe07f8SJohn Marino }
32332fe07f8SJohn Marino p++;
32432fe07f8SJohn Marino
32532fe07f8SJohn Marino /* p now points where we want it */
32632fe07f8SJohn Marino if (p < low)
32732fe07f8SJohn Marino return low;
32832fe07f8SJohn Marino else
32932fe07f8SJohn Marino return p;
33032fe07f8SJohn Marino }
33132fe07f8SJohn Marino
33232fe07f8SJohn Marino
33332fe07f8SJohn Marino /* cv_delfini():
33432fe07f8SJohn Marino * Finish vi delete action
33532fe07f8SJohn Marino */
33612db70c8Szrj libedit_private void
cv_delfini(EditLine * el)33732fe07f8SJohn Marino cv_delfini(EditLine *el)
33832fe07f8SJohn Marino {
33932fe07f8SJohn Marino int size;
34032fe07f8SJohn Marino int action = el->el_chared.c_vcmd.action;
34132fe07f8SJohn Marino
34232fe07f8SJohn Marino if (action & INSERT)
34332fe07f8SJohn Marino el->el_map.current = el->el_map.key;
34432fe07f8SJohn Marino
34532fe07f8SJohn Marino if (el->el_chared.c_vcmd.pos == 0)
34632fe07f8SJohn Marino /* sanity */
34732fe07f8SJohn Marino return;
34832fe07f8SJohn Marino
34932fe07f8SJohn Marino size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
35032fe07f8SJohn Marino if (size == 0)
35132fe07f8SJohn Marino size = 1;
35232fe07f8SJohn Marino el->el_line.cursor = el->el_chared.c_vcmd.pos;
35332fe07f8SJohn Marino if (action & YANK) {
35432fe07f8SJohn Marino if (size > 0)
35532fe07f8SJohn Marino cv_yank(el, el->el_line.cursor, size);
35632fe07f8SJohn Marino else
35732fe07f8SJohn Marino cv_yank(el, el->el_line.cursor + size, -size);
35832fe07f8SJohn Marino } else {
35932fe07f8SJohn Marino if (size > 0) {
36032fe07f8SJohn Marino c_delafter(el, size);
36132fe07f8SJohn Marino re_refresh_cursor(el);
36232fe07f8SJohn Marino } else {
36332fe07f8SJohn Marino c_delbefore(el, -size);
36432fe07f8SJohn Marino el->el_line.cursor += size;
36532fe07f8SJohn Marino }
36632fe07f8SJohn Marino }
36732fe07f8SJohn Marino el->el_chared.c_vcmd.action = NOP;
36832fe07f8SJohn Marino }
36932fe07f8SJohn Marino
37032fe07f8SJohn Marino
37132fe07f8SJohn Marino /* cv__endword():
37232fe07f8SJohn Marino * Go to the end of this word according to vi
37332fe07f8SJohn Marino */
37412db70c8Szrj libedit_private wchar_t *
cv__endword(wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))37512db70c8Szrj cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
37632fe07f8SJohn Marino {
37732fe07f8SJohn Marino int test;
37832fe07f8SJohn Marino
37932fe07f8SJohn Marino p++;
38032fe07f8SJohn Marino
38132fe07f8SJohn Marino while (n--) {
38212db70c8Szrj while ((p < high) && iswspace(*p))
38332fe07f8SJohn Marino p++;
38432fe07f8SJohn Marino
38532fe07f8SJohn Marino test = (*wtest)(*p);
38632fe07f8SJohn Marino while ((p < high) && (*wtest)(*p) == test)
38732fe07f8SJohn Marino p++;
38832fe07f8SJohn Marino }
38932fe07f8SJohn Marino p--;
39032fe07f8SJohn Marino return p;
39132fe07f8SJohn Marino }
39232fe07f8SJohn Marino
39332fe07f8SJohn Marino /* ch_init():
39432fe07f8SJohn Marino * Initialize the character editor
39532fe07f8SJohn Marino */
39612db70c8Szrj libedit_private int
ch_init(EditLine * el)39732fe07f8SJohn Marino ch_init(EditLine *el)
39832fe07f8SJohn Marino {
39960ecde0cSDaniel Fojt el->el_line.buffer = el_calloc(EL_BUFSIZ,
40032fe07f8SJohn Marino sizeof(*el->el_line.buffer));
40132fe07f8SJohn Marino if (el->el_line.buffer == NULL)
40232fe07f8SJohn Marino return -1;
40332fe07f8SJohn Marino
40432fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
40532fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer;
40632fe07f8SJohn Marino el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
40732fe07f8SJohn Marino
40860ecde0cSDaniel Fojt el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ,
40932fe07f8SJohn Marino sizeof(*el->el_chared.c_undo.buf));
41032fe07f8SJohn Marino if (el->el_chared.c_undo.buf == NULL)
41132fe07f8SJohn Marino return -1;
41232fe07f8SJohn Marino el->el_chared.c_undo.len = -1;
41332fe07f8SJohn Marino el->el_chared.c_undo.cursor = 0;
41460ecde0cSDaniel Fojt el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ,
41532fe07f8SJohn Marino sizeof(*el->el_chared.c_redo.buf));
41632fe07f8SJohn Marino if (el->el_chared.c_redo.buf == NULL)
41732fe07f8SJohn Marino return -1;
41832fe07f8SJohn Marino el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
41932fe07f8SJohn Marino el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
42032fe07f8SJohn Marino el->el_chared.c_redo.cmd = ED_UNASSIGNED;
42132fe07f8SJohn Marino
42232fe07f8SJohn Marino el->el_chared.c_vcmd.action = NOP;
42332fe07f8SJohn Marino el->el_chared.c_vcmd.pos = el->el_line.buffer;
42432fe07f8SJohn Marino
42560ecde0cSDaniel Fojt el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ,
42632fe07f8SJohn Marino sizeof(*el->el_chared.c_kill.buf));
42732fe07f8SJohn Marino if (el->el_chared.c_kill.buf == NULL)
42832fe07f8SJohn Marino return -1;
42932fe07f8SJohn Marino el->el_chared.c_kill.mark = el->el_line.buffer;
43032fe07f8SJohn Marino el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
43132fe07f8SJohn Marino el->el_chared.c_resizefun = NULL;
43232fe07f8SJohn Marino el->el_chared.c_resizearg = NULL;
43384b940c1SJohn Marino el->el_chared.c_aliasfun = NULL;
43484b940c1SJohn Marino el->el_chared.c_aliasarg = NULL;
43532fe07f8SJohn Marino
43632fe07f8SJohn Marino el->el_map.current = el->el_map.key;
43732fe07f8SJohn Marino
43832fe07f8SJohn Marino el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
43932fe07f8SJohn Marino el->el_state.doingarg = 0;
44032fe07f8SJohn Marino el->el_state.metanext = 0;
44132fe07f8SJohn Marino el->el_state.argument = 1;
44232fe07f8SJohn Marino el->el_state.lastcmd = ED_UNASSIGNED;
44332fe07f8SJohn Marino
44432fe07f8SJohn Marino return 0;
44532fe07f8SJohn Marino }
44632fe07f8SJohn Marino
44732fe07f8SJohn Marino /* ch_reset():
44832fe07f8SJohn Marino * Reset the character editor
44932fe07f8SJohn Marino */
45012db70c8Szrj libedit_private void
ch_reset(EditLine * el)45112db70c8Szrj ch_reset(EditLine *el)
45232fe07f8SJohn Marino {
45332fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
45432fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer;
45532fe07f8SJohn Marino
45632fe07f8SJohn Marino el->el_chared.c_undo.len = -1;
45732fe07f8SJohn Marino el->el_chared.c_undo.cursor = 0;
45832fe07f8SJohn Marino
45932fe07f8SJohn Marino el->el_chared.c_vcmd.action = NOP;
46032fe07f8SJohn Marino el->el_chared.c_vcmd.pos = el->el_line.buffer;
46132fe07f8SJohn Marino
46232fe07f8SJohn Marino el->el_chared.c_kill.mark = el->el_line.buffer;
46332fe07f8SJohn Marino
46432fe07f8SJohn Marino el->el_map.current = el->el_map.key;
46532fe07f8SJohn Marino
46632fe07f8SJohn Marino el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
46732fe07f8SJohn Marino el->el_state.doingarg = 0;
46832fe07f8SJohn Marino el->el_state.metanext = 0;
46932fe07f8SJohn Marino el->el_state.argument = 1;
47032fe07f8SJohn Marino el->el_state.lastcmd = ED_UNASSIGNED;
47132fe07f8SJohn Marino
47232fe07f8SJohn Marino el->el_history.eventno = 0;
47332fe07f8SJohn Marino }
47432fe07f8SJohn Marino
47532fe07f8SJohn Marino /* ch_enlargebufs():
47632fe07f8SJohn Marino * Enlarge line buffer to be able to hold twice as much characters.
47732fe07f8SJohn Marino * Returns 1 if successful, 0 if not.
47832fe07f8SJohn Marino */
47912db70c8Szrj libedit_private int
ch_enlargebufs(EditLine * el,size_t addlen)48032fe07f8SJohn Marino ch_enlargebufs(EditLine *el, size_t addlen)
48132fe07f8SJohn Marino {
48232fe07f8SJohn Marino size_t sz, newsz;
48312db70c8Szrj wchar_t *newbuffer, *oldbuf, *oldkbuf;
48432fe07f8SJohn Marino
48532fe07f8SJohn Marino sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
48632fe07f8SJohn Marino newsz = sz * 2;
48732fe07f8SJohn Marino /*
48832fe07f8SJohn Marino * If newly required length is longer than current buffer, we need
48932fe07f8SJohn Marino * to make the buffer big enough to hold both old and new stuff.
49032fe07f8SJohn Marino */
49132fe07f8SJohn Marino if (addlen > sz) {
49232fe07f8SJohn Marino while(newsz - sz < addlen)
49332fe07f8SJohn Marino newsz *= 2;
49432fe07f8SJohn Marino }
49532fe07f8SJohn Marino
49632fe07f8SJohn Marino /*
49732fe07f8SJohn Marino * Reallocate line buffer.
49832fe07f8SJohn Marino */
49932fe07f8SJohn Marino newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
50032fe07f8SJohn Marino if (!newbuffer)
50132fe07f8SJohn Marino return 0;
50232fe07f8SJohn Marino
50332fe07f8SJohn Marino /* zero the newly added memory, leave old data in */
50432fe07f8SJohn Marino (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
50532fe07f8SJohn Marino
50632fe07f8SJohn Marino oldbuf = el->el_line.buffer;
50732fe07f8SJohn Marino
50832fe07f8SJohn Marino el->el_line.buffer = newbuffer;
50932fe07f8SJohn Marino el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
51032fe07f8SJohn Marino el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
51132fe07f8SJohn Marino /* don't set new size until all buffers are enlarged */
51232fe07f8SJohn Marino el->el_line.limit = &newbuffer[sz - EL_LEAVE];
51332fe07f8SJohn Marino
51432fe07f8SJohn Marino /*
51532fe07f8SJohn Marino * Reallocate kill buffer.
51632fe07f8SJohn Marino */
51732fe07f8SJohn Marino newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
51832fe07f8SJohn Marino sizeof(*newbuffer));
51932fe07f8SJohn Marino if (!newbuffer)
52032fe07f8SJohn Marino return 0;
52132fe07f8SJohn Marino
52232fe07f8SJohn Marino /* zero the newly added memory, leave old data in */
52332fe07f8SJohn Marino (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
52432fe07f8SJohn Marino
52532fe07f8SJohn Marino oldkbuf = el->el_chared.c_kill.buf;
52632fe07f8SJohn Marino
52732fe07f8SJohn Marino el->el_chared.c_kill.buf = newbuffer;
52832fe07f8SJohn Marino el->el_chared.c_kill.last = newbuffer +
52932fe07f8SJohn Marino (el->el_chared.c_kill.last - oldkbuf);
53032fe07f8SJohn Marino el->el_chared.c_kill.mark = el->el_line.buffer +
53132fe07f8SJohn Marino (el->el_chared.c_kill.mark - oldbuf);
53232fe07f8SJohn Marino
53332fe07f8SJohn Marino /*
53432fe07f8SJohn Marino * Reallocate undo buffer.
53532fe07f8SJohn Marino */
53632fe07f8SJohn Marino newbuffer = el_realloc(el->el_chared.c_undo.buf,
53732fe07f8SJohn Marino newsz * sizeof(*newbuffer));
53832fe07f8SJohn Marino if (!newbuffer)
53932fe07f8SJohn Marino return 0;
54032fe07f8SJohn Marino
54132fe07f8SJohn Marino /* zero the newly added memory, leave old data in */
54232fe07f8SJohn Marino (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
54332fe07f8SJohn Marino el->el_chared.c_undo.buf = newbuffer;
54432fe07f8SJohn Marino
54532fe07f8SJohn Marino newbuffer = el_realloc(el->el_chared.c_redo.buf,
54632fe07f8SJohn Marino newsz * sizeof(*newbuffer));
54732fe07f8SJohn Marino if (!newbuffer)
54832fe07f8SJohn Marino return 0;
54932fe07f8SJohn Marino el->el_chared.c_redo.pos = newbuffer +
55032fe07f8SJohn Marino (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
55132fe07f8SJohn Marino el->el_chared.c_redo.lim = newbuffer +
55232fe07f8SJohn Marino (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
55332fe07f8SJohn Marino el->el_chared.c_redo.buf = newbuffer;
55432fe07f8SJohn Marino
55532fe07f8SJohn Marino if (!hist_enlargebuf(el, sz, newsz))
55632fe07f8SJohn Marino return 0;
55732fe07f8SJohn Marino
55832fe07f8SJohn Marino /* Safe to set enlarged buffer size */
55932fe07f8SJohn Marino el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
56032fe07f8SJohn Marino if (el->el_chared.c_resizefun)
56132fe07f8SJohn Marino (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
56232fe07f8SJohn Marino return 1;
56332fe07f8SJohn Marino }
56432fe07f8SJohn Marino
56532fe07f8SJohn Marino /* ch_end():
56632fe07f8SJohn Marino * Free the data structures used by the editor
56732fe07f8SJohn Marino */
56812db70c8Szrj libedit_private void
ch_end(EditLine * el)56932fe07f8SJohn Marino ch_end(EditLine *el)
57032fe07f8SJohn Marino {
57132fe07f8SJohn Marino el_free(el->el_line.buffer);
57232fe07f8SJohn Marino el->el_line.buffer = NULL;
57332fe07f8SJohn Marino el->el_line.limit = NULL;
57432fe07f8SJohn Marino el_free(el->el_chared.c_undo.buf);
57532fe07f8SJohn Marino el->el_chared.c_undo.buf = NULL;
57632fe07f8SJohn Marino el_free(el->el_chared.c_redo.buf);
57732fe07f8SJohn Marino el->el_chared.c_redo.buf = NULL;
57832fe07f8SJohn Marino el->el_chared.c_redo.pos = NULL;
57932fe07f8SJohn Marino el->el_chared.c_redo.lim = NULL;
58032fe07f8SJohn Marino el->el_chared.c_redo.cmd = ED_UNASSIGNED;
58132fe07f8SJohn Marino el_free(el->el_chared.c_kill.buf);
58232fe07f8SJohn Marino el->el_chared.c_kill.buf = NULL;
58312db70c8Szrj ch_reset(el);
58432fe07f8SJohn Marino }
58532fe07f8SJohn Marino
58632fe07f8SJohn Marino
58732fe07f8SJohn Marino /* el_insertstr():
588ae19eda8Szrj * Insert string at cursor
58932fe07f8SJohn Marino */
59012db70c8Szrj int
el_winsertstr(EditLine * el,const wchar_t * s)59112db70c8Szrj el_winsertstr(EditLine *el, const wchar_t *s)
59232fe07f8SJohn Marino {
59332fe07f8SJohn Marino size_t len;
59432fe07f8SJohn Marino
59512db70c8Szrj if (s == NULL || (len = wcslen(s)) == 0)
59632fe07f8SJohn Marino return -1;
59732fe07f8SJohn Marino if (el->el_line.lastchar + len >= el->el_line.limit) {
59832fe07f8SJohn Marino if (!ch_enlargebufs(el, len))
59932fe07f8SJohn Marino return -1;
60032fe07f8SJohn Marino }
60132fe07f8SJohn Marino
60232fe07f8SJohn Marino c_insert(el, (int)len);
60332fe07f8SJohn Marino while (*s)
60432fe07f8SJohn Marino *el->el_line.cursor++ = *s++;
60532fe07f8SJohn Marino return 0;
60632fe07f8SJohn Marino }
60732fe07f8SJohn Marino
60832fe07f8SJohn Marino
60932fe07f8SJohn Marino /* el_deletestr():
61032fe07f8SJohn Marino * Delete num characters before the cursor
61132fe07f8SJohn Marino */
61212db70c8Szrj void
el_deletestr(EditLine * el,int n)61332fe07f8SJohn Marino el_deletestr(EditLine *el, int n)
61432fe07f8SJohn Marino {
61532fe07f8SJohn Marino if (n <= 0)
61632fe07f8SJohn Marino return;
61732fe07f8SJohn Marino
61832fe07f8SJohn Marino if (el->el_line.cursor < &el->el_line.buffer[n])
61932fe07f8SJohn Marino return;
62032fe07f8SJohn Marino
62132fe07f8SJohn Marino c_delbefore(el, n); /* delete before dot */
62232fe07f8SJohn Marino el->el_line.cursor -= n;
62332fe07f8SJohn Marino if (el->el_line.cursor < el->el_line.buffer)
62432fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
62532fe07f8SJohn Marino }
62632fe07f8SJohn Marino
627*cdf8408cSAntonio Huete Jimenez /* el_deletestr1():
628*cdf8408cSAntonio Huete Jimenez * Delete characters between start and end
629*cdf8408cSAntonio Huete Jimenez */
630*cdf8408cSAntonio Huete Jimenez int
el_deletestr1(EditLine * el,int start,int end)631*cdf8408cSAntonio Huete Jimenez el_deletestr1(EditLine *el, int start, int end)
632*cdf8408cSAntonio Huete Jimenez {
633*cdf8408cSAntonio Huete Jimenez size_t line_length, len;
634*cdf8408cSAntonio Huete Jimenez wchar_t *p1, *p2;
635*cdf8408cSAntonio Huete Jimenez
636*cdf8408cSAntonio Huete Jimenez if (end <= start)
637*cdf8408cSAntonio Huete Jimenez return 0;
638*cdf8408cSAntonio Huete Jimenez
639*cdf8408cSAntonio Huete Jimenez line_length = (size_t)(el->el_line.lastchar - el->el_line.buffer);
640*cdf8408cSAntonio Huete Jimenez
641*cdf8408cSAntonio Huete Jimenez if (start >= (int)line_length || end >= (int)line_length)
642*cdf8408cSAntonio Huete Jimenez return 0;
643*cdf8408cSAntonio Huete Jimenez
644*cdf8408cSAntonio Huete Jimenez len = (size_t)(end - start);
645*cdf8408cSAntonio Huete Jimenez if (len > line_length - (size_t)end)
646*cdf8408cSAntonio Huete Jimenez len = line_length - (size_t)end;
647*cdf8408cSAntonio Huete Jimenez
648*cdf8408cSAntonio Huete Jimenez p1 = el->el_line.buffer + start;
649*cdf8408cSAntonio Huete Jimenez p2 = el->el_line.buffer + end;
650*cdf8408cSAntonio Huete Jimenez for (size_t i = 0; i < len; i++) {
651*cdf8408cSAntonio Huete Jimenez *p1++ = *p2++;
652*cdf8408cSAntonio Huete Jimenez el->el_line.lastchar--;
653*cdf8408cSAntonio Huete Jimenez }
654*cdf8408cSAntonio Huete Jimenez
655*cdf8408cSAntonio Huete Jimenez if (el->el_line.cursor < el->el_line.buffer)
656*cdf8408cSAntonio Huete Jimenez el->el_line.cursor = el->el_line.buffer;
657*cdf8408cSAntonio Huete Jimenez
658*cdf8408cSAntonio Huete Jimenez return end - start;
659*cdf8408cSAntonio Huete Jimenez }
660*cdf8408cSAntonio Huete Jimenez
661*cdf8408cSAntonio Huete Jimenez /* el_wreplacestr():
662*cdf8408cSAntonio Huete Jimenez * Replace the contents of the line with the provided string
663*cdf8408cSAntonio Huete Jimenez */
664*cdf8408cSAntonio Huete Jimenez int
el_wreplacestr(EditLine * el,const wchar_t * s)665*cdf8408cSAntonio Huete Jimenez el_wreplacestr(EditLine *el, const wchar_t *s)
666*cdf8408cSAntonio Huete Jimenez {
667*cdf8408cSAntonio Huete Jimenez size_t len;
668*cdf8408cSAntonio Huete Jimenez wchar_t * p;
669*cdf8408cSAntonio Huete Jimenez
670*cdf8408cSAntonio Huete Jimenez if (s == NULL || (len = wcslen(s)) == 0)
671*cdf8408cSAntonio Huete Jimenez return -1;
672*cdf8408cSAntonio Huete Jimenez
673*cdf8408cSAntonio Huete Jimenez if (el->el_line.buffer + len >= el->el_line.limit) {
674*cdf8408cSAntonio Huete Jimenez if (!ch_enlargebufs(el, len))
675*cdf8408cSAntonio Huete Jimenez return -1;
676*cdf8408cSAntonio Huete Jimenez }
677*cdf8408cSAntonio Huete Jimenez
678*cdf8408cSAntonio Huete Jimenez p = el->el_line.buffer;
679*cdf8408cSAntonio Huete Jimenez for (size_t i = 0; i < len; i++)
680*cdf8408cSAntonio Huete Jimenez *p++ = *s++;
681*cdf8408cSAntonio Huete Jimenez
682*cdf8408cSAntonio Huete Jimenez el->el_line.buffer[len] = '\0';
683*cdf8408cSAntonio Huete Jimenez el->el_line.lastchar = el->el_line.buffer + len;
684*cdf8408cSAntonio Huete Jimenez if (el->el_line.cursor > el->el_line.lastchar)
685*cdf8408cSAntonio Huete Jimenez el->el_line.cursor = el->el_line.lastchar;
686*cdf8408cSAntonio Huete Jimenez
687*cdf8408cSAntonio Huete Jimenez return 0;
688*cdf8408cSAntonio Huete Jimenez }
689*cdf8408cSAntonio Huete Jimenez
69084b940c1SJohn Marino /* el_cursor():
69184b940c1SJohn Marino * Move the cursor to the left or the right of the current position
69284b940c1SJohn Marino */
69312db70c8Szrj int
el_cursor(EditLine * el,int n)69484b940c1SJohn Marino el_cursor(EditLine *el, int n)
69584b940c1SJohn Marino {
69684b940c1SJohn Marino if (n == 0)
69784b940c1SJohn Marino goto out;
69884b940c1SJohn Marino
69984b940c1SJohn Marino el->el_line.cursor += n;
70084b940c1SJohn Marino
70184b940c1SJohn Marino if (el->el_line.cursor < el->el_line.buffer)
70284b940c1SJohn Marino el->el_line.cursor = el->el_line.buffer;
70384b940c1SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
70484b940c1SJohn Marino el->el_line.cursor = el->el_line.lastchar;
70584b940c1SJohn Marino out:
70684b940c1SJohn Marino return (int)(el->el_line.cursor - el->el_line.buffer);
70784b940c1SJohn Marino }
70884b940c1SJohn Marino
70932fe07f8SJohn Marino /* c_gets():
71032fe07f8SJohn Marino * Get a string
71132fe07f8SJohn Marino */
71212db70c8Szrj libedit_private int
c_gets(EditLine * el,wchar_t * buf,const wchar_t * prompt)71312db70c8Szrj c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
71432fe07f8SJohn Marino {
71532fe07f8SJohn Marino ssize_t len;
71612db70c8Szrj wchar_t *cp = el->el_line.buffer, ch;
71732fe07f8SJohn Marino
71832fe07f8SJohn Marino if (prompt) {
71912db70c8Szrj len = (ssize_t)wcslen(prompt);
72032fe07f8SJohn Marino (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
72132fe07f8SJohn Marino cp += len;
72232fe07f8SJohn Marino }
72332fe07f8SJohn Marino len = 0;
72432fe07f8SJohn Marino
72532fe07f8SJohn Marino for (;;) {
72632fe07f8SJohn Marino el->el_line.cursor = cp;
72732fe07f8SJohn Marino *cp = ' ';
72832fe07f8SJohn Marino el->el_line.lastchar = cp + 1;
72932fe07f8SJohn Marino re_refresh(el);
73032fe07f8SJohn Marino
73112db70c8Szrj if (el_wgetc(el, &ch) != 1) {
73232fe07f8SJohn Marino ed_end_of_file(el, 0);
73332fe07f8SJohn Marino len = -1;
73432fe07f8SJohn Marino break;
73532fe07f8SJohn Marino }
73632fe07f8SJohn Marino
73732fe07f8SJohn Marino switch (ch) {
73832fe07f8SJohn Marino
73912db70c8Szrj case L'\b': /* Delete and backspace */
74032fe07f8SJohn Marino case 0177:
74132fe07f8SJohn Marino if (len == 0) {
74232fe07f8SJohn Marino len = -1;
74332fe07f8SJohn Marino break;
74432fe07f8SJohn Marino }
74512db70c8Szrj len--;
74632fe07f8SJohn Marino cp--;
74732fe07f8SJohn Marino continue;
74832fe07f8SJohn Marino
74932fe07f8SJohn Marino case 0033: /* ESC */
75012db70c8Szrj case L'\r': /* Newline */
75112db70c8Szrj case L'\n':
75232fe07f8SJohn Marino buf[len] = ch;
75332fe07f8SJohn Marino break;
75432fe07f8SJohn Marino
75532fe07f8SJohn Marino default:
75632fe07f8SJohn Marino if (len >= (ssize_t)(EL_BUFSIZ - 16))
75732fe07f8SJohn Marino terminal_beep(el);
75832fe07f8SJohn Marino else {
75932fe07f8SJohn Marino buf[len++] = ch;
76032fe07f8SJohn Marino *cp++ = ch;
76132fe07f8SJohn Marino }
76232fe07f8SJohn Marino continue;
76332fe07f8SJohn Marino }
76432fe07f8SJohn Marino break;
76532fe07f8SJohn Marino }
76632fe07f8SJohn Marino
76732fe07f8SJohn Marino el->el_line.buffer[0] = '\0';
76832fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer;
76932fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
77032fe07f8SJohn Marino return (int)len;
77132fe07f8SJohn Marino }
77232fe07f8SJohn Marino
77332fe07f8SJohn Marino
77432fe07f8SJohn Marino /* c_hpos():
77532fe07f8SJohn Marino * Return the current horizontal position of the cursor
77632fe07f8SJohn Marino */
77712db70c8Szrj libedit_private int
c_hpos(EditLine * el)77832fe07f8SJohn Marino c_hpos(EditLine *el)
77932fe07f8SJohn Marino {
78012db70c8Szrj wchar_t *ptr;
78132fe07f8SJohn Marino
78232fe07f8SJohn Marino /*
78332fe07f8SJohn Marino * Find how many characters till the beginning of this line.
78432fe07f8SJohn Marino */
78532fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer)
78632fe07f8SJohn Marino return 0;
78732fe07f8SJohn Marino else {
78832fe07f8SJohn Marino for (ptr = el->el_line.cursor - 1;
78932fe07f8SJohn Marino ptr >= el->el_line.buffer && *ptr != '\n';
79032fe07f8SJohn Marino ptr--)
79132fe07f8SJohn Marino continue;
79232fe07f8SJohn Marino return (int)(el->el_line.cursor - ptr - 1);
79332fe07f8SJohn Marino }
79432fe07f8SJohn Marino }
79532fe07f8SJohn Marino
79612db70c8Szrj libedit_private int
ch_resizefun(EditLine * el,el_zfunc_t f,void * a)79732fe07f8SJohn Marino ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
79832fe07f8SJohn Marino {
79932fe07f8SJohn Marino el->el_chared.c_resizefun = f;
80032fe07f8SJohn Marino el->el_chared.c_resizearg = a;
80132fe07f8SJohn Marino return 0;
80232fe07f8SJohn Marino }
80384b940c1SJohn Marino
80412db70c8Szrj libedit_private int
ch_aliasfun(EditLine * el,el_afunc_t f,void * a)80584b940c1SJohn Marino ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
80684b940c1SJohn Marino {
80784b940c1SJohn Marino el->el_chared.c_aliasfun = f;
80884b940c1SJohn Marino el->el_chared.c_aliasarg = a;
80984b940c1SJohn Marino return 0;
81084b940c1SJohn Marino }
811