1*12db70c8Szrj /* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $ */
232fe07f8SJohn Marino
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino * Copyright (c) 1992, 1993
532fe07f8SJohn Marino * The Regents of the University of California. All rights reserved.
632fe07f8SJohn Marino *
732fe07f8SJohn Marino * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino *
1032fe07f8SJohn Marino * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino * are met:
1332fe07f8SJohn Marino * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino * documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino * may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino * without specific prior written permission.
2132fe07f8SJohn Marino *
2232fe07f8SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino * SUCH DAMAGE.
3332fe07f8SJohn Marino */
3432fe07f8SJohn Marino
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*12db70c8Szrj __RCSID("$NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino * emacs.c: Emacs functions
4632fe07f8SJohn Marino */
47*12db70c8Szrj #include <ctype.h>
48*12db70c8Szrj
4932fe07f8SJohn Marino #include "el.h"
50*12db70c8Szrj #include "emacs.h"
51*12db70c8Szrj #include "fcns.h"
5232fe07f8SJohn Marino
5332fe07f8SJohn Marino /* em_delete_or_list():
5432fe07f8SJohn Marino * Delete character under cursor or list completions if at end of line
5532fe07f8SJohn Marino * [^D]
5632fe07f8SJohn Marino */
57*12db70c8Szrj libedit_private el_action_t
5832fe07f8SJohn Marino /*ARGSUSED*/
em_delete_or_list(EditLine * el,wint_t c)59*12db70c8Szrj em_delete_or_list(EditLine *el, wint_t c)
6032fe07f8SJohn Marino {
6132fe07f8SJohn Marino
6232fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar) {
6332fe07f8SJohn Marino /* if I'm at the end */
6432fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer) {
6532fe07f8SJohn Marino /* and the beginning */
6632fe07f8SJohn Marino terminal_writec(el, c); /* then do an EOF */
6732fe07f8SJohn Marino return CC_EOF;
6832fe07f8SJohn Marino } else {
6932fe07f8SJohn Marino /*
7032fe07f8SJohn Marino * Here we could list completions, but it is an
7132fe07f8SJohn Marino * error right now
7232fe07f8SJohn Marino */
7332fe07f8SJohn Marino terminal_beep(el);
7432fe07f8SJohn Marino return CC_ERROR;
7532fe07f8SJohn Marino }
7632fe07f8SJohn Marino } else {
7732fe07f8SJohn Marino if (el->el_state.doingarg)
7832fe07f8SJohn Marino c_delafter(el, el->el_state.argument);
7932fe07f8SJohn Marino else
8032fe07f8SJohn Marino c_delafter1(el);
8132fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
8232fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar;
8332fe07f8SJohn Marino /* bounds check */
8432fe07f8SJohn Marino return CC_REFRESH;
8532fe07f8SJohn Marino }
8632fe07f8SJohn Marino }
8732fe07f8SJohn Marino
8832fe07f8SJohn Marino
8932fe07f8SJohn Marino /* em_delete_next_word():
9032fe07f8SJohn Marino * Cut from cursor to end of current word
9132fe07f8SJohn Marino * [M-d]
9232fe07f8SJohn Marino */
93*12db70c8Szrj libedit_private el_action_t
9432fe07f8SJohn Marino /*ARGSUSED*/
em_delete_next_word(EditLine * el,wint_t c)95*12db70c8Szrj em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
9632fe07f8SJohn Marino {
97*12db70c8Szrj wchar_t *cp, *p, *kp;
9832fe07f8SJohn Marino
9932fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar)
10032fe07f8SJohn Marino return CC_ERROR;
10132fe07f8SJohn Marino
10232fe07f8SJohn Marino cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
10332fe07f8SJohn Marino el->el_state.argument, ce__isword);
10432fe07f8SJohn Marino
10532fe07f8SJohn Marino for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
10632fe07f8SJohn Marino /* save the text */
10732fe07f8SJohn Marino *kp++ = *p;
10832fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
10932fe07f8SJohn Marino
11032fe07f8SJohn Marino c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
11132fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
11232fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar;
11332fe07f8SJohn Marino /* bounds check */
11432fe07f8SJohn Marino return CC_REFRESH;
11532fe07f8SJohn Marino }
11632fe07f8SJohn Marino
11732fe07f8SJohn Marino
11832fe07f8SJohn Marino /* em_yank():
11932fe07f8SJohn Marino * Paste cut buffer at cursor position
12032fe07f8SJohn Marino * [^Y]
12132fe07f8SJohn Marino */
122*12db70c8Szrj libedit_private el_action_t
12332fe07f8SJohn Marino /*ARGSUSED*/
em_yank(EditLine * el,wint_t c)124*12db70c8Szrj em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
12532fe07f8SJohn Marino {
126*12db70c8Szrj wchar_t *kp, *cp;
12732fe07f8SJohn Marino
12832fe07f8SJohn Marino if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
12932fe07f8SJohn Marino return CC_NORM;
13032fe07f8SJohn Marino
13132fe07f8SJohn Marino if (el->el_line.lastchar +
13232fe07f8SJohn Marino (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
13332fe07f8SJohn Marino el->el_line.limit)
13432fe07f8SJohn Marino return CC_ERROR;
13532fe07f8SJohn Marino
13632fe07f8SJohn Marino el->el_chared.c_kill.mark = el->el_line.cursor;
13732fe07f8SJohn Marino cp = el->el_line.cursor;
13832fe07f8SJohn Marino
13932fe07f8SJohn Marino /* open the space, */
14032fe07f8SJohn Marino c_insert(el,
14132fe07f8SJohn Marino (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
14232fe07f8SJohn Marino /* copy the chars */
14332fe07f8SJohn Marino for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
14432fe07f8SJohn Marino *cp++ = *kp;
14532fe07f8SJohn Marino
14632fe07f8SJohn Marino /* if an arg, cursor at beginning else cursor at end */
14732fe07f8SJohn Marino if (el->el_state.argument == 1)
14832fe07f8SJohn Marino el->el_line.cursor = cp;
14932fe07f8SJohn Marino
15032fe07f8SJohn Marino return CC_REFRESH;
15132fe07f8SJohn Marino }
15232fe07f8SJohn Marino
15332fe07f8SJohn Marino
15432fe07f8SJohn Marino /* em_kill_line():
15532fe07f8SJohn Marino * Cut the entire line and save in cut buffer
15632fe07f8SJohn Marino * [^U]
15732fe07f8SJohn Marino */
158*12db70c8Szrj libedit_private el_action_t
15932fe07f8SJohn Marino /*ARGSUSED*/
em_kill_line(EditLine * el,wint_t c)160*12db70c8Szrj em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
16132fe07f8SJohn Marino {
162*12db70c8Szrj wchar_t *kp, *cp;
16332fe07f8SJohn Marino
16432fe07f8SJohn Marino cp = el->el_line.buffer;
16532fe07f8SJohn Marino kp = el->el_chared.c_kill.buf;
16632fe07f8SJohn Marino while (cp < el->el_line.lastchar)
16732fe07f8SJohn Marino *kp++ = *cp++; /* copy it */
16832fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
16932fe07f8SJohn Marino /* zap! -- delete all of it */
17032fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer;
17132fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
17232fe07f8SJohn Marino return CC_REFRESH;
17332fe07f8SJohn Marino }
17432fe07f8SJohn Marino
17532fe07f8SJohn Marino
17632fe07f8SJohn Marino /* em_kill_region():
17732fe07f8SJohn Marino * Cut area between mark and cursor and save in cut buffer
17832fe07f8SJohn Marino * [^W]
17932fe07f8SJohn Marino */
180*12db70c8Szrj libedit_private el_action_t
18132fe07f8SJohn Marino /*ARGSUSED*/
em_kill_region(EditLine * el,wint_t c)182*12db70c8Szrj em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
18332fe07f8SJohn Marino {
184*12db70c8Szrj wchar_t *kp, *cp;
18532fe07f8SJohn Marino
18632fe07f8SJohn Marino if (!el->el_chared.c_kill.mark)
18732fe07f8SJohn Marino return CC_ERROR;
18832fe07f8SJohn Marino
18932fe07f8SJohn Marino if (el->el_chared.c_kill.mark > el->el_line.cursor) {
19032fe07f8SJohn Marino cp = el->el_line.cursor;
19132fe07f8SJohn Marino kp = el->el_chared.c_kill.buf;
19232fe07f8SJohn Marino while (cp < el->el_chared.c_kill.mark)
19332fe07f8SJohn Marino *kp++ = *cp++; /* copy it */
19432fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
19532fe07f8SJohn Marino c_delafter(el, (int)(cp - el->el_line.cursor));
19632fe07f8SJohn Marino } else { /* mark is before cursor */
19732fe07f8SJohn Marino cp = el->el_chared.c_kill.mark;
19832fe07f8SJohn Marino kp = el->el_chared.c_kill.buf;
19932fe07f8SJohn Marino while (cp < el->el_line.cursor)
20032fe07f8SJohn Marino *kp++ = *cp++; /* copy it */
20132fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
20232fe07f8SJohn Marino c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
20332fe07f8SJohn Marino el->el_line.cursor = el->el_chared.c_kill.mark;
20432fe07f8SJohn Marino }
20532fe07f8SJohn Marino return CC_REFRESH;
20632fe07f8SJohn Marino }
20732fe07f8SJohn Marino
20832fe07f8SJohn Marino
20932fe07f8SJohn Marino /* em_copy_region():
21032fe07f8SJohn Marino * Copy area between mark and cursor to cut buffer
21132fe07f8SJohn Marino * [M-W]
21232fe07f8SJohn Marino */
213*12db70c8Szrj libedit_private el_action_t
21432fe07f8SJohn Marino /*ARGSUSED*/
em_copy_region(EditLine * el,wint_t c)215*12db70c8Szrj em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
21632fe07f8SJohn Marino {
217*12db70c8Szrj wchar_t *kp, *cp;
21832fe07f8SJohn Marino
21932fe07f8SJohn Marino if (!el->el_chared.c_kill.mark)
22032fe07f8SJohn Marino return CC_ERROR;
22132fe07f8SJohn Marino
22232fe07f8SJohn Marino if (el->el_chared.c_kill.mark > el->el_line.cursor) {
22332fe07f8SJohn Marino cp = el->el_line.cursor;
22432fe07f8SJohn Marino kp = el->el_chared.c_kill.buf;
22532fe07f8SJohn Marino while (cp < el->el_chared.c_kill.mark)
22632fe07f8SJohn Marino *kp++ = *cp++; /* copy it */
22732fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
22832fe07f8SJohn Marino } else {
22932fe07f8SJohn Marino cp = el->el_chared.c_kill.mark;
23032fe07f8SJohn Marino kp = el->el_chared.c_kill.buf;
23132fe07f8SJohn Marino while (cp < el->el_line.cursor)
23232fe07f8SJohn Marino *kp++ = *cp++; /* copy it */
23332fe07f8SJohn Marino el->el_chared.c_kill.last = kp;
23432fe07f8SJohn Marino }
23532fe07f8SJohn Marino return CC_NORM;
23632fe07f8SJohn Marino }
23732fe07f8SJohn Marino
23832fe07f8SJohn Marino
23932fe07f8SJohn Marino /* em_gosmacs_transpose():
24032fe07f8SJohn Marino * Exchange the two characters before the cursor
24132fe07f8SJohn Marino * Gosling emacs transpose chars [^T]
24232fe07f8SJohn Marino */
243*12db70c8Szrj libedit_private el_action_t
em_gosmacs_transpose(EditLine * el,wint_t c)244*12db70c8Szrj em_gosmacs_transpose(EditLine *el, wint_t c)
24532fe07f8SJohn Marino {
24632fe07f8SJohn Marino
24732fe07f8SJohn Marino if (el->el_line.cursor > &el->el_line.buffer[1]) {
24832fe07f8SJohn Marino /* must have at least two chars entered */
24932fe07f8SJohn Marino c = el->el_line.cursor[-2];
25032fe07f8SJohn Marino el->el_line.cursor[-2] = el->el_line.cursor[-1];
25132fe07f8SJohn Marino el->el_line.cursor[-1] = c;
25232fe07f8SJohn Marino return CC_REFRESH;
25332fe07f8SJohn Marino } else
25432fe07f8SJohn Marino return CC_ERROR;
25532fe07f8SJohn Marino }
25632fe07f8SJohn Marino
25732fe07f8SJohn Marino
25832fe07f8SJohn Marino /* em_next_word():
25932fe07f8SJohn Marino * Move next to end of current word
26032fe07f8SJohn Marino * [M-f]
26132fe07f8SJohn Marino */
262*12db70c8Szrj libedit_private el_action_t
26332fe07f8SJohn Marino /*ARGSUSED*/
em_next_word(EditLine * el,wint_t c)264*12db70c8Szrj em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
26532fe07f8SJohn Marino {
26632fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar)
26732fe07f8SJohn Marino return CC_ERROR;
26832fe07f8SJohn Marino
26932fe07f8SJohn Marino el->el_line.cursor = c__next_word(el->el_line.cursor,
27032fe07f8SJohn Marino el->el_line.lastchar,
27132fe07f8SJohn Marino el->el_state.argument,
27232fe07f8SJohn Marino ce__isword);
27332fe07f8SJohn Marino
27432fe07f8SJohn Marino if (el->el_map.type == MAP_VI)
27532fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) {
27632fe07f8SJohn Marino cv_delfini(el);
27732fe07f8SJohn Marino return CC_REFRESH;
27832fe07f8SJohn Marino }
27932fe07f8SJohn Marino return CC_CURSOR;
28032fe07f8SJohn Marino }
28132fe07f8SJohn Marino
28232fe07f8SJohn Marino
28332fe07f8SJohn Marino /* em_upper_case():
28432fe07f8SJohn Marino * Uppercase the characters from cursor to end of current word
28532fe07f8SJohn Marino * [M-u]
28632fe07f8SJohn Marino */
287*12db70c8Szrj libedit_private el_action_t
28832fe07f8SJohn Marino /*ARGSUSED*/
em_upper_case(EditLine * el,wint_t c)289*12db70c8Szrj em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
29032fe07f8SJohn Marino {
291*12db70c8Szrj wchar_t *cp, *ep;
29232fe07f8SJohn Marino
29332fe07f8SJohn Marino ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
29432fe07f8SJohn Marino el->el_state.argument, ce__isword);
29532fe07f8SJohn Marino
29632fe07f8SJohn Marino for (cp = el->el_line.cursor; cp < ep; cp++)
297*12db70c8Szrj if (iswlower(*cp))
298*12db70c8Szrj *cp = towupper(*cp);
29932fe07f8SJohn Marino
30032fe07f8SJohn Marino el->el_line.cursor = ep;
30132fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
30232fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar;
30332fe07f8SJohn Marino return CC_REFRESH;
30432fe07f8SJohn Marino }
30532fe07f8SJohn Marino
30632fe07f8SJohn Marino
30732fe07f8SJohn Marino /* em_capitol_case():
30832fe07f8SJohn Marino * Capitalize the characters from cursor to end of current word
30932fe07f8SJohn Marino * [M-c]
31032fe07f8SJohn Marino */
311*12db70c8Szrj libedit_private el_action_t
31232fe07f8SJohn Marino /*ARGSUSED*/
em_capitol_case(EditLine * el,wint_t c)313*12db70c8Szrj em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
31432fe07f8SJohn Marino {
315*12db70c8Szrj wchar_t *cp, *ep;
31632fe07f8SJohn Marino
31732fe07f8SJohn Marino ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
31832fe07f8SJohn Marino el->el_state.argument, ce__isword);
31932fe07f8SJohn Marino
32032fe07f8SJohn Marino for (cp = el->el_line.cursor; cp < ep; cp++) {
321*12db70c8Szrj if (iswalpha(*cp)) {
322*12db70c8Szrj if (iswlower(*cp))
323*12db70c8Szrj *cp = towupper(*cp);
32432fe07f8SJohn Marino cp++;
32532fe07f8SJohn Marino break;
32632fe07f8SJohn Marino }
32732fe07f8SJohn Marino }
32832fe07f8SJohn Marino for (; cp < ep; cp++)
329*12db70c8Szrj if (iswupper(*cp))
330*12db70c8Szrj *cp = towlower(*cp);
33132fe07f8SJohn Marino
33232fe07f8SJohn Marino el->el_line.cursor = ep;
33332fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
33432fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar;
33532fe07f8SJohn Marino return CC_REFRESH;
33632fe07f8SJohn Marino }
33732fe07f8SJohn Marino
33832fe07f8SJohn Marino
33932fe07f8SJohn Marino /* em_lower_case():
34032fe07f8SJohn Marino * Lowercase the characters from cursor to end of current word
34132fe07f8SJohn Marino * [M-l]
34232fe07f8SJohn Marino */
343*12db70c8Szrj libedit_private el_action_t
34432fe07f8SJohn Marino /*ARGSUSED*/
em_lower_case(EditLine * el,wint_t c)345*12db70c8Szrj em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
34632fe07f8SJohn Marino {
347*12db70c8Szrj wchar_t *cp, *ep;
34832fe07f8SJohn Marino
34932fe07f8SJohn Marino ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
35032fe07f8SJohn Marino el->el_state.argument, ce__isword);
35132fe07f8SJohn Marino
35232fe07f8SJohn Marino for (cp = el->el_line.cursor; cp < ep; cp++)
353*12db70c8Szrj if (iswupper(*cp))
354*12db70c8Szrj *cp = towlower(*cp);
35532fe07f8SJohn Marino
35632fe07f8SJohn Marino el->el_line.cursor = ep;
35732fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar)
35832fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar;
35932fe07f8SJohn Marino return CC_REFRESH;
36032fe07f8SJohn Marino }
36132fe07f8SJohn Marino
36232fe07f8SJohn Marino
36332fe07f8SJohn Marino /* em_set_mark():
36432fe07f8SJohn Marino * Set the mark at cursor
36532fe07f8SJohn Marino * [^@]
36632fe07f8SJohn Marino */
367*12db70c8Szrj libedit_private el_action_t
36832fe07f8SJohn Marino /*ARGSUSED*/
em_set_mark(EditLine * el,wint_t c)369*12db70c8Szrj em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
37032fe07f8SJohn Marino {
37132fe07f8SJohn Marino
37232fe07f8SJohn Marino el->el_chared.c_kill.mark = el->el_line.cursor;
37332fe07f8SJohn Marino return CC_NORM;
37432fe07f8SJohn Marino }
37532fe07f8SJohn Marino
37632fe07f8SJohn Marino
37732fe07f8SJohn Marino /* em_exchange_mark():
37832fe07f8SJohn Marino * Exchange the cursor and mark
37932fe07f8SJohn Marino * [^X^X]
38032fe07f8SJohn Marino */
381*12db70c8Szrj libedit_private el_action_t
38232fe07f8SJohn Marino /*ARGSUSED*/
em_exchange_mark(EditLine * el,wint_t c)383*12db70c8Szrj em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
38432fe07f8SJohn Marino {
385*12db70c8Szrj wchar_t *cp;
38632fe07f8SJohn Marino
38732fe07f8SJohn Marino cp = el->el_line.cursor;
38832fe07f8SJohn Marino el->el_line.cursor = el->el_chared.c_kill.mark;
38932fe07f8SJohn Marino el->el_chared.c_kill.mark = cp;
39032fe07f8SJohn Marino return CC_CURSOR;
39132fe07f8SJohn Marino }
39232fe07f8SJohn Marino
39332fe07f8SJohn Marino
39432fe07f8SJohn Marino /* em_universal_argument():
39532fe07f8SJohn Marino * Universal argument (argument times 4)
39632fe07f8SJohn Marino * [^U]
39732fe07f8SJohn Marino */
398*12db70c8Szrj libedit_private el_action_t
39932fe07f8SJohn Marino /*ARGSUSED*/
em_universal_argument(EditLine * el,wint_t c)400*12db70c8Szrj em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
40132fe07f8SJohn Marino { /* multiply current argument by 4 */
40232fe07f8SJohn Marino
40332fe07f8SJohn Marino if (el->el_state.argument > 1000000)
40432fe07f8SJohn Marino return CC_ERROR;
40532fe07f8SJohn Marino el->el_state.doingarg = 1;
40632fe07f8SJohn Marino el->el_state.argument *= 4;
40732fe07f8SJohn Marino return CC_ARGHACK;
40832fe07f8SJohn Marino }
40932fe07f8SJohn Marino
41032fe07f8SJohn Marino
41132fe07f8SJohn Marino /* em_meta_next():
41232fe07f8SJohn Marino * Add 8th bit to next character typed
41332fe07f8SJohn Marino * [<ESC>]
41432fe07f8SJohn Marino */
415*12db70c8Szrj libedit_private el_action_t
41632fe07f8SJohn Marino /*ARGSUSED*/
em_meta_next(EditLine * el,wint_t c)417*12db70c8Szrj em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
41832fe07f8SJohn Marino {
41932fe07f8SJohn Marino
42032fe07f8SJohn Marino el->el_state.metanext = 1;
42132fe07f8SJohn Marino return CC_ARGHACK;
42232fe07f8SJohn Marino }
42332fe07f8SJohn Marino
42432fe07f8SJohn Marino
42532fe07f8SJohn Marino /* em_toggle_overwrite():
42632fe07f8SJohn Marino * Switch from insert to overwrite mode or vice versa
42732fe07f8SJohn Marino */
428*12db70c8Szrj libedit_private el_action_t
42932fe07f8SJohn Marino /*ARGSUSED*/
em_toggle_overwrite(EditLine * el,wint_t c)430*12db70c8Szrj em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
43132fe07f8SJohn Marino {
43232fe07f8SJohn Marino
43332fe07f8SJohn Marino el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
43432fe07f8SJohn Marino MODE_REPLACE : MODE_INSERT;
43532fe07f8SJohn Marino return CC_NORM;
43632fe07f8SJohn Marino }
43732fe07f8SJohn Marino
43832fe07f8SJohn Marino
43932fe07f8SJohn Marino /* em_copy_prev_word():
44032fe07f8SJohn Marino * Copy current word to cursor
44132fe07f8SJohn Marino */
442*12db70c8Szrj libedit_private el_action_t
44332fe07f8SJohn Marino /*ARGSUSED*/
em_copy_prev_word(EditLine * el,wint_t c)444*12db70c8Szrj em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
44532fe07f8SJohn Marino {
446*12db70c8Szrj wchar_t *cp, *oldc, *dp;
44732fe07f8SJohn Marino
44832fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer)
44932fe07f8SJohn Marino return CC_ERROR;
45032fe07f8SJohn Marino
45132fe07f8SJohn Marino oldc = el->el_line.cursor;
45232fe07f8SJohn Marino /* does a bounds check */
45332fe07f8SJohn Marino cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
45432fe07f8SJohn Marino el->el_state.argument, ce__isword);
45532fe07f8SJohn Marino
45632fe07f8SJohn Marino c_insert(el, (int)(oldc - cp));
45732fe07f8SJohn Marino for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
45832fe07f8SJohn Marino *dp++ = *cp;
45932fe07f8SJohn Marino
46032fe07f8SJohn Marino el->el_line.cursor = dp;/* put cursor at end */
46132fe07f8SJohn Marino
46232fe07f8SJohn Marino return CC_REFRESH;
46332fe07f8SJohn Marino }
46432fe07f8SJohn Marino
46532fe07f8SJohn Marino
46632fe07f8SJohn Marino /* em_inc_search_next():
46732fe07f8SJohn Marino * Emacs incremental next search
46832fe07f8SJohn Marino */
469*12db70c8Szrj libedit_private el_action_t
47032fe07f8SJohn Marino /*ARGSUSED*/
em_inc_search_next(EditLine * el,wint_t c)471*12db70c8Szrj em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
47232fe07f8SJohn Marino {
47332fe07f8SJohn Marino
47432fe07f8SJohn Marino el->el_search.patlen = 0;
47532fe07f8SJohn Marino return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
47632fe07f8SJohn Marino }
47732fe07f8SJohn Marino
47832fe07f8SJohn Marino
47932fe07f8SJohn Marino /* em_inc_search_prev():
48032fe07f8SJohn Marino * Emacs incremental reverse search
48132fe07f8SJohn Marino */
482*12db70c8Szrj libedit_private el_action_t
48332fe07f8SJohn Marino /*ARGSUSED*/
em_inc_search_prev(EditLine * el,wint_t c)484*12db70c8Szrj em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
48532fe07f8SJohn Marino {
48632fe07f8SJohn Marino
48732fe07f8SJohn Marino el->el_search.patlen = 0;
48832fe07f8SJohn Marino return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
48932fe07f8SJohn Marino }
49032fe07f8SJohn Marino
49132fe07f8SJohn Marino
49232fe07f8SJohn Marino /* em_delete_prev_char():
49332fe07f8SJohn Marino * Delete the character to the left of the cursor
49432fe07f8SJohn Marino * [^?]
49532fe07f8SJohn Marino */
496*12db70c8Szrj libedit_private el_action_t
49732fe07f8SJohn Marino /*ARGSUSED*/
em_delete_prev_char(EditLine * el,wint_t c)498*12db70c8Szrj em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
49932fe07f8SJohn Marino {
50032fe07f8SJohn Marino
50132fe07f8SJohn Marino if (el->el_line.cursor <= el->el_line.buffer)
50232fe07f8SJohn Marino return CC_ERROR;
50332fe07f8SJohn Marino
50432fe07f8SJohn Marino if (el->el_state.doingarg)
50532fe07f8SJohn Marino c_delbefore(el, el->el_state.argument);
50632fe07f8SJohn Marino else
50732fe07f8SJohn Marino c_delbefore1(el);
50832fe07f8SJohn Marino el->el_line.cursor -= el->el_state.argument;
50932fe07f8SJohn Marino if (el->el_line.cursor < el->el_line.buffer)
51032fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer;
51132fe07f8SJohn Marino return CC_REFRESH;
51232fe07f8SJohn Marino }
513