1*5b133f3fSguenther /* $OpenBSD: emacs.c,v 1.18 2023/03/08 04:43:05 guenther Exp $ */
213e01c7aSschwarze /* $NetBSD: emacs.c,v 1.35 2016/04/18 17:01:19 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 * emacs.c: Emacs functions
40df930be7Sderaadt */
417ccfa089Sschwarze #include <ctype.h>
427ccfa089Sschwarze
43df930be7Sderaadt #include "el.h"
445564fb94Sschwarze #include "emacs.h"
4513e01c7aSschwarze #include "fcns.h"
46df930be7Sderaadt
47df930be7Sderaadt /* em_delete_or_list():
48df930be7Sderaadt * Delete character under cursor or list completions if at end of line
49df930be7Sderaadt * [^D]
50df930be7Sderaadt */
51df930be7Sderaadt protected el_action_t
em_delete_or_list(EditLine * el,wint_t c)52b2589f0bSschwarze em_delete_or_list(EditLine *el, wint_t c)
53df930be7Sderaadt {
54d484b7d0Sotto
55d484b7d0Sotto if (el->el_line.cursor == el->el_line.lastchar) {
56d484b7d0Sotto /* if I'm at the end */
57d484b7d0Sotto if (el->el_line.cursor == el->el_line.buffer) {
58d484b7d0Sotto /* and the beginning */
59fd40972aSschwarze terminal_writec(el, c); /* then do an EOF */
6028d54ee8Sschwarze return CC_EOF;
61d484b7d0Sotto } else {
62d484b7d0Sotto /*
63d484b7d0Sotto * Here we could list completions, but it is an
64d484b7d0Sotto * error right now
65d484b7d0Sotto */
66fd40972aSschwarze terminal_beep(el);
6728d54ee8Sschwarze return CC_ERROR;
68df930be7Sderaadt }
69d484b7d0Sotto } else {
70aed0ee81Snicm if (el->el_state.doingarg)
71aed0ee81Snicm c_delafter(el, el->el_state.argument);
72aed0ee81Snicm else
73aed0ee81Snicm c_delafter1(el);
74df930be7Sderaadt if (el->el_line.cursor > el->el_line.lastchar)
75d484b7d0Sotto el->el_line.cursor = el->el_line.lastchar;
76d484b7d0Sotto /* bounds check */
7728d54ee8Sschwarze return CC_REFRESH;
78df930be7Sderaadt }
79df930be7Sderaadt }
80df930be7Sderaadt
81df930be7Sderaadt
82df930be7Sderaadt /* em_delete_next_word():
83df930be7Sderaadt * Cut from cursor to end of current word
84df930be7Sderaadt * [M-d]
85df930be7Sderaadt */
86df930be7Sderaadt protected el_action_t
em_delete_next_word(EditLine * el,wint_t c)87b2589f0bSschwarze em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
88df930be7Sderaadt {
89e3191321Sschwarze wchar_t *cp, *p, *kp;
90df930be7Sderaadt
91df930be7Sderaadt if (el->el_line.cursor == el->el_line.lastchar)
9228d54ee8Sschwarze return CC_ERROR;
93df930be7Sderaadt
94df930be7Sderaadt cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
95df930be7Sderaadt el->el_state.argument, ce__isword);
96df930be7Sderaadt
97df930be7Sderaadt for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
98df930be7Sderaadt /* save the text */
99df930be7Sderaadt *kp++ = *p;
100df930be7Sderaadt el->el_chared.c_kill.last = kp;
101df930be7Sderaadt
102aed0ee81Snicm c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
103df930be7Sderaadt if (el->el_line.cursor > el->el_line.lastchar)
104d484b7d0Sotto el->el_line.cursor = el->el_line.lastchar;
105d484b7d0Sotto /* bounds check */
10628d54ee8Sschwarze return CC_REFRESH;
107df930be7Sderaadt }
108df930be7Sderaadt
109df930be7Sderaadt
110df930be7Sderaadt /* em_yank():
111df930be7Sderaadt * Paste cut buffer at cursor position
112df930be7Sderaadt * [^Y]
113df930be7Sderaadt */
114df930be7Sderaadt protected el_action_t
em_yank(EditLine * el,wint_t c)115b2589f0bSschwarze em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
116df930be7Sderaadt {
117e3191321Sschwarze wchar_t *kp, *cp;
118df930be7Sderaadt
1196e02e073Sotto if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
12028d54ee8Sschwarze return CC_NORM;
121df930be7Sderaadt
122df930be7Sderaadt if (el->el_line.lastchar +
123df930be7Sderaadt (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
124df930be7Sderaadt el->el_line.limit)
12528d54ee8Sschwarze return CC_ERROR;
126df930be7Sderaadt
127df930be7Sderaadt el->el_chared.c_kill.mark = el->el_line.cursor;
128df930be7Sderaadt cp = el->el_line.cursor;
129df930be7Sderaadt
130df930be7Sderaadt /* open the space, */
131aed0ee81Snicm c_insert(el,
132aed0ee81Snicm (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
133df930be7Sderaadt /* copy the chars */
134df930be7Sderaadt for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
135df930be7Sderaadt *cp++ = *kp;
136df930be7Sderaadt
137df930be7Sderaadt /* if an arg, cursor at beginning else cursor at end */
138df930be7Sderaadt if (el->el_state.argument == 1)
139df930be7Sderaadt el->el_line.cursor = cp;
140df930be7Sderaadt
14128d54ee8Sschwarze return CC_REFRESH;
142df930be7Sderaadt }
143df930be7Sderaadt
144df930be7Sderaadt
145df930be7Sderaadt /* em_kill_line():
146df930be7Sderaadt * Cut the entire line and save in cut buffer
147df930be7Sderaadt * [^U]
148df930be7Sderaadt */
149df930be7Sderaadt protected el_action_t
em_kill_line(EditLine * el,wint_t c)150b2589f0bSschwarze em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
151df930be7Sderaadt {
152e3191321Sschwarze wchar_t *kp, *cp;
153df930be7Sderaadt
154df930be7Sderaadt cp = el->el_line.buffer;
155df930be7Sderaadt kp = el->el_chared.c_kill.buf;
156df930be7Sderaadt while (cp < el->el_line.lastchar)
157df930be7Sderaadt *kp++ = *cp++; /* copy it */
158df930be7Sderaadt el->el_chared.c_kill.last = kp;
159d484b7d0Sotto /* zap! -- delete all of it */
160d484b7d0Sotto el->el_line.lastchar = el->el_line.buffer;
161df930be7Sderaadt el->el_line.cursor = el->el_line.buffer;
16228d54ee8Sschwarze return CC_REFRESH;
163df930be7Sderaadt }
164df930be7Sderaadt
165df930be7Sderaadt
166df930be7Sderaadt /* em_kill_region():
167df930be7Sderaadt * Cut area between mark and cursor and save in cut buffer
168df930be7Sderaadt * [^W]
169df930be7Sderaadt */
170df930be7Sderaadt protected el_action_t
em_kill_region(EditLine * el,wint_t c)171b2589f0bSschwarze em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
172df930be7Sderaadt {
173e3191321Sschwarze wchar_t *kp, *cp;
174df930be7Sderaadt
175df930be7Sderaadt if (!el->el_chared.c_kill.mark)
17628d54ee8Sschwarze return CC_ERROR;
177df930be7Sderaadt
178df930be7Sderaadt if (el->el_chared.c_kill.mark > el->el_line.cursor) {
179df930be7Sderaadt cp = el->el_line.cursor;
180df930be7Sderaadt kp = el->el_chared.c_kill.buf;
181df930be7Sderaadt while (cp < el->el_chared.c_kill.mark)
182df930be7Sderaadt *kp++ = *cp++; /* copy it */
183df930be7Sderaadt el->el_chared.c_kill.last = kp;
184aed0ee81Snicm c_delafter(el, (int)(cp - el->el_line.cursor));
185d484b7d0Sotto } else { /* mark is before cursor */
186df930be7Sderaadt cp = el->el_chared.c_kill.mark;
187df930be7Sderaadt kp = el->el_chared.c_kill.buf;
188df930be7Sderaadt while (cp < el->el_line.cursor)
189df930be7Sderaadt *kp++ = *cp++; /* copy it */
190df930be7Sderaadt el->el_chared.c_kill.last = kp;
191aed0ee81Snicm c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
192df930be7Sderaadt el->el_line.cursor = el->el_chared.c_kill.mark;
193df930be7Sderaadt }
19428d54ee8Sschwarze return CC_REFRESH;
195df930be7Sderaadt }
196df930be7Sderaadt
197df930be7Sderaadt
198df930be7Sderaadt /* em_copy_region():
199df930be7Sderaadt * Copy area between mark and cursor to cut buffer
200df930be7Sderaadt * [M-W]
201df930be7Sderaadt */
202df930be7Sderaadt protected el_action_t
em_copy_region(EditLine * el,wint_t c)203b2589f0bSschwarze em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
204df930be7Sderaadt {
205e3191321Sschwarze wchar_t *kp, *cp;
206df930be7Sderaadt
207d484b7d0Sotto if (!el->el_chared.c_kill.mark)
20828d54ee8Sschwarze return CC_ERROR;
209df930be7Sderaadt
210df930be7Sderaadt if (el->el_chared.c_kill.mark > el->el_line.cursor) {
211df930be7Sderaadt cp = el->el_line.cursor;
212df930be7Sderaadt kp = el->el_chared.c_kill.buf;
213df930be7Sderaadt while (cp < el->el_chared.c_kill.mark)
214df930be7Sderaadt *kp++ = *cp++; /* copy it */
215df930be7Sderaadt el->el_chared.c_kill.last = kp;
216d484b7d0Sotto } else {
217df930be7Sderaadt cp = el->el_chared.c_kill.mark;
218df930be7Sderaadt kp = el->el_chared.c_kill.buf;
219df930be7Sderaadt while (cp < el->el_line.cursor)
220df930be7Sderaadt *kp++ = *cp++; /* copy it */
221df930be7Sderaadt el->el_chared.c_kill.last = kp;
222df930be7Sderaadt }
22328d54ee8Sschwarze return CC_NORM;
224df930be7Sderaadt }
225df930be7Sderaadt
226df930be7Sderaadt
227d484b7d0Sotto /* em_gosmacs_transpose():
228df930be7Sderaadt * Exchange the two characters before the cursor
229df930be7Sderaadt * Gosling emacs transpose chars [^T]
230df930be7Sderaadt */
231df930be7Sderaadt protected el_action_t
em_gosmacs_transpose(EditLine * el,wint_t c)232b2589f0bSschwarze em_gosmacs_transpose(EditLine *el, wint_t c)
233df930be7Sderaadt {
234df930be7Sderaadt
235df930be7Sderaadt if (el->el_line.cursor > &el->el_line.buffer[1]) {
236df930be7Sderaadt /* must have at least two chars entered */
237df930be7Sderaadt c = el->el_line.cursor[-2];
238df930be7Sderaadt el->el_line.cursor[-2] = el->el_line.cursor[-1];
239df930be7Sderaadt el->el_line.cursor[-1] = c;
24028d54ee8Sschwarze return CC_REFRESH;
241d484b7d0Sotto } else
24228d54ee8Sschwarze return CC_ERROR;
243df930be7Sderaadt }
244df930be7Sderaadt
245df930be7Sderaadt
246df930be7Sderaadt /* em_next_word():
247df930be7Sderaadt * Move next to end of current word
248df930be7Sderaadt * [M-f]
249df930be7Sderaadt */
250df930be7Sderaadt protected el_action_t
em_next_word(EditLine * el,wint_t c)251b2589f0bSschwarze em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
252df930be7Sderaadt {
253df930be7Sderaadt if (el->el_line.cursor == el->el_line.lastchar)
25428d54ee8Sschwarze return CC_ERROR;
255df930be7Sderaadt
256d484b7d0Sotto el->el_line.cursor = c__next_word(el->el_line.cursor,
257d484b7d0Sotto el->el_line.lastchar,
258df930be7Sderaadt el->el_state.argument,
259df930be7Sderaadt ce__isword);
260df930be7Sderaadt
261df930be7Sderaadt if (el->el_map.type == MAP_VI)
262d484b7d0Sotto if (el->el_chared.c_vcmd.action != NOP) {
263df930be7Sderaadt cv_delfini(el);
26428d54ee8Sschwarze return CC_REFRESH;
265d484b7d0Sotto }
26628d54ee8Sschwarze return CC_CURSOR;
267df930be7Sderaadt }
268df930be7Sderaadt
269df930be7Sderaadt
270df930be7Sderaadt /* em_upper_case():
271df930be7Sderaadt * Uppercase the characters from cursor to end of current word
272df930be7Sderaadt * [M-u]
273df930be7Sderaadt */
274df930be7Sderaadt protected el_action_t
em_upper_case(EditLine * el,wint_t c)275b2589f0bSschwarze em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
276df930be7Sderaadt {
277e3191321Sschwarze wchar_t *cp, *ep;
278df930be7Sderaadt
279df930be7Sderaadt ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
280df930be7Sderaadt el->el_state.argument, ce__isword);
281df930be7Sderaadt
282df930be7Sderaadt for (cp = el->el_line.cursor; cp < ep; cp++)
283565aa7e8Sschwarze if (iswlower(*cp))
284565aa7e8Sschwarze *cp = towupper(*cp);
285df930be7Sderaadt
286df930be7Sderaadt el->el_line.cursor = ep;
287df930be7Sderaadt if (el->el_line.cursor > el->el_line.lastchar)
288df930be7Sderaadt el->el_line.cursor = el->el_line.lastchar;
28928d54ee8Sschwarze return CC_REFRESH;
290df930be7Sderaadt }
291df930be7Sderaadt
292df930be7Sderaadt
293df930be7Sderaadt /* em_capitol_case():
294df930be7Sderaadt * Capitalize the characters from cursor to end of current word
295df930be7Sderaadt * [M-c]
296df930be7Sderaadt */
297df930be7Sderaadt protected el_action_t
em_capitol_case(EditLine * el,wint_t c)298b2589f0bSschwarze em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
299df930be7Sderaadt {
300e3191321Sschwarze wchar_t *cp, *ep;
301df930be7Sderaadt
302df930be7Sderaadt ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
303df930be7Sderaadt el->el_state.argument, ce__isword);
304df930be7Sderaadt
305df930be7Sderaadt for (cp = el->el_line.cursor; cp < ep; cp++) {
306565aa7e8Sschwarze if (iswalpha(*cp)) {
307565aa7e8Sschwarze if (iswlower(*cp))
308565aa7e8Sschwarze *cp = towupper(*cp);
309df930be7Sderaadt cp++;
310df930be7Sderaadt break;
311df930be7Sderaadt }
312df930be7Sderaadt }
313df930be7Sderaadt for (; cp < ep; cp++)
314565aa7e8Sschwarze if (iswupper(*cp))
315565aa7e8Sschwarze *cp = towlower(*cp);
316df930be7Sderaadt
317df930be7Sderaadt el->el_line.cursor = ep;
318df930be7Sderaadt if (el->el_line.cursor > el->el_line.lastchar)
319df930be7Sderaadt el->el_line.cursor = el->el_line.lastchar;
32028d54ee8Sschwarze return CC_REFRESH;
321df930be7Sderaadt }
322df930be7Sderaadt
323d484b7d0Sotto
324df930be7Sderaadt /* em_lower_case():
325df930be7Sderaadt * Lowercase the characters from cursor to end of current word
326df930be7Sderaadt * [M-l]
327df930be7Sderaadt */
328df930be7Sderaadt protected el_action_t
em_lower_case(EditLine * el,wint_t c)329b2589f0bSschwarze em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
330df930be7Sderaadt {
331e3191321Sschwarze wchar_t *cp, *ep;
332df930be7Sderaadt
333df930be7Sderaadt ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
334df930be7Sderaadt el->el_state.argument, ce__isword);
335df930be7Sderaadt
336df930be7Sderaadt for (cp = el->el_line.cursor; cp < ep; cp++)
337565aa7e8Sschwarze if (iswupper(*cp))
338565aa7e8Sschwarze *cp = towlower(*cp);
339df930be7Sderaadt
340df930be7Sderaadt el->el_line.cursor = ep;
341df930be7Sderaadt if (el->el_line.cursor > el->el_line.lastchar)
342df930be7Sderaadt el->el_line.cursor = el->el_line.lastchar;
34328d54ee8Sschwarze return CC_REFRESH;
344df930be7Sderaadt }
345df930be7Sderaadt
346df930be7Sderaadt
347df930be7Sderaadt /* em_set_mark():
348df930be7Sderaadt * Set the mark at cursor
349df930be7Sderaadt * [^@]
350df930be7Sderaadt */
351df930be7Sderaadt protected el_action_t
em_set_mark(EditLine * el,wint_t c)352b2589f0bSschwarze em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
353df930be7Sderaadt {
354d484b7d0Sotto
355df930be7Sderaadt el->el_chared.c_kill.mark = el->el_line.cursor;
35628d54ee8Sschwarze return CC_NORM;
357df930be7Sderaadt }
358df930be7Sderaadt
359df930be7Sderaadt
360df930be7Sderaadt /* em_exchange_mark():
361df930be7Sderaadt * Exchange the cursor and mark
362df930be7Sderaadt * [^X^X]
363df930be7Sderaadt */
364df930be7Sderaadt protected el_action_t
em_exchange_mark(EditLine * el,wint_t c)365b2589f0bSschwarze em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
366df930be7Sderaadt {
367e3191321Sschwarze wchar_t *cp;
368df930be7Sderaadt
369df930be7Sderaadt cp = el->el_line.cursor;
370df930be7Sderaadt el->el_line.cursor = el->el_chared.c_kill.mark;
371df930be7Sderaadt el->el_chared.c_kill.mark = cp;
37228d54ee8Sschwarze return CC_CURSOR;
373df930be7Sderaadt }
374df930be7Sderaadt
375d484b7d0Sotto
376df930be7Sderaadt /* em_universal_argument():
377df930be7Sderaadt * Universal argument (argument times 4)
378df930be7Sderaadt * [^U]
379df930be7Sderaadt */
380df930be7Sderaadt protected el_action_t
em_universal_argument(EditLine * el,wint_t c)381b2589f0bSschwarze em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
382df930be7Sderaadt { /* multiply current argument by 4 */
383d484b7d0Sotto
384df930be7Sderaadt if (el->el_state.argument > 1000000)
38528d54ee8Sschwarze return CC_ERROR;
386df930be7Sderaadt el->el_state.doingarg = 1;
387df930be7Sderaadt el->el_state.argument *= 4;
38828d54ee8Sschwarze return CC_ARGHACK;
389df930be7Sderaadt }
390df930be7Sderaadt
391d484b7d0Sotto
392df930be7Sderaadt /* em_meta_next():
393df930be7Sderaadt * Add 8th bit to next character typed
394df930be7Sderaadt * [<ESC>]
395df930be7Sderaadt */
396df930be7Sderaadt protected el_action_t
em_meta_next(EditLine * el,wint_t c)397b2589f0bSschwarze em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
398df930be7Sderaadt {
399d484b7d0Sotto
400df930be7Sderaadt el->el_state.metanext = 1;
40128d54ee8Sschwarze return CC_ARGHACK;
402df930be7Sderaadt }
403df930be7Sderaadt
404df930be7Sderaadt
405df930be7Sderaadt /* em_toggle_overwrite():
406df930be7Sderaadt * Switch from insert to overwrite mode or vice versa
407df930be7Sderaadt */
408df930be7Sderaadt protected el_action_t
em_toggle_overwrite(EditLine * el,wint_t c)409b2589f0bSschwarze em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
410df930be7Sderaadt {
411d484b7d0Sotto
412d484b7d0Sotto el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
413d484b7d0Sotto MODE_REPLACE : MODE_INSERT;
41428d54ee8Sschwarze return CC_NORM;
415df930be7Sderaadt }
416df930be7Sderaadt
417df930be7Sderaadt
418df930be7Sderaadt /* em_copy_prev_word():
419df930be7Sderaadt * Copy current word to cursor
420df930be7Sderaadt */
421df930be7Sderaadt protected el_action_t
em_copy_prev_word(EditLine * el,wint_t c)422b2589f0bSschwarze em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
423df930be7Sderaadt {
424e3191321Sschwarze wchar_t *cp, *oldc, *dp;
425df930be7Sderaadt
426df930be7Sderaadt if (el->el_line.cursor == el->el_line.buffer)
42728d54ee8Sschwarze return CC_ERROR;
428df930be7Sderaadt
429df930be7Sderaadt oldc = el->el_line.cursor;
430df930be7Sderaadt /* does a bounds check */
431df930be7Sderaadt cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
432df930be7Sderaadt el->el_state.argument, ce__isword);
433df930be7Sderaadt
434aed0ee81Snicm c_insert(el, (int)(oldc - cp));
435df930be7Sderaadt for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
436df930be7Sderaadt *dp++ = *cp;
437df930be7Sderaadt
438df930be7Sderaadt el->el_line.cursor = dp;/* put cursor at end */
439df930be7Sderaadt
44028d54ee8Sschwarze return CC_REFRESH;
441df930be7Sderaadt }
442df930be7Sderaadt
443df930be7Sderaadt
444df930be7Sderaadt /* em_inc_search_next():
445df930be7Sderaadt * Emacs incremental next search
446df930be7Sderaadt */
447df930be7Sderaadt protected el_action_t
em_inc_search_next(EditLine * el,wint_t c)448b2589f0bSschwarze em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
449df930be7Sderaadt {
450d484b7d0Sotto
451df930be7Sderaadt el->el_search.patlen = 0;
45228d54ee8Sschwarze return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
453df930be7Sderaadt }
454df930be7Sderaadt
455df930be7Sderaadt
456df930be7Sderaadt /* em_inc_search_prev():
457df930be7Sderaadt * Emacs incremental reverse search
458df930be7Sderaadt */
459df930be7Sderaadt protected el_action_t
em_inc_search_prev(EditLine * el,wint_t c)460b2589f0bSschwarze em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
461df930be7Sderaadt {
462d484b7d0Sotto
463df930be7Sderaadt el->el_search.patlen = 0;
46428d54ee8Sschwarze return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
465df930be7Sderaadt }
466aed0ee81Snicm
467aed0ee81Snicm
468aed0ee81Snicm /* em_delete_prev_char():
469aed0ee81Snicm * Delete the character to the left of the cursor
470aed0ee81Snicm * [^?]
471aed0ee81Snicm */
472aed0ee81Snicm protected el_action_t
em_delete_prev_char(EditLine * el,wint_t c)473b2589f0bSschwarze em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
474aed0ee81Snicm {
475aed0ee81Snicm
476aed0ee81Snicm if (el->el_line.cursor <= el->el_line.buffer)
47728d54ee8Sschwarze return CC_ERROR;
478aed0ee81Snicm
479aed0ee81Snicm if (el->el_state.doingarg)
480aed0ee81Snicm c_delbefore(el, el->el_state.argument);
481aed0ee81Snicm else
482aed0ee81Snicm c_delbefore1(el);
483aed0ee81Snicm el->el_line.cursor -= el->el_state.argument;
484aed0ee81Snicm if (el->el_line.cursor < el->el_line.buffer)
485aed0ee81Snicm el->el_line.cursor = el->el_line.buffer;
48628d54ee8Sschwarze return CC_REFRESH;
487aed0ee81Snicm }
488