1*8ffafb93Schristos /* $NetBSD: emacs.c,v 1.38 2024/06/29 17:28:07 christos Exp $ */
22543e3e6Slukem
36dc2f1dbScgd /*-
46dc2f1dbScgd * Copyright (c) 1992, 1993
56dc2f1dbScgd * The Regents of the University of California. All rights reserved.
66dc2f1dbScgd *
76dc2f1dbScgd * This code is derived from software contributed to Berkeley by
86dc2f1dbScgd * Christos Zoulas of Cornell University.
96dc2f1dbScgd *
106dc2f1dbScgd * Redistribution and use in source and binary forms, with or without
116dc2f1dbScgd * modification, are permitted provided that the following conditions
126dc2f1dbScgd * are met:
136dc2f1dbScgd * 1. Redistributions of source code must retain the above copyright
146dc2f1dbScgd * notice, this list of conditions and the following disclaimer.
156dc2f1dbScgd * 2. Redistributions in binary form must reproduce the above copyright
166dc2f1dbScgd * notice, this list of conditions and the following disclaimer in the
176dc2f1dbScgd * documentation and/or other materials provided with the distribution.
18eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors
196dc2f1dbScgd * may be used to endorse or promote products derived from this software
206dc2f1dbScgd * without specific prior written permission.
216dc2f1dbScgd *
226dc2f1dbScgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
236dc2f1dbScgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
246dc2f1dbScgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
256dc2f1dbScgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
266dc2f1dbScgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
276dc2f1dbScgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
286dc2f1dbScgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
296dc2f1dbScgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
306dc2f1dbScgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
316dc2f1dbScgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
326dc2f1dbScgd * SUCH DAMAGE.
336dc2f1dbScgd */
346dc2f1dbScgd
350e0ac6b7Schristos #include "config.h"
366dc2f1dbScgd #if !defined(lint) && !defined(SCCSID)
372543e3e6Slukem #if 0
386dc2f1dbScgd static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
392543e3e6Slukem #else
40*8ffafb93Schristos __RCSID("$NetBSD: emacs.c,v 1.38 2024/06/29 17:28:07 christos Exp $");
412543e3e6Slukem #endif
426dc2f1dbScgd #endif /* not lint && not SCCSID */
436dc2f1dbScgd
446dc2f1dbScgd /*
456dc2f1dbScgd * emacs.c: Emacs functions
466dc2f1dbScgd */
47e84df91eSchristos #include <ctype.h>
48e84df91eSchristos
496dc2f1dbScgd #include "el.h"
50747f6811Schristos #include "emacs.h"
514fc1f47dSchristos #include "fcns.h"
526dc2f1dbScgd
536dc2f1dbScgd /* em_delete_or_list():
546dc2f1dbScgd * Delete character under cursor or list completions if at end of line
556dc2f1dbScgd * [^D]
566dc2f1dbScgd */
57a2d6b270Schristos libedit_private el_action_t
586dc2f1dbScgd /*ARGSUSED*/
em_delete_or_list(EditLine * el,wint_t c)59f54e4f97Schristos em_delete_or_list(EditLine *el, wint_t c)
606dc2f1dbScgd {
61d30d584aSlukem
62d30d584aSlukem if (el->el_line.cursor == el->el_line.lastchar) {
63d30d584aSlukem /* if I'm at the end */
64d30d584aSlukem if (el->el_line.cursor == el->el_line.buffer) {
65d30d584aSlukem /* and the beginning */
6698c7cbebSchristos terminal_writec(el, c); /* then do an EOF */
67b71bed95Schristos return CC_EOF;
68d30d584aSlukem } else {
69d30d584aSlukem /*
70d30d584aSlukem * Here we could list completions, but it is an
71d30d584aSlukem * error right now
72d30d584aSlukem */
7398c7cbebSchristos terminal_beep(el);
74b71bed95Schristos return CC_ERROR;
756dc2f1dbScgd }
76d30d584aSlukem } else {
776360c4b0Smycroft if (el->el_state.doingarg)
786360c4b0Smycroft c_delafter(el, el->el_state.argument);
796360c4b0Smycroft else
806360c4b0Smycroft c_delafter1(el);
816dc2f1dbScgd if (el->el_line.cursor > el->el_line.lastchar)
82d30d584aSlukem el->el_line.cursor = el->el_line.lastchar;
83d30d584aSlukem /* bounds check */
84b71bed95Schristos return CC_REFRESH;
856dc2f1dbScgd }
866dc2f1dbScgd }
876dc2f1dbScgd
886dc2f1dbScgd
896dc2f1dbScgd /* em_delete_next_word():
906dc2f1dbScgd * Cut from cursor to end of current word
916dc2f1dbScgd * [M-d]
926dc2f1dbScgd */
93a2d6b270Schristos libedit_private el_action_t
946dc2f1dbScgd /*ARGSUSED*/
em_delete_next_word(EditLine * el,wint_t c)95f54e4f97Schristos em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
966dc2f1dbScgd {
970594af80Schristos wchar_t *cp, *p, *kp;
986dc2f1dbScgd
996dc2f1dbScgd if (el->el_line.cursor == el->el_line.lastchar)
100b71bed95Schristos return CC_ERROR;
1016dc2f1dbScgd
1026dc2f1dbScgd cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
1036dc2f1dbScgd el->el_state.argument, ce__isword);
1046dc2f1dbScgd
1056dc2f1dbScgd for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
1066dc2f1dbScgd /* save the text */
1076dc2f1dbScgd *kp++ = *p;
1086dc2f1dbScgd el->el_chared.c_kill.last = kp;
1096dc2f1dbScgd
1105c894153Schristos c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
1116dc2f1dbScgd if (el->el_line.cursor > el->el_line.lastchar)
112d30d584aSlukem el->el_line.cursor = el->el_line.lastchar;
113d30d584aSlukem /* bounds check */
114b71bed95Schristos return CC_REFRESH;
1156dc2f1dbScgd }
1166dc2f1dbScgd
1176dc2f1dbScgd
1186dc2f1dbScgd /* em_yank():
1196dc2f1dbScgd * Paste cut buffer at cursor position
1206dc2f1dbScgd * [^Y]
1216dc2f1dbScgd */
122a2d6b270Schristos libedit_private el_action_t
1236dc2f1dbScgd /*ARGSUSED*/
em_yank(EditLine * el,wint_t c)124f54e4f97Schristos em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
1256dc2f1dbScgd {
1260594af80Schristos wchar_t *kp, *cp;
1276dc2f1dbScgd
12872dc1c2aSchristos if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
129b71bed95Schristos return CC_NORM;
1306dc2f1dbScgd
1316dc2f1dbScgd if (el->el_line.lastchar +
1326dc2f1dbScgd (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
1336dc2f1dbScgd el->el_line.limit)
134b71bed95Schristos return CC_ERROR;
1356dc2f1dbScgd
1366dc2f1dbScgd el->el_chared.c_kill.mark = el->el_line.cursor;
1376dc2f1dbScgd
1386dc2f1dbScgd /* open the space, */
1395c894153Schristos c_insert(el,
1405c894153Schristos (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
141427b3799Schristos cp = el->el_line.cursor;
1426dc2f1dbScgd /* copy the chars */
1436dc2f1dbScgd for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
1446dc2f1dbScgd *cp++ = *kp;
1456dc2f1dbScgd
1466dc2f1dbScgd /* if an arg, cursor at beginning else cursor at end */
1476dc2f1dbScgd if (el->el_state.argument == 1)
1486dc2f1dbScgd el->el_line.cursor = cp;
1496dc2f1dbScgd
150b71bed95Schristos return CC_REFRESH;
1516dc2f1dbScgd }
1526dc2f1dbScgd
1536dc2f1dbScgd
1546dc2f1dbScgd /* em_kill_line():
1556dc2f1dbScgd * Cut the entire line and save in cut buffer
1566dc2f1dbScgd * [^U]
1576dc2f1dbScgd */
158a2d6b270Schristos libedit_private el_action_t
1596dc2f1dbScgd /*ARGSUSED*/
em_kill_line(EditLine * el,wint_t c)160f54e4f97Schristos em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
1616dc2f1dbScgd {
1620594af80Schristos wchar_t *kp, *cp;
1636dc2f1dbScgd
1646dc2f1dbScgd cp = el->el_line.buffer;
1656dc2f1dbScgd kp = el->el_chared.c_kill.buf;
1666dc2f1dbScgd while (cp < el->el_line.lastchar)
1676dc2f1dbScgd *kp++ = *cp++; /* copy it */
1686dc2f1dbScgd el->el_chared.c_kill.last = kp;
169d30d584aSlukem /* zap! -- delete all of it */
170d30d584aSlukem el->el_line.lastchar = el->el_line.buffer;
1716dc2f1dbScgd el->el_line.cursor = el->el_line.buffer;
172b71bed95Schristos return CC_REFRESH;
1736dc2f1dbScgd }
1746dc2f1dbScgd
1756dc2f1dbScgd
1766dc2f1dbScgd /* em_kill_region():
1776dc2f1dbScgd * Cut area between mark and cursor and save in cut buffer
1786dc2f1dbScgd * [^W]
1796dc2f1dbScgd */
180a2d6b270Schristos libedit_private el_action_t
1816dc2f1dbScgd /*ARGSUSED*/
em_kill_region(EditLine * el,wint_t c)182f54e4f97Schristos em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
1836dc2f1dbScgd {
1840594af80Schristos wchar_t *kp, *cp;
1856dc2f1dbScgd
1866dc2f1dbScgd if (!el->el_chared.c_kill.mark)
187b71bed95Schristos return CC_ERROR;
1886dc2f1dbScgd
1896dc2f1dbScgd if (el->el_chared.c_kill.mark > el->el_line.cursor) {
1906dc2f1dbScgd cp = el->el_line.cursor;
1916dc2f1dbScgd kp = el->el_chared.c_kill.buf;
1926dc2f1dbScgd while (cp < el->el_chared.c_kill.mark)
1936dc2f1dbScgd *kp++ = *cp++; /* copy it */
1946dc2f1dbScgd el->el_chared.c_kill.last = kp;
1955c894153Schristos c_delafter(el, (int)(cp - el->el_line.cursor));
196d30d584aSlukem } else { /* mark is before cursor */
1976dc2f1dbScgd cp = el->el_chared.c_kill.mark;
1986dc2f1dbScgd kp = el->el_chared.c_kill.buf;
1996dc2f1dbScgd while (cp < el->el_line.cursor)
2006dc2f1dbScgd *kp++ = *cp++; /* copy it */
2016dc2f1dbScgd el->el_chared.c_kill.last = kp;
2025c894153Schristos c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
2036dc2f1dbScgd el->el_line.cursor = el->el_chared.c_kill.mark;
2046dc2f1dbScgd }
205b71bed95Schristos return CC_REFRESH;
2066dc2f1dbScgd }
2076dc2f1dbScgd
2086dc2f1dbScgd
2096dc2f1dbScgd /* em_copy_region():
2106dc2f1dbScgd * Copy area between mark and cursor to cut buffer
2116dc2f1dbScgd * [M-W]
2126dc2f1dbScgd */
213a2d6b270Schristos libedit_private el_action_t
2146dc2f1dbScgd /*ARGSUSED*/
em_copy_region(EditLine * el,wint_t c)215f54e4f97Schristos em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
2166dc2f1dbScgd {
2170594af80Schristos wchar_t *kp, *cp;
2186dc2f1dbScgd
219a17c7fe4Schristos if (!el->el_chared.c_kill.mark)
220b71bed95Schristos return CC_ERROR;
2216dc2f1dbScgd
2226dc2f1dbScgd if (el->el_chared.c_kill.mark > el->el_line.cursor) {
2236dc2f1dbScgd cp = el->el_line.cursor;
2246dc2f1dbScgd kp = el->el_chared.c_kill.buf;
2256dc2f1dbScgd while (cp < el->el_chared.c_kill.mark)
2266dc2f1dbScgd *kp++ = *cp++; /* copy it */
2276dc2f1dbScgd el->el_chared.c_kill.last = kp;
228d30d584aSlukem } else {
2296dc2f1dbScgd cp = el->el_chared.c_kill.mark;
2306dc2f1dbScgd kp = el->el_chared.c_kill.buf;
2316dc2f1dbScgd while (cp < el->el_line.cursor)
2326dc2f1dbScgd *kp++ = *cp++; /* copy it */
2336dc2f1dbScgd el->el_chared.c_kill.last = kp;
2346dc2f1dbScgd }
235b71bed95Schristos return CC_NORM;
2366dc2f1dbScgd }
2376dc2f1dbScgd
2386dc2f1dbScgd
23970286103Sperry /* em_gosmacs_transpose():
2406dc2f1dbScgd * Exchange the two characters before the cursor
2416dc2f1dbScgd * Gosling emacs transpose chars [^T]
2426dc2f1dbScgd */
243a2d6b270Schristos libedit_private el_action_t
em_gosmacs_transpose(EditLine * el,wint_t c)244f54e4f97Schristos em_gosmacs_transpose(EditLine *el, wint_t c)
2456dc2f1dbScgd {
2466dc2f1dbScgd
2476dc2f1dbScgd if (el->el_line.cursor > &el->el_line.buffer[1]) {
2486dc2f1dbScgd /* must have at least two chars entered */
2496dc2f1dbScgd c = el->el_line.cursor[-2];
2506dc2f1dbScgd el->el_line.cursor[-2] = el->el_line.cursor[-1];
2510594af80Schristos el->el_line.cursor[-1] = c;
252b71bed95Schristos return CC_REFRESH;
253d30d584aSlukem } else
254b71bed95Schristos return CC_ERROR;
2556dc2f1dbScgd }
2566dc2f1dbScgd
2576dc2f1dbScgd
2586dc2f1dbScgd /* em_next_word():
2596dc2f1dbScgd * Move next to end of current word
2606dc2f1dbScgd * [M-f]
2616dc2f1dbScgd */
262a2d6b270Schristos libedit_private el_action_t
2636dc2f1dbScgd /*ARGSUSED*/
em_next_word(EditLine * el,wint_t c)264f54e4f97Schristos em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
2656dc2f1dbScgd {
2666dc2f1dbScgd if (el->el_line.cursor == el->el_line.lastchar)
267b71bed95Schristos return CC_ERROR;
2686dc2f1dbScgd
269d30d584aSlukem el->el_line.cursor = c__next_word(el->el_line.cursor,
270d30d584aSlukem el->el_line.lastchar,
2716dc2f1dbScgd el->el_state.argument,
2726dc2f1dbScgd ce__isword);
2736dc2f1dbScgd
2746dc2f1dbScgd if (el->el_map.type == MAP_VI)
27539f224afSchristos if (el->el_chared.c_vcmd.action != NOP) {
2766dc2f1dbScgd cv_delfini(el);
277b71bed95Schristos return CC_REFRESH;
278d30d584aSlukem }
279b71bed95Schristos return CC_CURSOR;
2806dc2f1dbScgd }
2816dc2f1dbScgd
2826dc2f1dbScgd
2836dc2f1dbScgd /* em_upper_case():
2846dc2f1dbScgd * Uppercase the characters from cursor to end of current word
2856dc2f1dbScgd * [M-u]
2866dc2f1dbScgd */
287a2d6b270Schristos libedit_private el_action_t
2886dc2f1dbScgd /*ARGSUSED*/
em_upper_case(EditLine * el,wint_t c)289f54e4f97Schristos em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
2906dc2f1dbScgd {
2910594af80Schristos wchar_t *cp, *ep;
2926dc2f1dbScgd
2936dc2f1dbScgd ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
2946dc2f1dbScgd el->el_state.argument, ce__isword);
2956dc2f1dbScgd
2966dc2f1dbScgd for (cp = el->el_line.cursor; cp < ep; cp++)
297fcf85103Schristos if (iswlower(*cp))
298fcf85103Schristos *cp = towupper(*cp);
2996dc2f1dbScgd
3006dc2f1dbScgd el->el_line.cursor = ep;
3016dc2f1dbScgd if (el->el_line.cursor > el->el_line.lastchar)
3026dc2f1dbScgd el->el_line.cursor = el->el_line.lastchar;
303b71bed95Schristos return CC_REFRESH;
3046dc2f1dbScgd }
3056dc2f1dbScgd
3066dc2f1dbScgd
3076dc2f1dbScgd /* em_capitol_case():
3086dc2f1dbScgd * Capitalize the characters from cursor to end of current word
3096dc2f1dbScgd * [M-c]
3106dc2f1dbScgd */
311a2d6b270Schristos libedit_private el_action_t
3126dc2f1dbScgd /*ARGSUSED*/
em_capitol_case(EditLine * el,wint_t c)313f54e4f97Schristos em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
3146dc2f1dbScgd {
3150594af80Schristos wchar_t *cp, *ep;
3166dc2f1dbScgd
3176dc2f1dbScgd ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3186dc2f1dbScgd el->el_state.argument, ce__isword);
3196dc2f1dbScgd
3206dc2f1dbScgd for (cp = el->el_line.cursor; cp < ep; cp++) {
321fcf85103Schristos if (iswalpha(*cp)) {
322fcf85103Schristos if (iswlower(*cp))
323fcf85103Schristos *cp = towupper(*cp);
3246dc2f1dbScgd cp++;
3256dc2f1dbScgd break;
3266dc2f1dbScgd }
3276dc2f1dbScgd }
3286dc2f1dbScgd for (; cp < ep; cp++)
329fcf85103Schristos if (iswupper(*cp))
330fcf85103Schristos *cp = towlower(*cp);
3316dc2f1dbScgd
3326dc2f1dbScgd el->el_line.cursor = ep;
3336dc2f1dbScgd if (el->el_line.cursor > el->el_line.lastchar)
3346dc2f1dbScgd el->el_line.cursor = el->el_line.lastchar;
335b71bed95Schristos return CC_REFRESH;
3366dc2f1dbScgd }
3376dc2f1dbScgd
338d30d584aSlukem
3396dc2f1dbScgd /* em_lower_case():
3406dc2f1dbScgd * Lowercase the characters from cursor to end of current word
3416dc2f1dbScgd * [M-l]
3426dc2f1dbScgd */
343a2d6b270Schristos libedit_private el_action_t
3446dc2f1dbScgd /*ARGSUSED*/
em_lower_case(EditLine * el,wint_t c)345f54e4f97Schristos em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
3466dc2f1dbScgd {
3470594af80Schristos wchar_t *cp, *ep;
3486dc2f1dbScgd
3496dc2f1dbScgd ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3506dc2f1dbScgd el->el_state.argument, ce__isword);
3516dc2f1dbScgd
3526dc2f1dbScgd for (cp = el->el_line.cursor; cp < ep; cp++)
353fcf85103Schristos if (iswupper(*cp))
354fcf85103Schristos *cp = towlower(*cp);
3556dc2f1dbScgd
3566dc2f1dbScgd el->el_line.cursor = ep;
3576dc2f1dbScgd if (el->el_line.cursor > el->el_line.lastchar)
3586dc2f1dbScgd el->el_line.cursor = el->el_line.lastchar;
359b71bed95Schristos return CC_REFRESH;
3606dc2f1dbScgd }
3616dc2f1dbScgd
3626dc2f1dbScgd
3636dc2f1dbScgd /* em_set_mark():
3646dc2f1dbScgd * Set the mark at cursor
3656dc2f1dbScgd * [^@]
3666dc2f1dbScgd */
367a2d6b270Schristos libedit_private el_action_t
3686dc2f1dbScgd /*ARGSUSED*/
em_set_mark(EditLine * el,wint_t c)369f54e4f97Schristos em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
3706dc2f1dbScgd {
371d30d584aSlukem
3726dc2f1dbScgd el->el_chared.c_kill.mark = el->el_line.cursor;
373b71bed95Schristos return CC_NORM;
3746dc2f1dbScgd }
3756dc2f1dbScgd
3766dc2f1dbScgd
3776dc2f1dbScgd /* em_exchange_mark():
3786dc2f1dbScgd * Exchange the cursor and mark
3796dc2f1dbScgd * [^X^X]
3806dc2f1dbScgd */
381a2d6b270Schristos libedit_private el_action_t
3826dc2f1dbScgd /*ARGSUSED*/
em_exchange_mark(EditLine * el,wint_t c)383f54e4f97Schristos em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
3846dc2f1dbScgd {
3850594af80Schristos wchar_t *cp;
3866dc2f1dbScgd
3876dc2f1dbScgd cp = el->el_line.cursor;
3886dc2f1dbScgd el->el_line.cursor = el->el_chared.c_kill.mark;
3896dc2f1dbScgd el->el_chared.c_kill.mark = cp;
390b71bed95Schristos return CC_CURSOR;
3916dc2f1dbScgd }
3926dc2f1dbScgd
393d30d584aSlukem
3946dc2f1dbScgd /* em_universal_argument():
3956dc2f1dbScgd * Universal argument (argument times 4)
3966dc2f1dbScgd * [^U]
3976dc2f1dbScgd */
398a2d6b270Schristos libedit_private el_action_t
3996dc2f1dbScgd /*ARGSUSED*/
em_universal_argument(EditLine * el,wint_t c)400f54e4f97Schristos em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
4016dc2f1dbScgd { /* multiply current argument by 4 */
402d30d584aSlukem
4036dc2f1dbScgd if (el->el_state.argument > 1000000)
404b71bed95Schristos return CC_ERROR;
4056dc2f1dbScgd el->el_state.doingarg = 1;
4066dc2f1dbScgd el->el_state.argument *= 4;
407b71bed95Schristos return CC_ARGHACK;
4086dc2f1dbScgd }
4096dc2f1dbScgd
410d30d584aSlukem
4116dc2f1dbScgd /* em_meta_next():
4126dc2f1dbScgd * Add 8th bit to next character typed
4136dc2f1dbScgd * [<ESC>]
4146dc2f1dbScgd */
415a2d6b270Schristos libedit_private el_action_t
4166dc2f1dbScgd /*ARGSUSED*/
em_meta_next(EditLine * el,wint_t c)417f54e4f97Schristos em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
4186dc2f1dbScgd {
419d30d584aSlukem
4206dc2f1dbScgd el->el_state.metanext = 1;
421b71bed95Schristos return CC_ARGHACK;
4226dc2f1dbScgd }
4236dc2f1dbScgd
4246dc2f1dbScgd
4256dc2f1dbScgd /* em_toggle_overwrite():
4266dc2f1dbScgd * Switch from insert to overwrite mode or vice versa
4276dc2f1dbScgd */
428a2d6b270Schristos libedit_private el_action_t
4296dc2f1dbScgd /*ARGSUSED*/
em_toggle_overwrite(EditLine * el,wint_t c)430f54e4f97Schristos em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
4316dc2f1dbScgd {
432d30d584aSlukem
433d30d584aSlukem el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
434d30d584aSlukem MODE_REPLACE : MODE_INSERT;
435b71bed95Schristos return CC_NORM;
4366dc2f1dbScgd }
4376dc2f1dbScgd
4386dc2f1dbScgd
4396dc2f1dbScgd /* em_copy_prev_word():
4406dc2f1dbScgd * Copy current word to cursor
4416dc2f1dbScgd */
442a2d6b270Schristos libedit_private el_action_t
4436dc2f1dbScgd /*ARGSUSED*/
em_copy_prev_word(EditLine * el,wint_t c)444f54e4f97Schristos em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
4456dc2f1dbScgd {
4460594af80Schristos wchar_t *cp, *oldc, *dp;
4476dc2f1dbScgd
4486dc2f1dbScgd if (el->el_line.cursor == el->el_line.buffer)
449b71bed95Schristos return CC_ERROR;
4506dc2f1dbScgd
4516dc2f1dbScgd /* does a bounds check */
4526dc2f1dbScgd cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
4536dc2f1dbScgd el->el_state.argument, ce__isword);
4546dc2f1dbScgd
455*8ffafb93Schristos c_insert(el, (int)(el->el_line.cursor - cp));
456427b3799Schristos oldc = el->el_line.cursor;
4576dc2f1dbScgd for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
4586dc2f1dbScgd *dp++ = *cp;
4596dc2f1dbScgd
4606dc2f1dbScgd el->el_line.cursor = dp;/* put cursor at end */
4616dc2f1dbScgd
462b71bed95Schristos return CC_REFRESH;
4636dc2f1dbScgd }
4646dc2f1dbScgd
4656dc2f1dbScgd
4666dc2f1dbScgd /* em_inc_search_next():
4676dc2f1dbScgd * Emacs incremental next search
4686dc2f1dbScgd */
469a2d6b270Schristos libedit_private el_action_t
4706dc2f1dbScgd /*ARGSUSED*/
em_inc_search_next(EditLine * el,wint_t c)471f54e4f97Schristos em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
4726dc2f1dbScgd {
473d30d584aSlukem
4746dc2f1dbScgd el->el_search.patlen = 0;
475b71bed95Schristos return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
4766dc2f1dbScgd }
4776dc2f1dbScgd
4786dc2f1dbScgd
4796dc2f1dbScgd /* em_inc_search_prev():
4806dc2f1dbScgd * Emacs incremental reverse search
4816dc2f1dbScgd */
482a2d6b270Schristos libedit_private el_action_t
4836dc2f1dbScgd /*ARGSUSED*/
em_inc_search_prev(EditLine * el,wint_t c)484f54e4f97Schristos em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
4856dc2f1dbScgd {
486d30d584aSlukem
4876dc2f1dbScgd el->el_search.patlen = 0;
488b71bed95Schristos return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
4896dc2f1dbScgd }
4906360c4b0Smycroft
4916360c4b0Smycroft
4926360c4b0Smycroft /* em_delete_prev_char():
4936360c4b0Smycroft * Delete the character to the left of the cursor
4946360c4b0Smycroft * [^?]
4956360c4b0Smycroft */
496a2d6b270Schristos libedit_private el_action_t
4976360c4b0Smycroft /*ARGSUSED*/
em_delete_prev_char(EditLine * el,wint_t c)498f54e4f97Schristos em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
4996360c4b0Smycroft {
5006360c4b0Smycroft
5016360c4b0Smycroft if (el->el_line.cursor <= el->el_line.buffer)
502b71bed95Schristos return CC_ERROR;
5036360c4b0Smycroft
5046360c4b0Smycroft if (el->el_state.doingarg)
5056360c4b0Smycroft c_delbefore(el, el->el_state.argument);
5066360c4b0Smycroft else
5076360c4b0Smycroft c_delbefore1(el);
5086360c4b0Smycroft el->el_line.cursor -= el->el_state.argument;
5096360c4b0Smycroft if (el->el_line.cursor < el->el_line.buffer)
5106360c4b0Smycroft el->el_line.cursor = el->el_line.buffer;
511b71bed95Schristos return CC_REFRESH;
5126360c4b0Smycroft }
513