1*baff8195SBaptiste Daroussin /* $NetBSD: chared.c,v 1.63 2022/10/30 19:11:31 christos Exp $ */
2d0ef721eSBaptiste Daroussin
3d0ef721eSBaptiste Daroussin /*-
4d0ef721eSBaptiste Daroussin * Copyright (c) 1992, 1993
5d0ef721eSBaptiste Daroussin * The Regents of the University of California. All rights reserved.
6d0ef721eSBaptiste Daroussin *
7d0ef721eSBaptiste Daroussin * This code is derived from software contributed to Berkeley by
8d0ef721eSBaptiste Daroussin * Christos Zoulas of Cornell University.
9d0ef721eSBaptiste Daroussin *
10d0ef721eSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without
11d0ef721eSBaptiste Daroussin * modification, are permitted provided that the following conditions
12d0ef721eSBaptiste Daroussin * are met:
13d0ef721eSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright
14d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer.
15d0ef721eSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright
16d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the
17d0ef721eSBaptiste Daroussin * documentation and/or other materials provided with the distribution.
18d0ef721eSBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors
19d0ef721eSBaptiste Daroussin * may be used to endorse or promote products derived from this software
20d0ef721eSBaptiste Daroussin * without specific prior written permission.
21d0ef721eSBaptiste Daroussin *
22d0ef721eSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23d0ef721eSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24d0ef721eSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25d0ef721eSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26d0ef721eSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27d0ef721eSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28d0ef721eSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29d0ef721eSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30d0ef721eSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31d0ef721eSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32d0ef721eSBaptiste Daroussin * SUCH DAMAGE.
33d0ef721eSBaptiste Daroussin */
34d0ef721eSBaptiste Daroussin
35d0ef721eSBaptiste Daroussin #include "config.h"
36d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID)
37d0ef721eSBaptiste Daroussin #if 0
38d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
39d0ef721eSBaptiste Daroussin #else
40*baff8195SBaptiste Daroussin __RCSID("$NetBSD: chared.c,v 1.63 2022/10/30 19:11:31 christos Exp $");
41d0ef721eSBaptiste Daroussin #endif
42d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */
43d0ef721eSBaptiste Daroussin
44d0ef721eSBaptiste Daroussin /*
45d0ef721eSBaptiste Daroussin * chared.c: Character editor utilities
46d0ef721eSBaptiste Daroussin */
47d0ef721eSBaptiste Daroussin #include <ctype.h>
48d0ef721eSBaptiste Daroussin #include <stdlib.h>
49d0ef721eSBaptiste Daroussin #include <string.h>
50d0ef721eSBaptiste Daroussin
51d0ef721eSBaptiste Daroussin #include "el.h"
52d0ef721eSBaptiste Daroussin #include "common.h"
53d0ef721eSBaptiste Daroussin #include "fcns.h"
54d0ef721eSBaptiste Daroussin
55d0ef721eSBaptiste Daroussin /* value to leave unused in line buffer */
56d0ef721eSBaptiste Daroussin #define EL_LEAVE 2
57d0ef721eSBaptiste Daroussin
58d0ef721eSBaptiste Daroussin /* cv_undo():
59d0ef721eSBaptiste Daroussin * Handle state for the vi undo command
60d0ef721eSBaptiste Daroussin */
61d0ef721eSBaptiste Daroussin libedit_private void
cv_undo(EditLine * el)62d0ef721eSBaptiste Daroussin cv_undo(EditLine *el)
63d0ef721eSBaptiste Daroussin {
64d0ef721eSBaptiste Daroussin c_undo_t *vu = &el->el_chared.c_undo;
65d0ef721eSBaptiste Daroussin c_redo_t *r = &el->el_chared.c_redo;
66d0ef721eSBaptiste Daroussin size_t size;
67d0ef721eSBaptiste Daroussin
68d0ef721eSBaptiste Daroussin /* Save entire line for undo */
69d0ef721eSBaptiste Daroussin size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
70d0ef721eSBaptiste Daroussin vu->len = (ssize_t)size;
71d0ef721eSBaptiste Daroussin vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
72d0ef721eSBaptiste Daroussin (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
73d0ef721eSBaptiste Daroussin
74d0ef721eSBaptiste Daroussin /* save command info for redo */
75d0ef721eSBaptiste Daroussin r->count = el->el_state.doingarg ? el->el_state.argument : 0;
76d0ef721eSBaptiste Daroussin r->action = el->el_chared.c_vcmd.action;
77d0ef721eSBaptiste Daroussin r->pos = r->buf;
78d0ef721eSBaptiste Daroussin r->cmd = el->el_state.thiscmd;
79d0ef721eSBaptiste Daroussin r->ch = el->el_state.thisch;
80d0ef721eSBaptiste Daroussin }
81d0ef721eSBaptiste Daroussin
82d0ef721eSBaptiste Daroussin /* cv_yank():
83d0ef721eSBaptiste Daroussin * Save yank/delete data for paste
84d0ef721eSBaptiste Daroussin */
85d0ef721eSBaptiste Daroussin libedit_private void
cv_yank(EditLine * el,const wchar_t * ptr,int size)86d0ef721eSBaptiste Daroussin cv_yank(EditLine *el, const wchar_t *ptr, int size)
87d0ef721eSBaptiste Daroussin {
88d0ef721eSBaptiste Daroussin c_kill_t *k = &el->el_chared.c_kill;
89d0ef721eSBaptiste Daroussin
90d0ef721eSBaptiste Daroussin (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
91d0ef721eSBaptiste Daroussin k->last = k->buf + size;
92d0ef721eSBaptiste Daroussin }
93d0ef721eSBaptiste Daroussin
94d0ef721eSBaptiste Daroussin
95d0ef721eSBaptiste Daroussin /* c_insert():
96d0ef721eSBaptiste Daroussin * Insert num characters
97d0ef721eSBaptiste Daroussin */
98d0ef721eSBaptiste Daroussin libedit_private void
c_insert(EditLine * el,int num)99d0ef721eSBaptiste Daroussin c_insert(EditLine *el, int num)
100d0ef721eSBaptiste Daroussin {
101d0ef721eSBaptiste Daroussin wchar_t *cp;
102d0ef721eSBaptiste Daroussin
103d0ef721eSBaptiste Daroussin if (el->el_line.lastchar + num >= el->el_line.limit) {
104d0ef721eSBaptiste Daroussin if (!ch_enlargebufs(el, (size_t)num))
105d0ef721eSBaptiste Daroussin return; /* can't go past end of buffer */
106d0ef721eSBaptiste Daroussin }
107d0ef721eSBaptiste Daroussin
108d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.lastchar) {
109d0ef721eSBaptiste Daroussin /* if I must move chars */
110d0ef721eSBaptiste Daroussin for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
111d0ef721eSBaptiste Daroussin cp[num] = *cp;
112d0ef721eSBaptiste Daroussin }
113d0ef721eSBaptiste Daroussin el->el_line.lastchar += num;
114d0ef721eSBaptiste Daroussin }
115d0ef721eSBaptiste Daroussin
116d0ef721eSBaptiste Daroussin
117d0ef721eSBaptiste Daroussin /* c_delafter():
118d0ef721eSBaptiste Daroussin * Delete num characters after the cursor
119d0ef721eSBaptiste Daroussin */
120d0ef721eSBaptiste Daroussin libedit_private void
c_delafter(EditLine * el,int num)121d0ef721eSBaptiste Daroussin c_delafter(EditLine *el, int num)
122d0ef721eSBaptiste Daroussin {
123d0ef721eSBaptiste Daroussin
124d0ef721eSBaptiste Daroussin if (el->el_line.cursor + num > el->el_line.lastchar)
125d0ef721eSBaptiste Daroussin num = (int)(el->el_line.lastchar - el->el_line.cursor);
126d0ef721eSBaptiste Daroussin
127d0ef721eSBaptiste Daroussin if (el->el_map.current != el->el_map.emacs) {
128d0ef721eSBaptiste Daroussin cv_undo(el);
129d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor, num);
130d0ef721eSBaptiste Daroussin }
131d0ef721eSBaptiste Daroussin
132d0ef721eSBaptiste Daroussin if (num > 0) {
133d0ef721eSBaptiste Daroussin wchar_t *cp;
134d0ef721eSBaptiste Daroussin
135d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
136d0ef721eSBaptiste Daroussin *cp = cp[num];
137d0ef721eSBaptiste Daroussin
138d0ef721eSBaptiste Daroussin el->el_line.lastchar -= num;
139d0ef721eSBaptiste Daroussin }
140d0ef721eSBaptiste Daroussin }
141d0ef721eSBaptiste Daroussin
142d0ef721eSBaptiste Daroussin
143d0ef721eSBaptiste Daroussin /* c_delafter1():
144d0ef721eSBaptiste Daroussin * Delete the character after the cursor, do not yank
145d0ef721eSBaptiste Daroussin */
146d0ef721eSBaptiste Daroussin libedit_private void
c_delafter1(EditLine * el)147d0ef721eSBaptiste Daroussin c_delafter1(EditLine *el)
148d0ef721eSBaptiste Daroussin {
149d0ef721eSBaptiste Daroussin wchar_t *cp;
150d0ef721eSBaptiste Daroussin
151d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
152d0ef721eSBaptiste Daroussin *cp = cp[1];
153d0ef721eSBaptiste Daroussin
154d0ef721eSBaptiste Daroussin el->el_line.lastchar--;
155d0ef721eSBaptiste Daroussin }
156d0ef721eSBaptiste Daroussin
157d0ef721eSBaptiste Daroussin
158d0ef721eSBaptiste Daroussin /* c_delbefore():
159d0ef721eSBaptiste Daroussin * Delete num characters before the cursor
160d0ef721eSBaptiste Daroussin */
161d0ef721eSBaptiste Daroussin libedit_private void
c_delbefore(EditLine * el,int num)162d0ef721eSBaptiste Daroussin c_delbefore(EditLine *el, int num)
163d0ef721eSBaptiste Daroussin {
164d0ef721eSBaptiste Daroussin
165d0ef721eSBaptiste Daroussin if (el->el_line.cursor - num < el->el_line.buffer)
166d0ef721eSBaptiste Daroussin num = (int)(el->el_line.cursor - el->el_line.buffer);
167d0ef721eSBaptiste Daroussin
168d0ef721eSBaptiste Daroussin if (el->el_map.current != el->el_map.emacs) {
169d0ef721eSBaptiste Daroussin cv_undo(el);
170d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor - num, num);
171d0ef721eSBaptiste Daroussin }
172d0ef721eSBaptiste Daroussin
173d0ef721eSBaptiste Daroussin if (num > 0) {
174d0ef721eSBaptiste Daroussin wchar_t *cp;
175d0ef721eSBaptiste Daroussin
176d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor - num;
177d0ef721eSBaptiste Daroussin &cp[num] <= el->el_line.lastchar;
178d0ef721eSBaptiste Daroussin cp++)
179d0ef721eSBaptiste Daroussin *cp = cp[num];
180d0ef721eSBaptiste Daroussin
181d0ef721eSBaptiste Daroussin el->el_line.lastchar -= num;
182d0ef721eSBaptiste Daroussin }
183d0ef721eSBaptiste Daroussin }
184d0ef721eSBaptiste Daroussin
185d0ef721eSBaptiste Daroussin
186d0ef721eSBaptiste Daroussin /* c_delbefore1():
187d0ef721eSBaptiste Daroussin * Delete the character before the cursor, do not yank
188d0ef721eSBaptiste Daroussin */
189d0ef721eSBaptiste Daroussin libedit_private void
c_delbefore1(EditLine * el)190d0ef721eSBaptiste Daroussin c_delbefore1(EditLine *el)
191d0ef721eSBaptiste Daroussin {
192d0ef721eSBaptiste Daroussin wchar_t *cp;
193d0ef721eSBaptiste Daroussin
194d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
195d0ef721eSBaptiste Daroussin *cp = cp[1];
196d0ef721eSBaptiste Daroussin
197d0ef721eSBaptiste Daroussin el->el_line.lastchar--;
198d0ef721eSBaptiste Daroussin }
199d0ef721eSBaptiste Daroussin
200d0ef721eSBaptiste Daroussin
201d0ef721eSBaptiste Daroussin /* ce__isword():
202d0ef721eSBaptiste Daroussin * Return if p is part of a word according to emacs
203d0ef721eSBaptiste Daroussin */
204d0ef721eSBaptiste Daroussin libedit_private int
ce__isword(wint_t p)205d0ef721eSBaptiste Daroussin ce__isword(wint_t p)
206d0ef721eSBaptiste Daroussin {
207d0ef721eSBaptiste Daroussin return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
208d0ef721eSBaptiste Daroussin }
209d0ef721eSBaptiste Daroussin
210d0ef721eSBaptiste Daroussin
211d0ef721eSBaptiste Daroussin /* cv__isword():
212d0ef721eSBaptiste Daroussin * Return if p is part of a word according to vi
213d0ef721eSBaptiste Daroussin */
214d0ef721eSBaptiste Daroussin libedit_private int
cv__isword(wint_t p)215d0ef721eSBaptiste Daroussin cv__isword(wint_t p)
216d0ef721eSBaptiste Daroussin {
217d0ef721eSBaptiste Daroussin if (iswalnum(p) || p == L'_')
218d0ef721eSBaptiste Daroussin return 1;
219d0ef721eSBaptiste Daroussin if (iswgraph(p))
220d0ef721eSBaptiste Daroussin return 2;
221d0ef721eSBaptiste Daroussin return 0;
222d0ef721eSBaptiste Daroussin }
223d0ef721eSBaptiste Daroussin
224d0ef721eSBaptiste Daroussin
225d0ef721eSBaptiste Daroussin /* cv__isWord():
226d0ef721eSBaptiste Daroussin * Return if p is part of a big word according to vi
227d0ef721eSBaptiste Daroussin */
228d0ef721eSBaptiste Daroussin libedit_private int
cv__isWord(wint_t p)229d0ef721eSBaptiste Daroussin cv__isWord(wint_t p)
230d0ef721eSBaptiste Daroussin {
231d0ef721eSBaptiste Daroussin return !iswspace(p);
232d0ef721eSBaptiste Daroussin }
233d0ef721eSBaptiste Daroussin
234d0ef721eSBaptiste Daroussin
235d0ef721eSBaptiste Daroussin /* c__prev_word():
236d0ef721eSBaptiste Daroussin * Find the previous word
237d0ef721eSBaptiste Daroussin */
238d0ef721eSBaptiste Daroussin libedit_private wchar_t *
c__prev_word(wchar_t * p,wchar_t * low,int n,int (* wtest)(wint_t))239d0ef721eSBaptiste Daroussin c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
240d0ef721eSBaptiste Daroussin {
241d0ef721eSBaptiste Daroussin p--;
242d0ef721eSBaptiste Daroussin
243d0ef721eSBaptiste Daroussin while (n--) {
244d0ef721eSBaptiste Daroussin while ((p >= low) && !(*wtest)(*p))
245d0ef721eSBaptiste Daroussin p--;
246d0ef721eSBaptiste Daroussin while ((p >= low) && (*wtest)(*p))
247d0ef721eSBaptiste Daroussin p--;
248d0ef721eSBaptiste Daroussin }
249d0ef721eSBaptiste Daroussin
250d0ef721eSBaptiste Daroussin /* cp now points to one character before the word */
251d0ef721eSBaptiste Daroussin p++;
252d0ef721eSBaptiste Daroussin if (p < low)
253d0ef721eSBaptiste Daroussin p = low;
254d0ef721eSBaptiste Daroussin /* cp now points where we want it */
255d0ef721eSBaptiste Daroussin return p;
256d0ef721eSBaptiste Daroussin }
257d0ef721eSBaptiste Daroussin
258d0ef721eSBaptiste Daroussin
259d0ef721eSBaptiste Daroussin /* c__next_word():
260d0ef721eSBaptiste Daroussin * Find the next word
261d0ef721eSBaptiste Daroussin */
262d0ef721eSBaptiste Daroussin libedit_private wchar_t *
c__next_word(wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))263d0ef721eSBaptiste Daroussin c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
264d0ef721eSBaptiste Daroussin {
265d0ef721eSBaptiste Daroussin while (n--) {
266d0ef721eSBaptiste Daroussin while ((p < high) && !(*wtest)(*p))
267d0ef721eSBaptiste Daroussin p++;
268d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p))
269d0ef721eSBaptiste Daroussin p++;
270d0ef721eSBaptiste Daroussin }
271d0ef721eSBaptiste Daroussin if (p > high)
272d0ef721eSBaptiste Daroussin p = high;
273d0ef721eSBaptiste Daroussin /* p now points where we want it */
274d0ef721eSBaptiste Daroussin return p;
275d0ef721eSBaptiste Daroussin }
276d0ef721eSBaptiste Daroussin
277d0ef721eSBaptiste Daroussin /* cv_next_word():
278d0ef721eSBaptiste Daroussin * Find the next word vi style
279d0ef721eSBaptiste Daroussin */
280d0ef721eSBaptiste Daroussin libedit_private wchar_t *
cv_next_word(EditLine * el,wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))281d0ef721eSBaptiste Daroussin cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
282d0ef721eSBaptiste Daroussin int (*wtest)(wint_t))
283d0ef721eSBaptiste Daroussin {
284d0ef721eSBaptiste Daroussin int test;
285d0ef721eSBaptiste Daroussin
286d0ef721eSBaptiste Daroussin while (n--) {
287d0ef721eSBaptiste Daroussin test = (*wtest)(*p);
288d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p) == test)
289d0ef721eSBaptiste Daroussin p++;
290d0ef721eSBaptiste Daroussin /*
291d0ef721eSBaptiste Daroussin * vi historically deletes with cw only the word preserving the
292d0ef721eSBaptiste Daroussin * trailing whitespace! This is not what 'w' does..
293d0ef721eSBaptiste Daroussin */
294d0ef721eSBaptiste Daroussin if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
295d0ef721eSBaptiste Daroussin while ((p < high) && iswspace(*p))
296d0ef721eSBaptiste Daroussin p++;
297d0ef721eSBaptiste Daroussin }
298d0ef721eSBaptiste Daroussin
299d0ef721eSBaptiste Daroussin /* p now points where we want it */
300d0ef721eSBaptiste Daroussin if (p > high)
301d0ef721eSBaptiste Daroussin return high;
302d0ef721eSBaptiste Daroussin else
303d0ef721eSBaptiste Daroussin return p;
304d0ef721eSBaptiste Daroussin }
305d0ef721eSBaptiste Daroussin
306d0ef721eSBaptiste Daroussin
307d0ef721eSBaptiste Daroussin /* cv_prev_word():
308d0ef721eSBaptiste Daroussin * Find the previous word vi style
309d0ef721eSBaptiste Daroussin */
310d0ef721eSBaptiste Daroussin libedit_private wchar_t *
cv_prev_word(wchar_t * p,wchar_t * low,int n,int (* wtest)(wint_t))311d0ef721eSBaptiste Daroussin cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
312d0ef721eSBaptiste Daroussin {
313d0ef721eSBaptiste Daroussin int test;
314d0ef721eSBaptiste Daroussin
315d0ef721eSBaptiste Daroussin p--;
316d0ef721eSBaptiste Daroussin while (n--) {
317d0ef721eSBaptiste Daroussin while ((p > low) && iswspace(*p))
318d0ef721eSBaptiste Daroussin p--;
319d0ef721eSBaptiste Daroussin test = (*wtest)(*p);
320d0ef721eSBaptiste Daroussin while ((p >= low) && (*wtest)(*p) == test)
321d0ef721eSBaptiste Daroussin p--;
322d0ef721eSBaptiste Daroussin }
323d0ef721eSBaptiste Daroussin p++;
324d0ef721eSBaptiste Daroussin
325d0ef721eSBaptiste Daroussin /* p now points where we want it */
326d0ef721eSBaptiste Daroussin if (p < low)
327d0ef721eSBaptiste Daroussin return low;
328d0ef721eSBaptiste Daroussin else
329d0ef721eSBaptiste Daroussin return p;
330d0ef721eSBaptiste Daroussin }
331d0ef721eSBaptiste Daroussin
332d0ef721eSBaptiste Daroussin
333d0ef721eSBaptiste Daroussin /* cv_delfini():
334d0ef721eSBaptiste Daroussin * Finish vi delete action
335d0ef721eSBaptiste Daroussin */
336d0ef721eSBaptiste Daroussin libedit_private void
cv_delfini(EditLine * el)337d0ef721eSBaptiste Daroussin cv_delfini(EditLine *el)
338d0ef721eSBaptiste Daroussin {
339d0ef721eSBaptiste Daroussin int size;
340d0ef721eSBaptiste Daroussin int action = el->el_chared.c_vcmd.action;
341d0ef721eSBaptiste Daroussin
342d0ef721eSBaptiste Daroussin if (action & INSERT)
343d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
344d0ef721eSBaptiste Daroussin
345d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.pos == 0)
346d0ef721eSBaptiste Daroussin /* sanity */
347d0ef721eSBaptiste Daroussin return;
348d0ef721eSBaptiste Daroussin
349d0ef721eSBaptiste Daroussin size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
350d0ef721eSBaptiste Daroussin if (size == 0)
351d0ef721eSBaptiste Daroussin size = 1;
352d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_chared.c_vcmd.pos;
353d0ef721eSBaptiste Daroussin if (action & YANK) {
354d0ef721eSBaptiste Daroussin if (size > 0)
355d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor, size);
356d0ef721eSBaptiste Daroussin else
357d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor + size, -size);
358d0ef721eSBaptiste Daroussin } else {
359d0ef721eSBaptiste Daroussin if (size > 0) {
360d0ef721eSBaptiste Daroussin c_delafter(el, size);
361d0ef721eSBaptiste Daroussin re_refresh_cursor(el);
362d0ef721eSBaptiste Daroussin } else {
363d0ef721eSBaptiste Daroussin c_delbefore(el, -size);
364d0ef721eSBaptiste Daroussin el->el_line.cursor += size;
365d0ef721eSBaptiste Daroussin }
366d0ef721eSBaptiste Daroussin }
367d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP;
368d0ef721eSBaptiste Daroussin }
369d0ef721eSBaptiste Daroussin
370d0ef721eSBaptiste Daroussin
371d0ef721eSBaptiste Daroussin /* cv__endword():
372d0ef721eSBaptiste Daroussin * Go to the end of this word according to vi
373d0ef721eSBaptiste Daroussin */
374d0ef721eSBaptiste Daroussin libedit_private wchar_t *
cv__endword(wchar_t * p,wchar_t * high,int n,int (* wtest)(wint_t))375d0ef721eSBaptiste Daroussin cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
376d0ef721eSBaptiste Daroussin {
377d0ef721eSBaptiste Daroussin int test;
378d0ef721eSBaptiste Daroussin
379d0ef721eSBaptiste Daroussin p++;
380d0ef721eSBaptiste Daroussin
381d0ef721eSBaptiste Daroussin while (n--) {
382d0ef721eSBaptiste Daroussin while ((p < high) && iswspace(*p))
383d0ef721eSBaptiste Daroussin p++;
384d0ef721eSBaptiste Daroussin
385d0ef721eSBaptiste Daroussin test = (*wtest)(*p);
386d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p) == test)
387d0ef721eSBaptiste Daroussin p++;
388d0ef721eSBaptiste Daroussin }
389d0ef721eSBaptiste Daroussin p--;
390d0ef721eSBaptiste Daroussin return p;
391d0ef721eSBaptiste Daroussin }
392d0ef721eSBaptiste Daroussin
393d0ef721eSBaptiste Daroussin /* ch_init():
394d0ef721eSBaptiste Daroussin * Initialize the character editor
395d0ef721eSBaptiste Daroussin */
396d0ef721eSBaptiste Daroussin libedit_private int
ch_init(EditLine * el)397d0ef721eSBaptiste Daroussin ch_init(EditLine *el)
398d0ef721eSBaptiste Daroussin {
399d0ef721eSBaptiste Daroussin el->el_line.buffer = el_calloc(EL_BUFSIZ,
400d0ef721eSBaptiste Daroussin sizeof(*el->el_line.buffer));
401d0ef721eSBaptiste Daroussin if (el->el_line.buffer == NULL)
402d0ef721eSBaptiste Daroussin return -1;
403d0ef721eSBaptiste Daroussin
404d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
405d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer;
406d0ef721eSBaptiste Daroussin el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
407d0ef721eSBaptiste Daroussin
408d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ,
409d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_undo.buf));
410d0ef721eSBaptiste Daroussin if (el->el_chared.c_undo.buf == NULL)
411d0ef721eSBaptiste Daroussin return -1;
412d0ef721eSBaptiste Daroussin el->el_chared.c_undo.len = -1;
413d0ef721eSBaptiste Daroussin el->el_chared.c_undo.cursor = 0;
414d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ,
415d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_redo.buf));
416d0ef721eSBaptiste Daroussin if (el->el_chared.c_redo.buf == NULL)
417*baff8195SBaptiste Daroussin goto out;
418d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
419d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
420d0ef721eSBaptiste Daroussin el->el_chared.c_redo.cmd = ED_UNASSIGNED;
421d0ef721eSBaptiste Daroussin
422d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP;
423d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.buffer;
424d0ef721eSBaptiste Daroussin
425d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ,
426d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_kill.buf));
427d0ef721eSBaptiste Daroussin if (el->el_chared.c_kill.buf == NULL)
428*baff8195SBaptiste Daroussin goto out;
429d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer;
430d0ef721eSBaptiste Daroussin el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
431d0ef721eSBaptiste Daroussin el->el_chared.c_resizefun = NULL;
432d0ef721eSBaptiste Daroussin el->el_chared.c_resizearg = NULL;
433d0ef721eSBaptiste Daroussin el->el_chared.c_aliasfun = NULL;
434d0ef721eSBaptiste Daroussin el->el_chared.c_aliasarg = NULL;
435d0ef721eSBaptiste Daroussin
436d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
437d0ef721eSBaptiste Daroussin
438d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
439d0ef721eSBaptiste Daroussin el->el_state.doingarg = 0;
440d0ef721eSBaptiste Daroussin el->el_state.metanext = 0;
441d0ef721eSBaptiste Daroussin el->el_state.argument = 1;
442d0ef721eSBaptiste Daroussin el->el_state.lastcmd = ED_UNASSIGNED;
443d0ef721eSBaptiste Daroussin
444d0ef721eSBaptiste Daroussin return 0;
445*baff8195SBaptiste Daroussin out:
446*baff8195SBaptiste Daroussin ch_end(el);
447*baff8195SBaptiste Daroussin return -1;
448d0ef721eSBaptiste Daroussin }
449d0ef721eSBaptiste Daroussin
450d0ef721eSBaptiste Daroussin /* ch_reset():
451d0ef721eSBaptiste Daroussin * Reset the character editor
452d0ef721eSBaptiste Daroussin */
453d0ef721eSBaptiste Daroussin libedit_private void
ch_reset(EditLine * el)454d0ef721eSBaptiste Daroussin ch_reset(EditLine *el)
455d0ef721eSBaptiste Daroussin {
456d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
457d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer;
458d0ef721eSBaptiste Daroussin
459d0ef721eSBaptiste Daroussin el->el_chared.c_undo.len = -1;
460d0ef721eSBaptiste Daroussin el->el_chared.c_undo.cursor = 0;
461d0ef721eSBaptiste Daroussin
462d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP;
463d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.buffer;
464d0ef721eSBaptiste Daroussin
465d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer;
466d0ef721eSBaptiste Daroussin
467d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
468d0ef721eSBaptiste Daroussin
469d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
470d0ef721eSBaptiste Daroussin el->el_state.doingarg = 0;
471d0ef721eSBaptiste Daroussin el->el_state.metanext = 0;
472d0ef721eSBaptiste Daroussin el->el_state.argument = 1;
473d0ef721eSBaptiste Daroussin el->el_state.lastcmd = ED_UNASSIGNED;
474d0ef721eSBaptiste Daroussin
475d0ef721eSBaptiste Daroussin el->el_history.eventno = 0;
476d0ef721eSBaptiste Daroussin }
477d0ef721eSBaptiste Daroussin
478d0ef721eSBaptiste Daroussin /* ch_enlargebufs():
479d0ef721eSBaptiste Daroussin * Enlarge line buffer to be able to hold twice as much characters.
480d0ef721eSBaptiste Daroussin * Returns 1 if successful, 0 if not.
481d0ef721eSBaptiste Daroussin */
482d0ef721eSBaptiste Daroussin libedit_private int
ch_enlargebufs(EditLine * el,size_t addlen)483d0ef721eSBaptiste Daroussin ch_enlargebufs(EditLine *el, size_t addlen)
484d0ef721eSBaptiste Daroussin {
485d0ef721eSBaptiste Daroussin size_t sz, newsz;
486d0ef721eSBaptiste Daroussin wchar_t *newbuffer, *oldbuf, *oldkbuf;
487d0ef721eSBaptiste Daroussin
488d0ef721eSBaptiste Daroussin sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
489d0ef721eSBaptiste Daroussin newsz = sz * 2;
490d0ef721eSBaptiste Daroussin /*
491d0ef721eSBaptiste Daroussin * If newly required length is longer than current buffer, we need
492d0ef721eSBaptiste Daroussin * to make the buffer big enough to hold both old and new stuff.
493d0ef721eSBaptiste Daroussin */
494d0ef721eSBaptiste Daroussin if (addlen > sz) {
495d0ef721eSBaptiste Daroussin while(newsz - sz < addlen)
496d0ef721eSBaptiste Daroussin newsz *= 2;
497d0ef721eSBaptiste Daroussin }
498d0ef721eSBaptiste Daroussin
499d0ef721eSBaptiste Daroussin /*
500d0ef721eSBaptiste Daroussin * Reallocate line buffer.
501d0ef721eSBaptiste Daroussin */
502d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
503d0ef721eSBaptiste Daroussin if (!newbuffer)
504d0ef721eSBaptiste Daroussin return 0;
505d0ef721eSBaptiste Daroussin
506d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */
507d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
508d0ef721eSBaptiste Daroussin
509d0ef721eSBaptiste Daroussin oldbuf = el->el_line.buffer;
510d0ef721eSBaptiste Daroussin
511d0ef721eSBaptiste Daroussin el->el_line.buffer = newbuffer;
512d0ef721eSBaptiste Daroussin el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
513d0ef721eSBaptiste Daroussin el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
514d0ef721eSBaptiste Daroussin /* don't set new size until all buffers are enlarged */
515d0ef721eSBaptiste Daroussin el->el_line.limit = &newbuffer[sz - EL_LEAVE];
516d0ef721eSBaptiste Daroussin
517d0ef721eSBaptiste Daroussin /*
518d0ef721eSBaptiste Daroussin * Reallocate kill buffer.
519d0ef721eSBaptiste Daroussin */
520d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
521d0ef721eSBaptiste Daroussin sizeof(*newbuffer));
522d0ef721eSBaptiste Daroussin if (!newbuffer)
523d0ef721eSBaptiste Daroussin return 0;
524d0ef721eSBaptiste Daroussin
525d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */
526d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
527d0ef721eSBaptiste Daroussin
528d0ef721eSBaptiste Daroussin oldkbuf = el->el_chared.c_kill.buf;
529d0ef721eSBaptiste Daroussin
530d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = newbuffer;
531d0ef721eSBaptiste Daroussin el->el_chared.c_kill.last = newbuffer +
532d0ef721eSBaptiste Daroussin (el->el_chared.c_kill.last - oldkbuf);
533d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer +
534d0ef721eSBaptiste Daroussin (el->el_chared.c_kill.mark - oldbuf);
535d0ef721eSBaptiste Daroussin
536d0ef721eSBaptiste Daroussin /*
537d0ef721eSBaptiste Daroussin * Reallocate undo buffer.
538d0ef721eSBaptiste Daroussin */
539d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_undo.buf,
540d0ef721eSBaptiste Daroussin newsz * sizeof(*newbuffer));
541d0ef721eSBaptiste Daroussin if (!newbuffer)
542d0ef721eSBaptiste Daroussin return 0;
543d0ef721eSBaptiste Daroussin
544d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */
545d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
546d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = newbuffer;
547d0ef721eSBaptiste Daroussin
548d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_redo.buf,
549d0ef721eSBaptiste Daroussin newsz * sizeof(*newbuffer));
550d0ef721eSBaptiste Daroussin if (!newbuffer)
551d0ef721eSBaptiste Daroussin return 0;
552d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = newbuffer +
553d0ef721eSBaptiste Daroussin (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
554d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = newbuffer +
555d0ef721eSBaptiste Daroussin (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
556d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = newbuffer;
557d0ef721eSBaptiste Daroussin
558d0ef721eSBaptiste Daroussin if (!hist_enlargebuf(el, sz, newsz))
559d0ef721eSBaptiste Daroussin return 0;
560d0ef721eSBaptiste Daroussin
561d0ef721eSBaptiste Daroussin /* Safe to set enlarged buffer size */
562d0ef721eSBaptiste Daroussin el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
563d0ef721eSBaptiste Daroussin if (el->el_chared.c_resizefun)
564d0ef721eSBaptiste Daroussin (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
565d0ef721eSBaptiste Daroussin return 1;
566d0ef721eSBaptiste Daroussin }
567d0ef721eSBaptiste Daroussin
568d0ef721eSBaptiste Daroussin /* ch_end():
569d0ef721eSBaptiste Daroussin * Free the data structures used by the editor
570d0ef721eSBaptiste Daroussin */
571d0ef721eSBaptiste Daroussin libedit_private void
ch_end(EditLine * el)572d0ef721eSBaptiste Daroussin ch_end(EditLine *el)
573d0ef721eSBaptiste Daroussin {
574d0ef721eSBaptiste Daroussin el_free(el->el_line.buffer);
575d0ef721eSBaptiste Daroussin el->el_line.buffer = NULL;
576d0ef721eSBaptiste Daroussin el->el_line.limit = NULL;
577d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_undo.buf);
578d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = NULL;
579d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_redo.buf);
580d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = NULL;
581d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = NULL;
582d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = NULL;
583d0ef721eSBaptiste Daroussin el->el_chared.c_redo.cmd = ED_UNASSIGNED;
584d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_kill.buf);
585d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = NULL;
586d0ef721eSBaptiste Daroussin ch_reset(el);
587d0ef721eSBaptiste Daroussin }
588d0ef721eSBaptiste Daroussin
589d0ef721eSBaptiste Daroussin
590d0ef721eSBaptiste Daroussin /* el_insertstr():
591d0ef721eSBaptiste Daroussin * Insert string at cursor
592d0ef721eSBaptiste Daroussin */
593d0ef721eSBaptiste Daroussin int
el_winsertstr(EditLine * el,const wchar_t * s)594d0ef721eSBaptiste Daroussin el_winsertstr(EditLine *el, const wchar_t *s)
595d0ef721eSBaptiste Daroussin {
596d0ef721eSBaptiste Daroussin size_t len;
597d0ef721eSBaptiste Daroussin
598d0ef721eSBaptiste Daroussin if (s == NULL || (len = wcslen(s)) == 0)
599d0ef721eSBaptiste Daroussin return -1;
600d0ef721eSBaptiste Daroussin if (el->el_line.lastchar + len >= el->el_line.limit) {
601d0ef721eSBaptiste Daroussin if (!ch_enlargebufs(el, len))
602d0ef721eSBaptiste Daroussin return -1;
603d0ef721eSBaptiste Daroussin }
604d0ef721eSBaptiste Daroussin
605d0ef721eSBaptiste Daroussin c_insert(el, (int)len);
606d0ef721eSBaptiste Daroussin while (*s)
607d0ef721eSBaptiste Daroussin *el->el_line.cursor++ = *s++;
608d0ef721eSBaptiste Daroussin return 0;
609d0ef721eSBaptiste Daroussin }
610d0ef721eSBaptiste Daroussin
611d0ef721eSBaptiste Daroussin
612d0ef721eSBaptiste Daroussin /* el_deletestr():
613d0ef721eSBaptiste Daroussin * Delete num characters before the cursor
614d0ef721eSBaptiste Daroussin */
615d0ef721eSBaptiste Daroussin void
el_deletestr(EditLine * el,int n)616d0ef721eSBaptiste Daroussin el_deletestr(EditLine *el, int n)
617d0ef721eSBaptiste Daroussin {
618d0ef721eSBaptiste Daroussin if (n <= 0)
619d0ef721eSBaptiste Daroussin return;
620d0ef721eSBaptiste Daroussin
621d0ef721eSBaptiste Daroussin if (el->el_line.cursor < &el->el_line.buffer[n])
622d0ef721eSBaptiste Daroussin return;
623d0ef721eSBaptiste Daroussin
624d0ef721eSBaptiste Daroussin c_delbefore(el, n); /* delete before dot */
625d0ef721eSBaptiste Daroussin el->el_line.cursor -= n;
626d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.buffer)
627d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
628d0ef721eSBaptiste Daroussin }
629d0ef721eSBaptiste Daroussin
6307f399375SBaptiste Daroussin /* el_deletestr1():
6317f399375SBaptiste Daroussin * Delete characters between start and end
6327f399375SBaptiste Daroussin */
6337f399375SBaptiste Daroussin int
el_deletestr1(EditLine * el,int start,int end)6347f399375SBaptiste Daroussin el_deletestr1(EditLine *el, int start, int end)
6357f399375SBaptiste Daroussin {
6367f399375SBaptiste Daroussin size_t line_length, len;
6377f399375SBaptiste Daroussin wchar_t *p1, *p2;
6387f399375SBaptiste Daroussin
6397f399375SBaptiste Daroussin if (end <= start)
6407f399375SBaptiste Daroussin return 0;
6417f399375SBaptiste Daroussin
6427f399375SBaptiste Daroussin line_length = (size_t)(el->el_line.lastchar - el->el_line.buffer);
6437f399375SBaptiste Daroussin
6447f399375SBaptiste Daroussin if (start >= (int)line_length || end >= (int)line_length)
6457f399375SBaptiste Daroussin return 0;
6467f399375SBaptiste Daroussin
6477f399375SBaptiste Daroussin len = (size_t)(end - start);
6487f399375SBaptiste Daroussin if (len > line_length - (size_t)end)
6497f399375SBaptiste Daroussin len = line_length - (size_t)end;
6507f399375SBaptiste Daroussin
6517f399375SBaptiste Daroussin p1 = el->el_line.buffer + start;
6527f399375SBaptiste Daroussin p2 = el->el_line.buffer + end;
6537f399375SBaptiste Daroussin for (size_t i = 0; i < len; i++) {
6547f399375SBaptiste Daroussin *p1++ = *p2++;
6557f399375SBaptiste Daroussin el->el_line.lastchar--;
6567f399375SBaptiste Daroussin }
6577f399375SBaptiste Daroussin
6587f399375SBaptiste Daroussin if (el->el_line.cursor < el->el_line.buffer)
6597f399375SBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
6607f399375SBaptiste Daroussin
6617f399375SBaptiste Daroussin return end - start;
6627f399375SBaptiste Daroussin }
6637f399375SBaptiste Daroussin
6647f399375SBaptiste Daroussin /* el_wreplacestr():
6657f399375SBaptiste Daroussin * Replace the contents of the line with the provided string
6667f399375SBaptiste Daroussin */
6677f399375SBaptiste Daroussin int
el_wreplacestr(EditLine * el,const wchar_t * s)6687f399375SBaptiste Daroussin el_wreplacestr(EditLine *el, const wchar_t *s)
6697f399375SBaptiste Daroussin {
6707f399375SBaptiste Daroussin size_t len;
6717f399375SBaptiste Daroussin wchar_t * p;
6727f399375SBaptiste Daroussin
6737f399375SBaptiste Daroussin if (s == NULL || (len = wcslen(s)) == 0)
6747f399375SBaptiste Daroussin return -1;
6757f399375SBaptiste Daroussin
6767f399375SBaptiste Daroussin if (el->el_line.buffer + len >= el->el_line.limit) {
6777f399375SBaptiste Daroussin if (!ch_enlargebufs(el, len))
6787f399375SBaptiste Daroussin return -1;
6797f399375SBaptiste Daroussin }
6807f399375SBaptiste Daroussin
6817f399375SBaptiste Daroussin p = el->el_line.buffer;
6827f399375SBaptiste Daroussin for (size_t i = 0; i < len; i++)
6837f399375SBaptiste Daroussin *p++ = *s++;
6847f399375SBaptiste Daroussin
6857f399375SBaptiste Daroussin el->el_line.buffer[len] = '\0';
6867f399375SBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer + len;
6877f399375SBaptiste Daroussin if (el->el_line.cursor > el->el_line.lastchar)
6887f399375SBaptiste Daroussin el->el_line.cursor = el->el_line.lastchar;
6897f399375SBaptiste Daroussin
6907f399375SBaptiste Daroussin return 0;
6917f399375SBaptiste Daroussin }
6927f399375SBaptiste Daroussin
693d0ef721eSBaptiste Daroussin /* el_cursor():
694d0ef721eSBaptiste Daroussin * Move the cursor to the left or the right of the current position
695d0ef721eSBaptiste Daroussin */
696d0ef721eSBaptiste Daroussin int
el_cursor(EditLine * el,int n)697d0ef721eSBaptiste Daroussin el_cursor(EditLine *el, int n)
698d0ef721eSBaptiste Daroussin {
699d0ef721eSBaptiste Daroussin if (n == 0)
700d0ef721eSBaptiste Daroussin goto out;
701d0ef721eSBaptiste Daroussin
702d0ef721eSBaptiste Daroussin el->el_line.cursor += n;
703d0ef721eSBaptiste Daroussin
704d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.buffer)
705d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
706d0ef721eSBaptiste Daroussin if (el->el_line.cursor > el->el_line.lastchar)
707d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.lastchar;
708d0ef721eSBaptiste Daroussin out:
709d0ef721eSBaptiste Daroussin return (int)(el->el_line.cursor - el->el_line.buffer);
710d0ef721eSBaptiste Daroussin }
711d0ef721eSBaptiste Daroussin
712d0ef721eSBaptiste Daroussin /* c_gets():
713d0ef721eSBaptiste Daroussin * Get a string
714d0ef721eSBaptiste Daroussin */
715d0ef721eSBaptiste Daroussin libedit_private int
c_gets(EditLine * el,wchar_t * buf,const wchar_t * prompt)716d0ef721eSBaptiste Daroussin c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
717d0ef721eSBaptiste Daroussin {
718d0ef721eSBaptiste Daroussin ssize_t len;
719d0ef721eSBaptiste Daroussin wchar_t *cp = el->el_line.buffer, ch;
720d0ef721eSBaptiste Daroussin
721d0ef721eSBaptiste Daroussin if (prompt) {
722d0ef721eSBaptiste Daroussin len = (ssize_t)wcslen(prompt);
723d0ef721eSBaptiste Daroussin (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
724d0ef721eSBaptiste Daroussin cp += len;
725d0ef721eSBaptiste Daroussin }
726d0ef721eSBaptiste Daroussin len = 0;
727d0ef721eSBaptiste Daroussin
728d0ef721eSBaptiste Daroussin for (;;) {
729d0ef721eSBaptiste Daroussin el->el_line.cursor = cp;
730d0ef721eSBaptiste Daroussin *cp = ' ';
731d0ef721eSBaptiste Daroussin el->el_line.lastchar = cp + 1;
732d0ef721eSBaptiste Daroussin re_refresh(el);
733d0ef721eSBaptiste Daroussin
734d0ef721eSBaptiste Daroussin if (el_wgetc(el, &ch) != 1) {
735d0ef721eSBaptiste Daroussin ed_end_of_file(el, 0);
736d0ef721eSBaptiste Daroussin len = -1;
737d0ef721eSBaptiste Daroussin break;
738d0ef721eSBaptiste Daroussin }
739d0ef721eSBaptiste Daroussin
740d0ef721eSBaptiste Daroussin switch (ch) {
741d0ef721eSBaptiste Daroussin
742d0ef721eSBaptiste Daroussin case L'\b': /* Delete and backspace */
743d0ef721eSBaptiste Daroussin case 0177:
744d0ef721eSBaptiste Daroussin if (len == 0) {
745d0ef721eSBaptiste Daroussin len = -1;
746d0ef721eSBaptiste Daroussin break;
747d0ef721eSBaptiste Daroussin }
748d0ef721eSBaptiste Daroussin len--;
749d0ef721eSBaptiste Daroussin cp--;
750d0ef721eSBaptiste Daroussin continue;
751d0ef721eSBaptiste Daroussin
752d0ef721eSBaptiste Daroussin case 0033: /* ESC */
753d0ef721eSBaptiste Daroussin case L'\r': /* Newline */
754d0ef721eSBaptiste Daroussin case L'\n':
755d0ef721eSBaptiste Daroussin buf[len] = ch;
756d0ef721eSBaptiste Daroussin break;
757d0ef721eSBaptiste Daroussin
758d0ef721eSBaptiste Daroussin default:
759d0ef721eSBaptiste Daroussin if (len >= (ssize_t)(EL_BUFSIZ - 16))
760d0ef721eSBaptiste Daroussin terminal_beep(el);
761d0ef721eSBaptiste Daroussin else {
762d0ef721eSBaptiste Daroussin buf[len++] = ch;
763d0ef721eSBaptiste Daroussin *cp++ = ch;
764d0ef721eSBaptiste Daroussin }
765d0ef721eSBaptiste Daroussin continue;
766d0ef721eSBaptiste Daroussin }
767d0ef721eSBaptiste Daroussin break;
768d0ef721eSBaptiste Daroussin }
769d0ef721eSBaptiste Daroussin
770d0ef721eSBaptiste Daroussin el->el_line.buffer[0] = '\0';
771d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer;
772d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
773d0ef721eSBaptiste Daroussin return (int)len;
774d0ef721eSBaptiste Daroussin }
775d0ef721eSBaptiste Daroussin
776d0ef721eSBaptiste Daroussin
777d0ef721eSBaptiste Daroussin /* c_hpos():
778d0ef721eSBaptiste Daroussin * Return the current horizontal position of the cursor
779d0ef721eSBaptiste Daroussin */
780d0ef721eSBaptiste Daroussin libedit_private int
c_hpos(EditLine * el)781d0ef721eSBaptiste Daroussin c_hpos(EditLine *el)
782d0ef721eSBaptiste Daroussin {
783d0ef721eSBaptiste Daroussin wchar_t *ptr;
784d0ef721eSBaptiste Daroussin
785d0ef721eSBaptiste Daroussin /*
786d0ef721eSBaptiste Daroussin * Find how many characters till the beginning of this line.
787d0ef721eSBaptiste Daroussin */
788d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.buffer)
789d0ef721eSBaptiste Daroussin return 0;
790d0ef721eSBaptiste Daroussin else {
791d0ef721eSBaptiste Daroussin for (ptr = el->el_line.cursor - 1;
792d0ef721eSBaptiste Daroussin ptr >= el->el_line.buffer && *ptr != '\n';
793d0ef721eSBaptiste Daroussin ptr--)
794d0ef721eSBaptiste Daroussin continue;
795d0ef721eSBaptiste Daroussin return (int)(el->el_line.cursor - ptr - 1);
796d0ef721eSBaptiste Daroussin }
797d0ef721eSBaptiste Daroussin }
798d0ef721eSBaptiste Daroussin
799d0ef721eSBaptiste Daroussin libedit_private int
ch_resizefun(EditLine * el,el_zfunc_t f,void * a)800d0ef721eSBaptiste Daroussin ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
801d0ef721eSBaptiste Daroussin {
802d0ef721eSBaptiste Daroussin el->el_chared.c_resizefun = f;
803d0ef721eSBaptiste Daroussin el->el_chared.c_resizearg = a;
804d0ef721eSBaptiste Daroussin return 0;
805d0ef721eSBaptiste Daroussin }
806d0ef721eSBaptiste Daroussin
807d0ef721eSBaptiste Daroussin libedit_private int
ch_aliasfun(EditLine * el,el_afunc_t f,void * a)808d0ef721eSBaptiste Daroussin ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
809d0ef721eSBaptiste Daroussin {
810d0ef721eSBaptiste Daroussin el->el_chared.c_aliasfun = f;
811d0ef721eSBaptiste Daroussin el->el_chared.c_aliasarg = a;
812d0ef721eSBaptiste Daroussin return 0;
813d0ef721eSBaptiste Daroussin }
814