1*5b133f3fSguenther /* $OpenBSD: common.c,v 1.23 2023/03/08 04:43:05 guenther Exp $ */
2aed0ee81Snicm /* $NetBSD: common.c,v 1.24 2009/12/30 22:37:40 christos Exp $ */
3babb851aSmillert
4df930be7Sderaadt /*-
5df930be7Sderaadt * Copyright (c) 1992, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt * Christos Zoulas of Cornell University.
10df930be7Sderaadt *
11df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt * modification, are permitted provided that the following conditions
13df930be7Sderaadt * are met:
14df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt * documentation and/or other materials provided with the distribution.
196580fee3Smillert * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt * may be used to endorse or promote products derived from this software
21df930be7Sderaadt * without specific prior written permission.
22df930be7Sderaadt *
23df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt * SUCH DAMAGE.
34df930be7Sderaadt */
35df930be7Sderaadt
36d484b7d0Sotto #include "config.h"
37df930be7Sderaadt
38df930be7Sderaadt /*
39df930be7Sderaadt * common.c: Common Editor functions
40df930be7Sderaadt */
417ccfa089Sschwarze #include <ctype.h>
427ccfa089Sschwarze #include <string.h>
437ccfa089Sschwarze
44df930be7Sderaadt #include "el.h"
455564fb94Sschwarze #include "common.h"
4613e01c7aSschwarze #include "fcns.h"
475564fb94Sschwarze #include "parse.h"
485564fb94Sschwarze #include "vi.h"
49df930be7Sderaadt
50df930be7Sderaadt /* ed_end_of_file():
51df930be7Sderaadt * Indicate end of file
52df930be7Sderaadt * [^D]
53df930be7Sderaadt */
54df930be7Sderaadt protected el_action_t
ed_end_of_file(EditLine * el,wint_t c)55b2589f0bSschwarze ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
56df930be7Sderaadt {
57d484b7d0Sotto
58df930be7Sderaadt re_goto_bottom(el);
59df930be7Sderaadt *el->el_line.lastchar = '\0';
6028d54ee8Sschwarze return CC_EOF;
61df930be7Sderaadt }
62df930be7Sderaadt
63df930be7Sderaadt
64df930be7Sderaadt /* ed_insert():
65df930be7Sderaadt * Add character to the line
66df930be7Sderaadt * Insert a character [bound to all insert keys]
67df930be7Sderaadt */
68df930be7Sderaadt protected el_action_t
ed_insert(EditLine * el,wint_t c)69b2589f0bSschwarze ed_insert(EditLine *el, wint_t c)
70df930be7Sderaadt {
71d484b7d0Sotto int count = el->el_state.argument;
72df930be7Sderaadt
73df930be7Sderaadt if (c == '\0')
7428d54ee8Sschwarze return CC_ERROR;
75df930be7Sderaadt
76df930be7Sderaadt if (el->el_line.lastchar + el->el_state.argument >=
77d484b7d0Sotto el->el_line.limit) {
78d484b7d0Sotto /* end of buffer space, try to allocate more */
79d484b7d0Sotto if (!ch_enlargebufs(el, (size_t) count))
80d484b7d0Sotto return CC_ERROR; /* error allocating more */
81df930be7Sderaadt }
82df930be7Sderaadt
83d484b7d0Sotto if (count == 1) {
84d484b7d0Sotto if (el->el_state.inputmode == MODE_INSERT
85d484b7d0Sotto || el->el_line.cursor >= el->el_line.lastchar)
86df930be7Sderaadt c_insert(el, 1);
87df930be7Sderaadt
88df930be7Sderaadt *el->el_line.cursor++ = c;
89df930be7Sderaadt re_fastaddc(el); /* fast refresh for one char. */
90d484b7d0Sotto } else {
91d484b7d0Sotto if (el->el_state.inputmode != MODE_REPLACE_1)
92df930be7Sderaadt c_insert(el, el->el_state.argument);
93df930be7Sderaadt
94d484b7d0Sotto while (count-- && el->el_line.cursor < el->el_line.lastchar)
95df930be7Sderaadt *el->el_line.cursor++ = c;
96df930be7Sderaadt re_refresh(el);
97df930be7Sderaadt }
98df930be7Sderaadt
99df930be7Sderaadt if (el->el_state.inputmode == MODE_REPLACE_1)
100d484b7d0Sotto return vi_command_mode(el, 0);
101df930be7Sderaadt
10228d54ee8Sschwarze return CC_NORM;
103df930be7Sderaadt }
104df930be7Sderaadt
105df930be7Sderaadt
106df930be7Sderaadt /* ed_delete_prev_word():
107df930be7Sderaadt * Delete from beginning of current word to cursor
108df930be7Sderaadt * [M-^?] [^W]
109df930be7Sderaadt */
110df930be7Sderaadt protected el_action_t
ed_delete_prev_word(EditLine * el,wint_t c)111b2589f0bSschwarze ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
112df930be7Sderaadt {
113e3191321Sschwarze wchar_t *cp, *p, *kp;
114df930be7Sderaadt
115df930be7Sderaadt if (el->el_line.cursor == el->el_line.buffer)
11628d54ee8Sschwarze return CC_ERROR;
117df930be7Sderaadt
118df930be7Sderaadt cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
119df930be7Sderaadt el->el_state.argument, ce__isword);
120df930be7Sderaadt
121df930be7Sderaadt for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
122df930be7Sderaadt *kp++ = *p;
123df930be7Sderaadt el->el_chared.c_kill.last = kp;
124df930be7Sderaadt
125aed0ee81Snicm c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
126df930be7Sderaadt el->el_line.cursor = cp;
127df930be7Sderaadt if (el->el_line.cursor < el->el_line.buffer)
128df930be7Sderaadt el->el_line.cursor = el->el_line.buffer; /* bounds check */
12928d54ee8Sschwarze return CC_REFRESH;
130df930be7Sderaadt }
131df930be7Sderaadt
132df930be7Sderaadt
133df930be7Sderaadt /* ed_delete_next_char():
134df930be7Sderaadt * Delete character under cursor
135df930be7Sderaadt * [^D] [x]
136df930be7Sderaadt */
137df930be7Sderaadt protected el_action_t
ed_delete_next_char(EditLine * el,wint_t c)138b2589f0bSschwarze ed_delete_next_char(EditLine *el, wint_t c)
139df930be7Sderaadt {
140df930be7Sderaadt #ifdef notdef /* XXX */
141df930be7Sderaadt #define EL el->el_line
14230806f50Sschwarze (void) fprintf(el->el_errfile,
143565aa7e8Sschwarze "\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
144d484b7d0Sotto EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
145d484b7d0Sotto EL.lastchar, EL.limit, EL.limit);
146df930be7Sderaadt #endif
147d484b7d0Sotto if (el->el_line.cursor == el->el_line.lastchar) {
148d484b7d0Sotto /* if I'm at the end */
149df930be7Sderaadt if (el->el_map.type == MAP_VI) {
150df930be7Sderaadt if (el->el_line.cursor == el->el_line.buffer) {
151df930be7Sderaadt /* if I'm also at the beginning */
152df930be7Sderaadt #ifdef KSHVI
15328d54ee8Sschwarze return CC_ERROR;
154df930be7Sderaadt #else
155aed0ee81Snicm /* then do an EOF */
156fd40972aSschwarze terminal_writec(el, c);
15728d54ee8Sschwarze return CC_EOF;
158df930be7Sderaadt #endif
159d484b7d0Sotto } else {
160df930be7Sderaadt #ifdef KSHVI
161df930be7Sderaadt el->el_line.cursor--;
162df930be7Sderaadt #else
16328d54ee8Sschwarze return CC_ERROR;
164df930be7Sderaadt #endif
165df930be7Sderaadt }
166d484b7d0Sotto } else {
167df930be7Sderaadt if (el->el_line.cursor != el->el_line.buffer)
168df930be7Sderaadt el->el_line.cursor--;
169df930be7Sderaadt else
17028d54ee8Sschwarze return CC_ERROR;
171df930be7Sderaadt }
172df930be7Sderaadt }
173df930be7Sderaadt c_delafter(el, el->el_state.argument); /* delete after dot */
174d484b7d0Sotto if (el->el_line.cursor >= el->el_line.lastchar &&
175d484b7d0Sotto el->el_line.cursor > el->el_line.buffer)
176d484b7d0Sotto /* bounds check */
177d484b7d0Sotto el->el_line.cursor = el->el_line.lastchar - 1;
17828d54ee8Sschwarze return CC_REFRESH;
179df930be7Sderaadt }
180df930be7Sderaadt
181df930be7Sderaadt
182df930be7Sderaadt /* ed_kill_line():
183df930be7Sderaadt * Cut to the end of line
184df930be7Sderaadt * [^K] [^K]
185df930be7Sderaadt */
186df930be7Sderaadt protected el_action_t
ed_kill_line(EditLine * el,wint_t c)187b2589f0bSschwarze ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
188df930be7Sderaadt {
189e3191321Sschwarze wchar_t *kp, *cp;
190df930be7Sderaadt
191df930be7Sderaadt cp = el->el_line.cursor;
192df930be7Sderaadt kp = el->el_chared.c_kill.buf;
193df930be7Sderaadt while (cp < el->el_line.lastchar)
194df930be7Sderaadt *kp++ = *cp++; /* copy it */
195df930be7Sderaadt el->el_chared.c_kill.last = kp;
196d484b7d0Sotto /* zap! -- delete to end */
197d484b7d0Sotto el->el_line.lastchar = el->el_line.cursor;
19828d54ee8Sschwarze return CC_REFRESH;
199df930be7Sderaadt }
200df930be7Sderaadt
201df930be7Sderaadt
202df930be7Sderaadt /* ed_move_to_end():
203df930be7Sderaadt * Move cursor to the end of line
204df930be7Sderaadt * [^E] [^E]
205df930be7Sderaadt */
206df930be7Sderaadt protected el_action_t
ed_move_to_end(EditLine * el,wint_t c)207b2589f0bSschwarze ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
208df930be7Sderaadt {
209d484b7d0Sotto
210df930be7Sderaadt el->el_line.cursor = el->el_line.lastchar;
211df930be7Sderaadt if (el->el_map.type == MAP_VI) {
212d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
213df930be7Sderaadt cv_delfini(el);
21428d54ee8Sschwarze return CC_REFRESH;
215df930be7Sderaadt }
216aed0ee81Snicm #ifdef VI_MOVE
217aed0ee81Snicm el->el_line.cursor--;
218aed0ee81Snicm #endif
219df930be7Sderaadt }
22028d54ee8Sschwarze return CC_CURSOR;
221df930be7Sderaadt }
222df930be7Sderaadt
223df930be7Sderaadt
224df930be7Sderaadt /* ed_move_to_beg():
225df930be7Sderaadt * Move cursor to the beginning of line
226df930be7Sderaadt * [^A] [^A]
227df930be7Sderaadt */
228df930be7Sderaadt protected el_action_t
ed_move_to_beg(EditLine * el,wint_t c)229b2589f0bSschwarze ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
230df930be7Sderaadt {
231d484b7d0Sotto
232df930be7Sderaadt el->el_line.cursor = el->el_line.buffer;
233df930be7Sderaadt
234df930be7Sderaadt if (el->el_map.type == MAP_VI) {
235df930be7Sderaadt /* We want FIRST non space character */
236565aa7e8Sschwarze while (iswspace(*el->el_line.cursor))
237df930be7Sderaadt el->el_line.cursor++;
238d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
239df930be7Sderaadt cv_delfini(el);
24028d54ee8Sschwarze return CC_REFRESH;
241df930be7Sderaadt }
242df930be7Sderaadt }
24328d54ee8Sschwarze return CC_CURSOR;
244df930be7Sderaadt }
245df930be7Sderaadt
246df930be7Sderaadt
247df930be7Sderaadt /* ed_transpose_chars():
248df930be7Sderaadt * Exchange the character to the left of the cursor with the one under it
249df930be7Sderaadt * [^T] [^T]
250df930be7Sderaadt */
251df930be7Sderaadt protected el_action_t
ed_transpose_chars(EditLine * el,wint_t c)252b2589f0bSschwarze ed_transpose_chars(EditLine *el, wint_t c)
253df930be7Sderaadt {
254d484b7d0Sotto
255df930be7Sderaadt if (el->el_line.cursor < el->el_line.lastchar) {
256df930be7Sderaadt if (el->el_line.lastchar <= &el->el_line.buffer[1])
25728d54ee8Sschwarze return CC_ERROR;
258df930be7Sderaadt else
259df930be7Sderaadt el->el_line.cursor++;
260df930be7Sderaadt }
261df930be7Sderaadt if (el->el_line.cursor > &el->el_line.buffer[1]) {
262df930be7Sderaadt /* must have at least two chars entered */
263df930be7Sderaadt c = el->el_line.cursor[-2];
264df930be7Sderaadt el->el_line.cursor[-2] = el->el_line.cursor[-1];
265df930be7Sderaadt el->el_line.cursor[-1] = c;
26628d54ee8Sschwarze return CC_REFRESH;
267d484b7d0Sotto } else
26828d54ee8Sschwarze return CC_ERROR;
269df930be7Sderaadt }
270df930be7Sderaadt
271df930be7Sderaadt
272df930be7Sderaadt /* ed_next_char():
273df930be7Sderaadt * Move to the right one character
274df930be7Sderaadt * [^F] [^F]
275df930be7Sderaadt */
276df930be7Sderaadt protected el_action_t
ed_next_char(EditLine * el,wint_t c)277b2589f0bSschwarze ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
278df930be7Sderaadt {
279e3191321Sschwarze wchar_t *lim = el->el_line.lastchar;
280d484b7d0Sotto
281d484b7d0Sotto if (el->el_line.cursor >= lim ||
282d484b7d0Sotto (el->el_line.cursor == lim - 1 &&
283d484b7d0Sotto el->el_map.type == MAP_VI &&
284d484b7d0Sotto el->el_chared.c_vcmd.action == NOP))
28528d54ee8Sschwarze return CC_ERROR;
286df930be7Sderaadt
287df930be7Sderaadt el->el_line.cursor += el->el_state.argument;
288d484b7d0Sotto if (el->el_line.cursor > lim)
289d484b7d0Sotto el->el_line.cursor = lim;
290df930be7Sderaadt
291df930be7Sderaadt if (el->el_map.type == MAP_VI)
292d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
293df930be7Sderaadt cv_delfini(el);
29428d54ee8Sschwarze return CC_REFRESH;
295df930be7Sderaadt }
29628d54ee8Sschwarze return CC_CURSOR;
297df930be7Sderaadt }
298df930be7Sderaadt
299df930be7Sderaadt
300df930be7Sderaadt /* ed_prev_word():
301df930be7Sderaadt * Move to the beginning of the current word
302df930be7Sderaadt * [M-b] [b]
303df930be7Sderaadt */
304df930be7Sderaadt protected el_action_t
ed_prev_word(EditLine * el,wint_t c)305b2589f0bSschwarze ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
306df930be7Sderaadt {
307df930be7Sderaadt
308d484b7d0Sotto if (el->el_line.cursor == el->el_line.buffer)
30928d54ee8Sschwarze return CC_ERROR;
310d484b7d0Sotto
311d484b7d0Sotto el->el_line.cursor = c__prev_word(el->el_line.cursor,
312d484b7d0Sotto el->el_line.buffer,
313df930be7Sderaadt el->el_state.argument,
314df930be7Sderaadt ce__isword);
315df930be7Sderaadt
316df930be7Sderaadt if (el->el_map.type == MAP_VI)
317d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
318df930be7Sderaadt cv_delfini(el);
31928d54ee8Sschwarze return CC_REFRESH;
320df930be7Sderaadt }
32128d54ee8Sschwarze return CC_CURSOR;
322df930be7Sderaadt }
323df930be7Sderaadt
324df930be7Sderaadt
325df930be7Sderaadt /* ed_prev_char():
326df930be7Sderaadt * Move to the left one character
327df930be7Sderaadt * [^B] [^B]
328df930be7Sderaadt */
329df930be7Sderaadt protected el_action_t
ed_prev_char(EditLine * el,wint_t c)330b2589f0bSschwarze ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
331df930be7Sderaadt {
332d484b7d0Sotto
333df930be7Sderaadt if (el->el_line.cursor > el->el_line.buffer) {
334df930be7Sderaadt el->el_line.cursor -= el->el_state.argument;
335df930be7Sderaadt if (el->el_line.cursor < el->el_line.buffer)
336df930be7Sderaadt el->el_line.cursor = el->el_line.buffer;
337df930be7Sderaadt
338df930be7Sderaadt if (el->el_map.type == MAP_VI)
339d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
340df930be7Sderaadt cv_delfini(el);
34128d54ee8Sschwarze return CC_REFRESH;
342df930be7Sderaadt }
34328d54ee8Sschwarze return CC_CURSOR;
344d484b7d0Sotto } else
34528d54ee8Sschwarze return CC_ERROR;
346df930be7Sderaadt }
347df930be7Sderaadt
348df930be7Sderaadt
349df930be7Sderaadt /* ed_quoted_insert():
350df930be7Sderaadt * Add the next character typed verbatim
351df930be7Sderaadt * [^V] [^V]
352df930be7Sderaadt */
353df930be7Sderaadt protected el_action_t
ed_quoted_insert(EditLine * el,wint_t c)354b2589f0bSschwarze ed_quoted_insert(EditLine *el, wint_t c)
355df930be7Sderaadt {
356df930be7Sderaadt int num;
357df930be7Sderaadt
358df930be7Sderaadt tty_quotemode(el);
359df2a7d38Sschwarze num = el_wgetc(el, &c);
360df930be7Sderaadt tty_noquotemode(el);
361df930be7Sderaadt if (num == 1)
36228d54ee8Sschwarze return ed_insert(el, c);
363df930be7Sderaadt else
36428d54ee8Sschwarze return ed_end_of_file(el, 0);
365df930be7Sderaadt }
366df930be7Sderaadt
367df930be7Sderaadt
368df930be7Sderaadt /* ed_digit():
369df930be7Sderaadt * Adds to argument or enters a digit
370df930be7Sderaadt */
371df930be7Sderaadt protected el_action_t
ed_digit(EditLine * el,wint_t c)372b2589f0bSschwarze ed_digit(EditLine *el, wint_t c)
373df930be7Sderaadt {
374d484b7d0Sotto
375565aa7e8Sschwarze if (!iswdigit(c))
37628d54ee8Sschwarze return CC_ERROR;
377df930be7Sderaadt
378df930be7Sderaadt if (el->el_state.doingarg) {
379df930be7Sderaadt /* if doing an arg, add this in... */
380df930be7Sderaadt if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
381df930be7Sderaadt el->el_state.argument = c - '0';
382df930be7Sderaadt else {
383df930be7Sderaadt if (el->el_state.argument > 1000000)
38428d54ee8Sschwarze return CC_ERROR;
385df930be7Sderaadt el->el_state.argument =
386df930be7Sderaadt (el->el_state.argument * 10) + (c - '0');
387df930be7Sderaadt }
38828d54ee8Sschwarze return CC_ARGHACK;
389df930be7Sderaadt }
390df930be7Sderaadt
391d484b7d0Sotto return ed_insert(el, c);
392df930be7Sderaadt }
393df930be7Sderaadt
394df930be7Sderaadt
395df930be7Sderaadt /* ed_argument_digit():
396df930be7Sderaadt * Digit that starts argument
397df930be7Sderaadt * For ESC-n
398df930be7Sderaadt */
399df930be7Sderaadt protected el_action_t
ed_argument_digit(EditLine * el,wint_t c)400b2589f0bSschwarze ed_argument_digit(EditLine *el, wint_t c)
401df930be7Sderaadt {
402d484b7d0Sotto
403565aa7e8Sschwarze if (!iswdigit(c))
40428d54ee8Sschwarze return CC_ERROR;
405df930be7Sderaadt
406df930be7Sderaadt if (el->el_state.doingarg) {
407df930be7Sderaadt if (el->el_state.argument > 1000000)
40828d54ee8Sschwarze return CC_ERROR;
409d484b7d0Sotto el->el_state.argument = (el->el_state.argument * 10) +
410d484b7d0Sotto (c - '0');
411d484b7d0Sotto } else { /* else starting an argument */
412df930be7Sderaadt el->el_state.argument = c - '0';
413df930be7Sderaadt el->el_state.doingarg = 1;
414df930be7Sderaadt }
41528d54ee8Sschwarze return CC_ARGHACK;
416df930be7Sderaadt }
417df930be7Sderaadt
418df930be7Sderaadt
419df930be7Sderaadt /* ed_unassigned():
420df930be7Sderaadt * Indicates unbound character
421df930be7Sderaadt * Bound to keys that are not assigned
422df930be7Sderaadt */
423df930be7Sderaadt protected el_action_t
ed_unassigned(EditLine * el,wint_t c)424b2589f0bSschwarze ed_unassigned(EditLine *el, wint_t c __attribute__((__unused__)))
425df930be7Sderaadt {
426d484b7d0Sotto
42728d54ee8Sschwarze return CC_ERROR;
428df930be7Sderaadt }
429df930be7Sderaadt
430df930be7Sderaadt
43155643de9Sschwarze /* ed_ignore():
43255643de9Sschwarze * Input characters that have no effect
43355643de9Sschwarze * [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
434df930be7Sderaadt */
435df930be7Sderaadt protected el_action_t
ed_ignore(EditLine * el,wint_t c)43655643de9Sschwarze ed_ignore(EditLine *el __attribute__((__unused__)),
437b2589f0bSschwarze wint_t c __attribute__((__unused__)))
438df930be7Sderaadt {
439d484b7d0Sotto
44028d54ee8Sschwarze return CC_NORM;
441df930be7Sderaadt }
442df930be7Sderaadt
443df930be7Sderaadt
444df930be7Sderaadt /* ed_newline():
445df930be7Sderaadt * Execute command
446df930be7Sderaadt * [^J]
447df930be7Sderaadt */
448df930be7Sderaadt protected el_action_t
ed_newline(EditLine * el,wint_t c)449b2589f0bSschwarze ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
450df930be7Sderaadt {
451d484b7d0Sotto
452df930be7Sderaadt re_goto_bottom(el);
453df930be7Sderaadt *el->el_line.lastchar++ = '\n';
454df930be7Sderaadt *el->el_line.lastchar = '\0';
45528d54ee8Sschwarze return CC_NEWLINE;
456df930be7Sderaadt }
457df930be7Sderaadt
458df930be7Sderaadt
459df930be7Sderaadt /* ed_delete_prev_char():
460df930be7Sderaadt * Delete the character to the left of the cursor
461df930be7Sderaadt * [^?]
462df930be7Sderaadt */
463df930be7Sderaadt protected el_action_t
ed_delete_prev_char(EditLine * el,wint_t c)464b2589f0bSschwarze ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
465df930be7Sderaadt {
466d484b7d0Sotto
467df930be7Sderaadt if (el->el_line.cursor <= el->el_line.buffer)
46828d54ee8Sschwarze return CC_ERROR;
469df930be7Sderaadt
470df930be7Sderaadt c_delbefore(el, el->el_state.argument);
471df930be7Sderaadt el->el_line.cursor -= el->el_state.argument;
472df930be7Sderaadt if (el->el_line.cursor < el->el_line.buffer)
473df930be7Sderaadt el->el_line.cursor = el->el_line.buffer;
47428d54ee8Sschwarze return CC_REFRESH;
475df930be7Sderaadt }
476df930be7Sderaadt
477df930be7Sderaadt
478df930be7Sderaadt /* ed_clear_screen():
479df930be7Sderaadt * Clear screen leaving current line at the top
480df930be7Sderaadt * [^L]
481df930be7Sderaadt */
482df930be7Sderaadt protected el_action_t
ed_clear_screen(EditLine * el,wint_t c)483b2589f0bSschwarze ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
484df930be7Sderaadt {
485d484b7d0Sotto
486fd40972aSschwarze terminal_clear_screen(el); /* clear the whole real screen */
487df930be7Sderaadt re_clear_display(el); /* reset everything */
48828d54ee8Sschwarze return CC_REFRESH;
489df930be7Sderaadt }
490df930be7Sderaadt
491df930be7Sderaadt
492df930be7Sderaadt /* ed_redisplay():
493df930be7Sderaadt * Redisplay everything
494df930be7Sderaadt * ^R
495df930be7Sderaadt */
496df930be7Sderaadt protected el_action_t
ed_redisplay(EditLine * el,wint_t c)497d484b7d0Sotto ed_redisplay(EditLine *el __attribute__((__unused__)),
498b2589f0bSschwarze wint_t c __attribute__((__unused__)))
499df930be7Sderaadt {
500d484b7d0Sotto
50128d54ee8Sschwarze return CC_REDISPLAY;
502df930be7Sderaadt }
503df930be7Sderaadt
504df930be7Sderaadt
505df930be7Sderaadt /* ed_start_over():
506df930be7Sderaadt * Erase current line and start from scratch
507df930be7Sderaadt * [^G]
508df930be7Sderaadt */
509df930be7Sderaadt protected el_action_t
ed_start_over(EditLine * el,wint_t c)510b2589f0bSschwarze ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
511df930be7Sderaadt {
512d484b7d0Sotto
5135161d913Sschwarze ch_reset(el);
51428d54ee8Sschwarze return CC_REFRESH;
515df930be7Sderaadt }
516df930be7Sderaadt
517df930be7Sderaadt
518df930be7Sderaadt /* ed_sequence_lead_in():
519df930be7Sderaadt * First character in a bound sequence
520df930be7Sderaadt * Placeholder for external keys
521df930be7Sderaadt */
522df930be7Sderaadt protected el_action_t
ed_sequence_lead_in(EditLine * el,wint_t c)523d484b7d0Sotto ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
524b2589f0bSschwarze wint_t c __attribute__((__unused__)))
525df930be7Sderaadt {
526d484b7d0Sotto
52728d54ee8Sschwarze return CC_NORM;
528df930be7Sderaadt }
529df930be7Sderaadt
530df930be7Sderaadt
531df930be7Sderaadt /* ed_prev_history():
532df930be7Sderaadt * Move to the previous history line
533df930be7Sderaadt * [^P] [k]
534df930be7Sderaadt */
535df930be7Sderaadt protected el_action_t
ed_prev_history(EditLine * el,wint_t c)536b2589f0bSschwarze ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
537df930be7Sderaadt {
538df930be7Sderaadt char beep = 0;
539d484b7d0Sotto int sv_event = el->el_history.eventno;
540df930be7Sderaadt
541d484b7d0Sotto el->el_chared.c_undo.len = -1;
542df930be7Sderaadt *el->el_line.lastchar = '\0'; /* just in case */
543df930be7Sderaadt
544d484b7d0Sotto if (el->el_history.eventno == 0) { /* save the current buffer
545d484b7d0Sotto * away */
5465c93237dSschwarze (void) wcsncpy(el->el_history.buf, el->el_line.buffer,
547d484b7d0Sotto EL_BUFSIZ);
548df930be7Sderaadt el->el_history.last = el->el_history.buf +
549df930be7Sderaadt (el->el_line.lastchar - el->el_line.buffer);
550df930be7Sderaadt }
551df930be7Sderaadt el->el_history.eventno += el->el_state.argument;
552df930be7Sderaadt
553df930be7Sderaadt if (hist_get(el) == CC_ERROR) {
554d484b7d0Sotto if (el->el_map.type == MAP_VI) {
555d484b7d0Sotto el->el_history.eventno = sv_event;
556d484b7d0Sotto }
557df930be7Sderaadt beep = 1;
558df930be7Sderaadt /* el->el_history.eventno was fixed by first call */
559df930be7Sderaadt (void) hist_get(el);
560df930be7Sderaadt }
561df930be7Sderaadt if (beep)
562d484b7d0Sotto return CC_REFRESH_BEEP;
563d484b7d0Sotto return CC_REFRESH;
564df930be7Sderaadt }
565df930be7Sderaadt
566df930be7Sderaadt
567df930be7Sderaadt /* ed_next_history():
568df930be7Sderaadt * Move to the next history line
569df930be7Sderaadt * [^N] [j]
570df930be7Sderaadt */
571df930be7Sderaadt protected el_action_t
ed_next_history(EditLine * el,wint_t c)572b2589f0bSschwarze ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
573df930be7Sderaadt {
574d484b7d0Sotto el_action_t beep = CC_REFRESH, rval;
575d484b7d0Sotto
576d484b7d0Sotto el->el_chared.c_undo.len = -1;
577df930be7Sderaadt *el->el_line.lastchar = '\0'; /* just in case */
578df930be7Sderaadt
579df930be7Sderaadt el->el_history.eventno -= el->el_state.argument;
580df930be7Sderaadt
581df930be7Sderaadt if (el->el_history.eventno < 0) {
582df930be7Sderaadt el->el_history.eventno = 0;
583d484b7d0Sotto beep = CC_REFRESH_BEEP;
584df930be7Sderaadt }
585d484b7d0Sotto rval = hist_get(el);
586d484b7d0Sotto if (rval == CC_REFRESH)
587d484b7d0Sotto return beep;
588d484b7d0Sotto return rval;
589df930be7Sderaadt
590df930be7Sderaadt }
591df930be7Sderaadt
592df930be7Sderaadt
593df930be7Sderaadt /* ed_search_prev_history():
594df930be7Sderaadt * Search previous in history for a line matching the current
595df930be7Sderaadt * next search history [M-P] [K]
596df930be7Sderaadt */
597df930be7Sderaadt protected el_action_t
ed_search_prev_history(EditLine * el,wint_t c)598b2589f0bSschwarze ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
599df930be7Sderaadt {
600e3191321Sschwarze const wchar_t *hp;
601df930be7Sderaadt int h;
6028df20b6bSschwarze int found = 0;
603df930be7Sderaadt
604df930be7Sderaadt el->el_chared.c_vcmd.action = NOP;
605d484b7d0Sotto el->el_chared.c_undo.len = -1;
606df930be7Sderaadt *el->el_line.lastchar = '\0'; /* just in case */
607df930be7Sderaadt if (el->el_history.eventno < 0) {
608df930be7Sderaadt #ifdef DEBUG_EDIT
609d484b7d0Sotto (void) fprintf(el->el_errfile,
610d484b7d0Sotto "e_prev_search_hist(): eventno < 0;\n");
611df930be7Sderaadt #endif
612df930be7Sderaadt el->el_history.eventno = 0;
61328d54ee8Sschwarze return CC_ERROR;
614df930be7Sderaadt }
615df930be7Sderaadt if (el->el_history.eventno == 0) {
6165c93237dSschwarze (void) wcsncpy(el->el_history.buf, el->el_line.buffer,
617d484b7d0Sotto EL_BUFSIZ);
618df930be7Sderaadt el->el_history.last = el->el_history.buf +
619df930be7Sderaadt (el->el_line.lastchar - el->el_line.buffer);
620df930be7Sderaadt }
621df930be7Sderaadt if (el->el_history.ref == NULL)
62228d54ee8Sschwarze return CC_ERROR;
623df930be7Sderaadt
624df930be7Sderaadt hp = HIST_FIRST(el);
625df930be7Sderaadt if (hp == NULL)
62628d54ee8Sschwarze return CC_ERROR;
627df930be7Sderaadt
628df930be7Sderaadt c_setpat(el); /* Set search pattern !! */
629df930be7Sderaadt
630df930be7Sderaadt for (h = 1; h <= el->el_history.eventno; h++)
631df930be7Sderaadt hp = HIST_NEXT(el);
632df930be7Sderaadt
633df930be7Sderaadt while (hp != NULL) {
634df930be7Sderaadt #ifdef SDEBUG
635df930be7Sderaadt (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
636df930be7Sderaadt #endif
6375c93237dSschwarze if ((wcsncmp(hp, el->el_line.buffer, (size_t)
638d484b7d0Sotto (el->el_line.lastchar - el->el_line.buffer)) ||
639df930be7Sderaadt hp[el->el_line.lastchar - el->el_line.buffer]) &&
640df930be7Sderaadt c_hmatch(el, hp)) {
6418df20b6bSschwarze found = 1;
642df930be7Sderaadt break;
643df930be7Sderaadt }
644df930be7Sderaadt h++;
645df930be7Sderaadt hp = HIST_NEXT(el);
646df930be7Sderaadt }
647df930be7Sderaadt
648df930be7Sderaadt if (!found) {
649df930be7Sderaadt #ifdef SDEBUG
650df930be7Sderaadt (void) fprintf(el->el_errfile, "not found\n");
651df930be7Sderaadt #endif
65228d54ee8Sschwarze return CC_ERROR;
653df930be7Sderaadt }
654df930be7Sderaadt el->el_history.eventno = h;
655df930be7Sderaadt
65628d54ee8Sschwarze return hist_get(el);
657df930be7Sderaadt }
658df930be7Sderaadt
659df930be7Sderaadt
660df930be7Sderaadt /* ed_search_next_history():
661df930be7Sderaadt * Search next in history for a line matching the current
662df930be7Sderaadt * [M-N] [J]
663df930be7Sderaadt */
664df930be7Sderaadt protected el_action_t
ed_search_next_history(EditLine * el,wint_t c)665b2589f0bSschwarze ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
666df930be7Sderaadt {
667e3191321Sschwarze const wchar_t *hp;
668df930be7Sderaadt int h;
6698df20b6bSschwarze int found = 0;
670df930be7Sderaadt
671df930be7Sderaadt el->el_chared.c_vcmd.action = NOP;
672d484b7d0Sotto el->el_chared.c_undo.len = -1;
673df930be7Sderaadt *el->el_line.lastchar = '\0'; /* just in case */
674df930be7Sderaadt
675df930be7Sderaadt if (el->el_history.eventno == 0)
67628d54ee8Sschwarze return CC_ERROR;
677df930be7Sderaadt
678df930be7Sderaadt if (el->el_history.ref == NULL)
67928d54ee8Sschwarze return CC_ERROR;
680df930be7Sderaadt
681df930be7Sderaadt hp = HIST_FIRST(el);
682df930be7Sderaadt if (hp == NULL)
68328d54ee8Sschwarze return CC_ERROR;
684df930be7Sderaadt
685df930be7Sderaadt c_setpat(el); /* Set search pattern !! */
686df930be7Sderaadt
687df930be7Sderaadt for (h = 1; h < el->el_history.eventno && hp; h++) {
688df930be7Sderaadt #ifdef SDEBUG
689df930be7Sderaadt (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
690df930be7Sderaadt #endif
6915c93237dSschwarze if ((wcsncmp(hp, el->el_line.buffer, (size_t)
692d484b7d0Sotto (el->el_line.lastchar - el->el_line.buffer)) ||
693df930be7Sderaadt hp[el->el_line.lastchar - el->el_line.buffer]) &&
694df930be7Sderaadt c_hmatch(el, hp))
695df930be7Sderaadt found = h;
696df930be7Sderaadt hp = HIST_NEXT(el);
697df930be7Sderaadt }
698df930be7Sderaadt
699df930be7Sderaadt if (!found) { /* is it the current history number? */
700df930be7Sderaadt if (!c_hmatch(el, el->el_history.buf)) {
701df930be7Sderaadt #ifdef SDEBUG
702df930be7Sderaadt (void) fprintf(el->el_errfile, "not found\n");
703df930be7Sderaadt #endif
70428d54ee8Sschwarze return CC_ERROR;
705df930be7Sderaadt }
706df930be7Sderaadt }
707df930be7Sderaadt el->el_history.eventno = found;
708df930be7Sderaadt
70928d54ee8Sschwarze return hist_get(el);
710df930be7Sderaadt }
711df930be7Sderaadt
712df930be7Sderaadt
713df930be7Sderaadt /* ed_prev_line():
714df930be7Sderaadt * Move up one line
715df930be7Sderaadt * Could be [k] [^p]
716df930be7Sderaadt */
717df930be7Sderaadt protected el_action_t
ed_prev_line(EditLine * el,wint_t c)718b2589f0bSschwarze ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
719df930be7Sderaadt {
720e3191321Sschwarze wchar_t *ptr;
721df930be7Sderaadt int nchars = c_hpos(el);
722df930be7Sderaadt
723df930be7Sderaadt /*
724df930be7Sderaadt * Move to the line requested
725df930be7Sderaadt */
726df930be7Sderaadt if (*(ptr = el->el_line.cursor) == '\n')
727df930be7Sderaadt ptr--;
728df930be7Sderaadt
729df930be7Sderaadt for (; ptr >= el->el_line.buffer; ptr--)
730df930be7Sderaadt if (*ptr == '\n' && --el->el_state.argument <= 0)
731df930be7Sderaadt break;
732df930be7Sderaadt
733df930be7Sderaadt if (el->el_state.argument > 0)
73428d54ee8Sschwarze return CC_ERROR;
735df930be7Sderaadt
736df930be7Sderaadt /*
737df930be7Sderaadt * Move to the beginning of the line
738df930be7Sderaadt */
739df930be7Sderaadt for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
740df930be7Sderaadt continue;
741df930be7Sderaadt
742df930be7Sderaadt /*
743df930be7Sderaadt * Move to the character requested
744df930be7Sderaadt */
745df930be7Sderaadt for (ptr++;
746df930be7Sderaadt nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
747df930be7Sderaadt ptr++)
748df930be7Sderaadt continue;
749df930be7Sderaadt
750df930be7Sderaadt el->el_line.cursor = ptr;
75128d54ee8Sschwarze return CC_CURSOR;
752df930be7Sderaadt }
753df930be7Sderaadt
754df930be7Sderaadt
755df930be7Sderaadt /* ed_next_line():
756df930be7Sderaadt * Move down one line
757df930be7Sderaadt * Could be [j] [^n]
758df930be7Sderaadt */
759df930be7Sderaadt protected el_action_t
ed_next_line(EditLine * el,wint_t c)760b2589f0bSschwarze ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
761df930be7Sderaadt {
762e3191321Sschwarze wchar_t *ptr;
763df930be7Sderaadt int nchars = c_hpos(el);
764df930be7Sderaadt
765df930be7Sderaadt /*
766df930be7Sderaadt * Move to the line requested
767df930be7Sderaadt */
768df930be7Sderaadt for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
769df930be7Sderaadt if (*ptr == '\n' && --el->el_state.argument <= 0)
770df930be7Sderaadt break;
771df930be7Sderaadt
772df930be7Sderaadt if (el->el_state.argument > 0)
77328d54ee8Sschwarze return CC_ERROR;
774df930be7Sderaadt
775df930be7Sderaadt /*
776df930be7Sderaadt * Move to the character requested
777df930be7Sderaadt */
778df930be7Sderaadt for (ptr++;
779df930be7Sderaadt nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
780df930be7Sderaadt ptr++)
781df930be7Sderaadt continue;
782df930be7Sderaadt
783df930be7Sderaadt el->el_line.cursor = ptr;
78428d54ee8Sschwarze return CC_CURSOR;
785df930be7Sderaadt }
786df930be7Sderaadt
787df930be7Sderaadt
788df930be7Sderaadt /* ed_command():
789df930be7Sderaadt * Editline extended command
790df930be7Sderaadt * [M-X] [:]
791df930be7Sderaadt */
792df930be7Sderaadt protected el_action_t
ed_command(EditLine * el,wint_t c)793b2589f0bSschwarze ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
794df930be7Sderaadt {
795e3191321Sschwarze wchar_t tmpbuf[EL_BUFSIZ];
796df930be7Sderaadt int tmplen;
797df930be7Sderaadt
7985c93237dSschwarze tmplen = c_gets(el, tmpbuf, L"\n: ");
799fd40972aSschwarze terminal__putc(el, '\n');
800df930be7Sderaadt
801d484b7d0Sotto if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
802fd40972aSschwarze terminal_beep(el);
803df930be7Sderaadt
804d484b7d0Sotto el->el_map.current = el->el_map.key;
805d484b7d0Sotto re_clear_display(el);
806df930be7Sderaadt return CC_REFRESH;
807df930be7Sderaadt }
808