1 /* $NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #if !defined(lint) && !defined(SCCSID)
38 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
40 __RCSID("$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $");
42 #endif /* not lint && not SCCSID */
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
47 * emacs.c: Emacs functions
54 /* em_delete_or_list():
55 * Delete character under cursor or list completions if at end of line
60 em_delete_or_list(EditLine *el, wint_t c)
63 if (el->el_line.cursor == el->el_line.lastchar) {
64 /* if I'm at the end */
65 if (el->el_line.cursor == el->el_line.buffer) {
66 /* and the beginning */
67 terminal_writec(el, c); /* then do an EOF */
71 * Here we could list completions, but it is an
78 if (el->el_state.doingarg)
79 c_delafter(el, el->el_state.argument);
82 if (el->el_line.cursor > el->el_line.lastchar)
83 el->el_line.cursor = el->el_line.lastchar;
90 /* em_delete_next_word():
91 * Cut from cursor to end of current word
96 em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
100 if (el->el_line.cursor == el->el_line.lastchar)
103 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
104 el->el_state.argument, ce__isword);
106 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
109 el->el_chared.c_kill.last = kp;
111 c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
112 if (el->el_line.cursor > el->el_line.lastchar)
113 el->el_line.cursor = el->el_line.lastchar;
120 * Paste cut buffer at cursor position
123 protected el_action_t
125 em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
129 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
132 if (el->el_line.lastchar +
133 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
137 el->el_chared.c_kill.mark = el->el_line.cursor;
138 cp = el->el_line.cursor;
140 /* open the space, */
142 (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
144 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
147 /* if an arg, cursor at beginning else cursor at end */
148 if (el->el_state.argument == 1)
149 el->el_line.cursor = cp;
156 * Cut the entire line and save in cut buffer
159 protected el_action_t
161 em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
165 cp = el->el_line.buffer;
166 kp = el->el_chared.c_kill.buf;
167 while (cp < el->el_line.lastchar)
168 *kp++ = *cp++; /* copy it */
169 el->el_chared.c_kill.last = kp;
170 /* zap! -- delete all of it */
171 el->el_line.lastchar = el->el_line.buffer;
172 el->el_line.cursor = el->el_line.buffer;
178 * Cut area between mark and cursor and save in cut buffer
181 protected el_action_t
183 em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
187 if (!el->el_chared.c_kill.mark)
190 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
191 cp = el->el_line.cursor;
192 kp = el->el_chared.c_kill.buf;
193 while (cp < el->el_chared.c_kill.mark)
194 *kp++ = *cp++; /* copy it */
195 el->el_chared.c_kill.last = kp;
196 c_delafter(el, (int)(cp - el->el_line.cursor));
197 } else { /* mark is before cursor */
198 cp = el->el_chared.c_kill.mark;
199 kp = el->el_chared.c_kill.buf;
200 while (cp < el->el_line.cursor)
201 *kp++ = *cp++; /* copy it */
202 el->el_chared.c_kill.last = kp;
203 c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
204 el->el_line.cursor = el->el_chared.c_kill.mark;
211 * Copy area between mark and cursor to cut buffer
214 protected el_action_t
216 em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
220 if (!el->el_chared.c_kill.mark)
223 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
224 cp = el->el_line.cursor;
225 kp = el->el_chared.c_kill.buf;
226 while (cp < el->el_chared.c_kill.mark)
227 *kp++ = *cp++; /* copy it */
228 el->el_chared.c_kill.last = kp;
230 cp = el->el_chared.c_kill.mark;
231 kp = el->el_chared.c_kill.buf;
232 while (cp < el->el_line.cursor)
233 *kp++ = *cp++; /* copy it */
234 el->el_chared.c_kill.last = kp;
240 /* em_gosmacs_transpose():
241 * Exchange the two characters before the cursor
242 * Gosling emacs transpose chars [^T]
244 protected el_action_t
245 em_gosmacs_transpose(EditLine *el, wint_t c)
248 if (el->el_line.cursor > &el->el_line.buffer[1]) {
249 /* must have at least two chars entered */
250 c = el->el_line.cursor[-2];
251 el->el_line.cursor[-2] = el->el_line.cursor[-1];
252 el->el_line.cursor[-1] = (Char)c;
260 * Move next to end of current word
263 protected el_action_t
265 em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
267 if (el->el_line.cursor == el->el_line.lastchar)
270 el->el_line.cursor = c__next_word(el->el_line.cursor,
271 el->el_line.lastchar,
272 el->el_state.argument,
275 if (el->el_map.type == MAP_VI)
276 if (el->el_chared.c_vcmd.action != NOP) {
285 * Uppercase the characters from cursor to end of current word
288 protected el_action_t
290 em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
294 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
295 el->el_state.argument, ce__isword);
297 for (cp = el->el_line.cursor; cp < ep; cp++)
301 el->el_line.cursor = ep;
302 if (el->el_line.cursor > el->el_line.lastchar)
303 el->el_line.cursor = el->el_line.lastchar;
308 /* em_capitol_case():
309 * Capitalize the characters from cursor to end of current word
312 protected el_action_t
314 em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
318 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
319 el->el_state.argument, ce__isword);
321 for (cp = el->el_line.cursor; cp < ep; cp++) {
329 for (; cp < ep; cp++)
333 el->el_line.cursor = ep;
334 if (el->el_line.cursor > el->el_line.lastchar)
335 el->el_line.cursor = el->el_line.lastchar;
341 * Lowercase the characters from cursor to end of current word
344 protected el_action_t
346 em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
350 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
351 el->el_state.argument, ce__isword);
353 for (cp = el->el_line.cursor; cp < ep; cp++)
357 el->el_line.cursor = ep;
358 if (el->el_line.cursor > el->el_line.lastchar)
359 el->el_line.cursor = el->el_line.lastchar;
365 * Set the mark at cursor
368 protected el_action_t
370 em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
373 el->el_chared.c_kill.mark = el->el_line.cursor;
378 /* em_exchange_mark():
379 * Exchange the cursor and mark
382 protected el_action_t
384 em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
388 cp = el->el_line.cursor;
389 el->el_line.cursor = el->el_chared.c_kill.mark;
390 el->el_chared.c_kill.mark = cp;
395 /* em_universal_argument():
396 * Universal argument (argument times 4)
399 protected el_action_t
401 em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
402 { /* multiply current argument by 4 */
404 if (el->el_state.argument > 1000000)
406 el->el_state.doingarg = 1;
407 el->el_state.argument *= 4;
413 * Add 8th bit to next character typed
416 protected el_action_t
418 em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
421 el->el_state.metanext = 1;
426 /* em_toggle_overwrite():
427 * Switch from insert to overwrite mode or vice versa
429 protected el_action_t
431 em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
434 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
435 MODE_REPLACE : MODE_INSERT;
440 /* em_copy_prev_word():
441 * Copy current word to cursor
443 protected el_action_t
445 em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
447 Char *cp, *oldc, *dp;
449 if (el->el_line.cursor == el->el_line.buffer)
452 oldc = el->el_line.cursor;
453 /* does a bounds check */
454 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
455 el->el_state.argument, ce__isword);
457 c_insert(el, (int)(oldc - cp));
458 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
461 el->el_line.cursor = dp;/* put cursor at end */
467 /* em_inc_search_next():
468 * Emacs incremental next search
470 protected el_action_t
472 em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
475 el->el_search.patlen = 0;
476 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
480 /* em_inc_search_prev():
481 * Emacs incremental reverse search
483 protected el_action_t
485 em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
488 el->el_search.patlen = 0;
489 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
493 /* em_delete_prev_char():
494 * Delete the character to the left of the cursor
497 protected el_action_t
499 em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
502 if (el->el_line.cursor <= el->el_line.buffer)
505 if (el->el_state.doingarg)
506 c_delbefore(el, el->el_state.argument);
509 el->el_line.cursor -= el->el_state.argument;
510 if (el->el_line.cursor < el->el_line.buffer)
511 el->el_line.cursor = el->el_line.buffer;