154216Sbostic /*-
2*61275Sbostic * Copyright (c) 1992, 1993
3*61275Sbostic * The Regents of the University of California. All rights reserved.
454216Sbostic *
554216Sbostic * This code is derived from software contributed to Berkeley by
654216Sbostic * Christos Zoulas of Cornell University.
754216Sbostic *
854216Sbostic * %sccs.include.redist.c%
954216Sbostic */
1054216Sbostic
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61275Sbostic static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454216Sbostic
1554216Sbostic /*
1654624Schristos * emacs.c: Emacs functions
1754216Sbostic */
1854216Sbostic #include "sys.h"
1954216Sbostic #include "el.h"
2054216Sbostic
2154216Sbostic /* em_delete_or_list():
2254216Sbostic * Delete character under cursor or list completions if at end of line
2354216Sbostic * [^D]
2454216Sbostic */
2554216Sbostic protected el_action_t
2654216Sbostic /*ARGSUSED*/
em_delete_or_list(el,c)2754216Sbostic em_delete_or_list(el, c)
2854216Sbostic EditLine *el;
2954216Sbostic int c;
3054216Sbostic {
3154216Sbostic if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */
3254216Sbostic #ifdef notyet
3354216Sbostic if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */
3454216Sbostic #endif
3554216Sbostic term_overwrite(el, STReof, 4);/* then do a EOF */
3654216Sbostic term__flush();
3754216Sbostic return CC_EOF;
3854216Sbostic #ifdef notyet
3954216Sbostic }
4054216Sbostic else {
4154216Sbostic re_goto_bottom(el);
4254216Sbostic *el->el_line.lastchar = '\0'; /* just in case */
4354216Sbostic return CC_LIST_CHOICES;
4454216Sbostic }
4554216Sbostic #endif
4654216Sbostic }
4754216Sbostic else {
4854216Sbostic c_delafter(el, el->el_state.argument); /* delete after dot */
4954216Sbostic if (el->el_line.cursor > el->el_line.lastchar)
5054216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */
5154216Sbostic return CC_REFRESH;
5254216Sbostic }
5354216Sbostic }
5454216Sbostic
5554216Sbostic
5654216Sbostic /* em_delete_next_word():
5754216Sbostic * Cut from cursor to end of current word
5854216Sbostic * [M-d]
5954216Sbostic */
6054216Sbostic protected el_action_t
6154216Sbostic /*ARGSUSED*/
em_delete_next_word(el,c)6254216Sbostic em_delete_next_word(el, c)
6354216Sbostic EditLine *el;
6454216Sbostic int c;
6554216Sbostic {
6654216Sbostic char *cp, *p, *kp;
6754216Sbostic
6854216Sbostic if (el->el_line.cursor == el->el_line.lastchar)
6954216Sbostic return CC_ERROR;
7054216Sbostic
7154216Sbostic cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
7254216Sbostic el->el_state.argument, ce__isword);
7354216Sbostic
7454216Sbostic for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
7554216Sbostic /* save the text */
7654216Sbostic *kp++ = *p;
7754216Sbostic el->el_chared.c_kill.last = kp;
7854216Sbostic
7954216Sbostic c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
8054216Sbostic if (el->el_line.cursor > el->el_line.lastchar)
8154216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */
8254216Sbostic return CC_REFRESH;
8354216Sbostic }
8454216Sbostic
8554216Sbostic
8654216Sbostic /* em_yank():
8754216Sbostic * Paste cut buffer at cursor position
8854216Sbostic * [^Y]
8954216Sbostic */
9054216Sbostic protected el_action_t
9154216Sbostic /*ARGSUSED*/
em_yank(el,c)9254216Sbostic em_yank(el, c)
9354216Sbostic EditLine *el;
9454216Sbostic int c;
9554216Sbostic {
9654216Sbostic char *kp, *cp;
9754216Sbostic
9854216Sbostic if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
9954216Sbostic return CC_ERROR;
10054216Sbostic
10154216Sbostic if (el->el_line.lastchar +
10254216Sbostic (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
10354216Sbostic el->el_line.limit)
10454216Sbostic return CC_ERROR;
10554216Sbostic
10654216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor;
10754216Sbostic cp = el->el_line.cursor;
10854216Sbostic
10954216Sbostic /* open the space, */
11054216Sbostic c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
11154216Sbostic /* copy the chars */
11254216Sbostic for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
11354216Sbostic *cp++ = *kp;
11454216Sbostic
11554216Sbostic /* if an arg, cursor at beginning else cursor at end */
11654216Sbostic if (el->el_state.argument == 1)
11754216Sbostic el->el_line.cursor = cp;
11854216Sbostic
11954216Sbostic return CC_REFRESH;
12054216Sbostic }
12154216Sbostic
12254216Sbostic
12354216Sbostic /* em_kill_line():
12454216Sbostic * Cut the entire line and save in cut buffer
12554216Sbostic * [^U]
12654216Sbostic */
12754216Sbostic protected el_action_t
12854216Sbostic /*ARGSUSED*/
em_kill_line(el,c)12954216Sbostic em_kill_line(el, c)
13054216Sbostic EditLine *el;
13154216Sbostic int c;
13254216Sbostic {
13354216Sbostic char *kp, *cp;
13454216Sbostic
13554216Sbostic cp = el->el_line.buffer;
13654216Sbostic kp = el->el_chared.c_kill.buf;
13754216Sbostic while (cp < el->el_line.lastchar)
13854216Sbostic *kp++ = *cp++; /* copy it */
13954216Sbostic el->el_chared.c_kill.last = kp;
14054216Sbostic el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */
14154216Sbostic el->el_line.cursor = el->el_line.buffer;
14254216Sbostic return CC_REFRESH;
14354216Sbostic }
14454216Sbostic
14554216Sbostic
14654216Sbostic /* em_kill_region():
14754216Sbostic * Cut area between mark and cursor and save in cut buffer
14854216Sbostic * [^W]
14954216Sbostic */
15054216Sbostic protected el_action_t
15154216Sbostic /*ARGSUSED*/
em_kill_region(el,c)15254216Sbostic em_kill_region(el, c)
15354216Sbostic EditLine *el;
15454216Sbostic int c;
15554216Sbostic {
15654216Sbostic char *kp, *cp;
15754216Sbostic
15854216Sbostic if (!el->el_chared.c_kill.mark)
15954216Sbostic return CC_ERROR;
16054216Sbostic
16154216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) {
16254216Sbostic cp = el->el_line.cursor;
16354216Sbostic kp = el->el_chared.c_kill.buf;
16454216Sbostic while (cp < el->el_chared.c_kill.mark)
16554216Sbostic *kp++ = *cp++; /* copy it */
16654216Sbostic el->el_chared.c_kill.last = kp;
16754216Sbostic c_delafter(el, cp - el->el_line.cursor);
16854216Sbostic }
16954216Sbostic else { /* mark is before cursor */
17054216Sbostic cp = el->el_chared.c_kill.mark;
17154216Sbostic kp = el->el_chared.c_kill.buf;
17254216Sbostic while (cp < el->el_line.cursor)
17354216Sbostic *kp++ = *cp++; /* copy it */
17454216Sbostic el->el_chared.c_kill.last = kp;
17554216Sbostic c_delbefore(el, cp - el->el_chared.c_kill.mark);
17654216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark;
17754216Sbostic }
17854216Sbostic return CC_REFRESH;
17954216Sbostic }
18054216Sbostic
18154216Sbostic
18254216Sbostic /* em_copy_region():
18354216Sbostic * Copy area between mark and cursor to cut buffer
18454216Sbostic * [M-W]
18554216Sbostic */
18654216Sbostic protected el_action_t
18754216Sbostic /*ARGSUSED*/
em_copy_region(el,c)18854216Sbostic em_copy_region(el, c)
18954216Sbostic EditLine *el;
19054216Sbostic int c;
19154216Sbostic {
19254216Sbostic char *kp, *cp;
19354216Sbostic
19454216Sbostic if (el->el_chared.c_kill.mark)
19554216Sbostic return CC_ERROR;
19654216Sbostic
19754216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) {
19854216Sbostic cp = el->el_line.cursor;
19954216Sbostic kp = el->el_chared.c_kill.buf;
20054216Sbostic while (cp < el->el_chared.c_kill.mark)
20154216Sbostic *kp++ = *cp++; /* copy it */
20254216Sbostic el->el_chared.c_kill.last = kp;
20354216Sbostic }
20454216Sbostic else {
20554216Sbostic cp = el->el_chared.c_kill.mark;
20654216Sbostic kp = el->el_chared.c_kill.buf;
20754216Sbostic while (cp < el->el_line.cursor)
20854216Sbostic *kp++ = *cp++; /* copy it */
20954216Sbostic el->el_chared.c_kill.last = kp;
21054216Sbostic }
21154216Sbostic return CC_NORM;
21254216Sbostic }
21354216Sbostic
21454216Sbostic
21554216Sbostic /* em_gosmacs_traspose():
21654216Sbostic * Exchange the two characters before the cursor
21754216Sbostic * Gosling emacs transpose chars [^T]
21854216Sbostic */
21954216Sbostic protected el_action_t
em_gosmacs_traspose(el,c)22054216Sbostic em_gosmacs_traspose(el, c)
22154216Sbostic EditLine *el;
22254216Sbostic int c;
22354216Sbostic {
22454216Sbostic
22554216Sbostic if (el->el_line.cursor > &el->el_line.buffer[1]) {
22654216Sbostic /* must have at least two chars entered */
22754216Sbostic c = el->el_line.cursor[-2];
22854216Sbostic el->el_line.cursor[-2] = el->el_line.cursor[-1];
22954216Sbostic el->el_line.cursor[-1] = c;
23054216Sbostic return CC_REFRESH;
23154216Sbostic }
23254216Sbostic else
23354216Sbostic return CC_ERROR;
23454216Sbostic }
23554216Sbostic
23654216Sbostic
23754216Sbostic /* em_next_word():
23854216Sbostic * Move next to end of current word
23954216Sbostic * [M-f]
24054216Sbostic */
24154216Sbostic protected el_action_t
24254216Sbostic /*ARGSUSED*/
em_next_word(el,c)24354216Sbostic em_next_word(el, c)
24454216Sbostic EditLine *el;
24554216Sbostic int c;
24654216Sbostic {
24754216Sbostic if (el->el_line.cursor == el->el_line.lastchar)
24854216Sbostic return CC_ERROR;
24954216Sbostic
25054216Sbostic el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar,
25154216Sbostic el->el_state.argument,
25254216Sbostic ce__isword);
25354216Sbostic
25454216Sbostic if (el->el_map.type == MAP_VI)
25554216Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
25654216Sbostic cv_delfini(el);
25754216Sbostic return CC_REFRESH;
25854216Sbostic }
25954216Sbostic
26054216Sbostic return CC_CURSOR;
26154216Sbostic }
26254216Sbostic
26354216Sbostic /* em_upper_case():
26454216Sbostic * Uppercase the characters from cursor to end of current word
26554216Sbostic * [M-u]
26654216Sbostic */
26754216Sbostic protected el_action_t
26854216Sbostic /*ARGSUSED*/
em_upper_case(el,c)26954216Sbostic em_upper_case(el, c)
27054216Sbostic EditLine *el;
27154216Sbostic int c;
27254216Sbostic {
27354216Sbostic char *cp, *ep;
27454216Sbostic
27554216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
27654216Sbostic el->el_state.argument, ce__isword);
27754216Sbostic
27854216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++)
27954216Sbostic if (islower(*cp))
28054216Sbostic *cp = toupper(*cp);
28154216Sbostic
28254216Sbostic el->el_line.cursor = ep;
28354216Sbostic if (el->el_line.cursor > el->el_line.lastchar)
28454216Sbostic el->el_line.cursor = el->el_line.lastchar;
28554216Sbostic return CC_REFRESH;
28654216Sbostic }
28754216Sbostic
28854216Sbostic
28954216Sbostic /* em_capitol_case():
29054216Sbostic * Capitalize the characters from cursor to end of current word
29154216Sbostic * [M-c]
29254216Sbostic */
29354216Sbostic protected el_action_t
29454216Sbostic /*ARGSUSED*/
em_capitol_case(el,c)29554216Sbostic em_capitol_case(el, c)
29654216Sbostic EditLine *el;
29754216Sbostic int c;
29854216Sbostic {
29954216Sbostic char *cp, *ep;
30054216Sbostic
30154216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
30254216Sbostic el->el_state.argument, ce__isword);
30354216Sbostic
30454216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) {
30554216Sbostic if (isalpha(*cp)) {
30654216Sbostic if (islower(*cp))
30754216Sbostic *cp = toupper(*cp);
30854216Sbostic cp++;
30954216Sbostic break;
31054216Sbostic }
31154216Sbostic }
31254216Sbostic for (; cp < ep; cp++)
31354216Sbostic if (isupper(*cp))
31454216Sbostic *cp = tolower(*cp);
31554216Sbostic
31654216Sbostic el->el_line.cursor = ep;
31754216Sbostic if (el->el_line.cursor > el->el_line.lastchar)
31854216Sbostic el->el_line.cursor = el->el_line.lastchar;
31954216Sbostic return CC_REFRESH;
32054216Sbostic }
32154216Sbostic
32254216Sbostic /* em_lower_case():
32354216Sbostic * Lowercase the characters from cursor to end of current word
32454216Sbostic * [M-l]
32554216Sbostic */
32654216Sbostic protected el_action_t
32754216Sbostic /*ARGSUSED*/
em_lower_case(el,c)32854216Sbostic em_lower_case(el, c)
32954216Sbostic EditLine *el;
33054216Sbostic int c;
33154216Sbostic {
33254216Sbostic char *cp, *ep;
33354216Sbostic
33454216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
33554216Sbostic el->el_state.argument, ce__isword);
33654216Sbostic
33754216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++)
33854216Sbostic if (isupper(*cp))
33954216Sbostic *cp = tolower(*cp);
34054216Sbostic
34154216Sbostic el->el_line.cursor = ep;
34254216Sbostic if (el->el_line.cursor > el->el_line.lastchar)
34354216Sbostic el->el_line.cursor = el->el_line.lastchar;
34454216Sbostic return CC_REFRESH;
34554216Sbostic }
34654216Sbostic
34754216Sbostic
34854216Sbostic /* em_set_mark():
34954216Sbostic * Set the mark at cursor
35054216Sbostic * [^@]
35154216Sbostic */
35254216Sbostic protected el_action_t
35354216Sbostic /*ARGSUSED*/
em_set_mark(el,c)35454216Sbostic em_set_mark(el, c)
35554216Sbostic EditLine *el;
35654216Sbostic int c;
35754216Sbostic {
35854216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor;
35954216Sbostic return CC_NORM;
36054216Sbostic }
36154216Sbostic
36254216Sbostic
36354216Sbostic /* em_exchange_mark():
36454216Sbostic * Exchange the cursor and mark
36554216Sbostic * [^X^X]
36654216Sbostic */
36754216Sbostic protected el_action_t
36854216Sbostic /*ARGSUSED*/
em_exchange_mark(el,c)36954216Sbostic em_exchange_mark(el, c)
37054216Sbostic EditLine *el;
37154216Sbostic int c;
37254216Sbostic {
37354216Sbostic register char *cp;
37454216Sbostic
37554216Sbostic cp = el->el_line.cursor;
37654216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark;
37754216Sbostic el->el_chared.c_kill.mark = cp;
37854216Sbostic return CC_CURSOR;
37954216Sbostic }
38054216Sbostic
38154216Sbostic /* em_universal_argument():
38254216Sbostic * Universal argument (argument times 4)
38354216Sbostic * [^U]
38454216Sbostic */
38554216Sbostic protected el_action_t
38654216Sbostic /*ARGSUSED*/
em_universal_argument(el,c)38754216Sbostic em_universal_argument(el, c)
38854216Sbostic EditLine *el;
38954216Sbostic int c;
39054216Sbostic { /* multiply current argument by 4 */
39154216Sbostic if (el->el_state.argument > 1000000)
39254216Sbostic return CC_ERROR;
39354216Sbostic el->el_state.doingarg = 1;
39454216Sbostic el->el_state.argument *= 4;
39554216Sbostic return CC_ARGHACK;
39654216Sbostic }
39754216Sbostic
39854216Sbostic /* em_meta_next():
39954216Sbostic * Add 8th bit to next character typed
40054216Sbostic * [<ESC>]
40154216Sbostic */
40254216Sbostic protected el_action_t
40354216Sbostic /*ARGSUSED*/
em_meta_next(el,c)40454216Sbostic em_meta_next(el, c)
40554216Sbostic EditLine *el;
40654216Sbostic int c;
40754216Sbostic {
40854216Sbostic el->el_state.metanext = 1;
40954216Sbostic return CC_ARGHACK;
41054216Sbostic }
41154216Sbostic
41254216Sbostic
41354216Sbostic /* em_toggle_overwrite():
41454216Sbostic * Switch from insert to overwrite mode or vice versa
41554216Sbostic */
41654216Sbostic protected el_action_t
41754216Sbostic /*ARGSUSED*/
em_toggle_overwrite(el,c)41854216Sbostic em_toggle_overwrite(el, c)
41954216Sbostic EditLine *el;
42054216Sbostic int c;
42154216Sbostic {
42254216Sbostic el->el_state.inputmode =
42354216Sbostic (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
42454216Sbostic return CC_NORM;
42554216Sbostic }
42654216Sbostic
42754216Sbostic
42854216Sbostic /* em_copy_prev_word():
42954216Sbostic * Copy current word to cursor
43054216Sbostic */
43154216Sbostic protected el_action_t
43254216Sbostic /*ARGSUSED*/
em_copy_prev_word(el,c)43354216Sbostic em_copy_prev_word(el, c)
43454216Sbostic EditLine *el;
43554216Sbostic int c;
43654216Sbostic {
43754216Sbostic char *cp, *oldc, *dp;
43854216Sbostic
43954216Sbostic if (el->el_line.cursor == el->el_line.buffer)
44054216Sbostic return CC_ERROR;
44154216Sbostic
44254216Sbostic oldc = el->el_line.cursor;
44354216Sbostic /* does a bounds check */
44454216Sbostic cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
44554216Sbostic el->el_state.argument, ce__isword);
44654216Sbostic
44754216Sbostic c_insert(el, oldc - cp);
44854216Sbostic for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
44954216Sbostic *dp++ = *cp;
45054216Sbostic
45154216Sbostic el->el_line.cursor = dp; /* put cursor at end */
45254216Sbostic
45354216Sbostic return CC_REFRESH;
45454216Sbostic }
45554216Sbostic
45654216Sbostic
45754216Sbostic /* em_inc_search_next():
45854216Sbostic * Emacs incremental next search
45954216Sbostic */
46054216Sbostic protected el_action_t
46154216Sbostic /*ARGSUSED*/
em_inc_search_next(el,c)46254216Sbostic em_inc_search_next(el, c)
46354216Sbostic EditLine *el;
46454216Sbostic int c;
46554216Sbostic {
46654216Sbostic el->el_search.patlen = 0;
46754216Sbostic return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
46854216Sbostic }
46954216Sbostic
47054216Sbostic
47154216Sbostic /* em_inc_search_prev():
47254216Sbostic * Emacs incremental reverse search
47354216Sbostic */
47454216Sbostic protected el_action_t
47554216Sbostic /*ARGSUSED*/
em_inc_search_prev(el,c)47654216Sbostic em_inc_search_prev(el, c)
47754216Sbostic EditLine *el;
47854216Sbostic int c;
47954216Sbostic {
48054216Sbostic el->el_search.patlen = 0;
48154216Sbostic return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
48254216Sbostic }
483