1 /* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 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.25 2011/07/29 15:16:33 christos Exp $");
42 #endif /* not lint && not SCCSID */
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
47 * emacs.c: Emacs functions
51 /* em_delete_or_list():
52 * Delete character under cursor or list completions if at end of line
57 em_delete_or_list(EditLine *el, Int c)
60 if (el->el_line.cursor == el->el_line.lastchar) {
61 /* if I'm at the end */
62 if (el->el_line.cursor == el->el_line.buffer) {
63 /* and the beginning */
64 terminal_writec(el, c); /* then do an EOF */
68 * Here we could list completions, but it is an
75 if (el->el_state.doingarg)
76 c_delafter(el, el->el_state.argument);
79 if (el->el_line.cursor > el->el_line.lastchar)
80 el->el_line.cursor = el->el_line.lastchar;
87 /* em_delete_next_word():
88 * Cut from cursor to end of current word
93 em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
97 if (el->el_line.cursor == el->el_line.lastchar)
100 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
101 el->el_state.argument, ce__isword);
103 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
106 el->el_chared.c_kill.last = kp;
108 c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
109 if (el->el_line.cursor > el->el_line.lastchar)
110 el->el_line.cursor = el->el_line.lastchar;
117 * Paste cut buffer at cursor position
120 protected el_action_t
122 em_yank(EditLine *el, Int c __attribute__((__unused__)))
126 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
129 if (el->el_line.lastchar +
130 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
134 el->el_chared.c_kill.mark = el->el_line.cursor;
135 cp = el->el_line.cursor;
137 /* open the space, */
139 (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
141 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
144 /* if an arg, cursor at beginning else cursor at end */
145 if (el->el_state.argument == 1)
146 el->el_line.cursor = cp;
153 * Cut the entire line and save in cut buffer
156 protected el_action_t
158 em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
162 cp = el->el_line.buffer;
163 kp = el->el_chared.c_kill.buf;
164 while (cp < el->el_line.lastchar)
165 *kp++ = *cp++; /* copy it */
166 el->el_chared.c_kill.last = kp;
167 /* zap! -- delete all of it */
168 el->el_line.lastchar = el->el_line.buffer;
169 el->el_line.cursor = el->el_line.buffer;
175 * Cut area between mark and cursor and save in cut buffer
178 protected el_action_t
180 em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
184 if (!el->el_chared.c_kill.mark)
187 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
188 cp = el->el_line.cursor;
189 kp = el->el_chared.c_kill.buf;
190 while (cp < el->el_chared.c_kill.mark)
191 *kp++ = *cp++; /* copy it */
192 el->el_chared.c_kill.last = kp;
193 c_delafter(el, (int)(cp - el->el_line.cursor));
194 } else { /* mark is before cursor */
195 cp = el->el_chared.c_kill.mark;
196 kp = el->el_chared.c_kill.buf;
197 while (cp < el->el_line.cursor)
198 *kp++ = *cp++; /* copy it */
199 el->el_chared.c_kill.last = kp;
200 c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
201 el->el_line.cursor = el->el_chared.c_kill.mark;
208 * Copy area between mark and cursor to cut buffer
211 protected el_action_t
213 em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
217 if (!el->el_chared.c_kill.mark)
220 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
221 cp = el->el_line.cursor;
222 kp = el->el_chared.c_kill.buf;
223 while (cp < el->el_chared.c_kill.mark)
224 *kp++ = *cp++; /* copy it */
225 el->el_chared.c_kill.last = kp;
227 cp = el->el_chared.c_kill.mark;
228 kp = el->el_chared.c_kill.buf;
229 while (cp < el->el_line.cursor)
230 *kp++ = *cp++; /* copy it */
231 el->el_chared.c_kill.last = kp;
237 /* em_gosmacs_transpose():
238 * Exchange the two characters before the cursor
239 * Gosling emacs transpose chars [^T]
241 protected el_action_t
242 em_gosmacs_transpose(EditLine *el, Int c)
245 if (el->el_line.cursor > &el->el_line.buffer[1]) {
246 /* must have at least two chars entered */
247 c = el->el_line.cursor[-2];
248 el->el_line.cursor[-2] = el->el_line.cursor[-1];
249 el->el_line.cursor[-1] = c;
257 * Move next to end of current word
260 protected el_action_t
262 em_next_word(EditLine *el, Int c __attribute__((__unused__)))
264 if (el->el_line.cursor == el->el_line.lastchar)
267 el->el_line.cursor = c__next_word(el->el_line.cursor,
268 el->el_line.lastchar,
269 el->el_state.argument,
272 if (el->el_map.type == MAP_VI)
273 if (el->el_chared.c_vcmd.action != NOP) {
282 * Uppercase the characters from cursor to end of current word
285 protected el_action_t
287 em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
291 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
292 el->el_state.argument, ce__isword);
294 for (cp = el->el_line.cursor; cp < ep; cp++)
298 el->el_line.cursor = ep;
299 if (el->el_line.cursor > el->el_line.lastchar)
300 el->el_line.cursor = el->el_line.lastchar;
305 /* em_capitol_case():
306 * Capitalize the characters from cursor to end of current word
309 protected el_action_t
311 em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
315 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
316 el->el_state.argument, ce__isword);
318 for (cp = el->el_line.cursor; cp < ep; cp++) {
326 for (; cp < ep; cp++)
330 el->el_line.cursor = ep;
331 if (el->el_line.cursor > el->el_line.lastchar)
332 el->el_line.cursor = el->el_line.lastchar;
338 * Lowercase the characters from cursor to end of current word
341 protected el_action_t
343 em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
347 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
348 el->el_state.argument, ce__isword);
350 for (cp = el->el_line.cursor; cp < ep; cp++)
354 el->el_line.cursor = ep;
355 if (el->el_line.cursor > el->el_line.lastchar)
356 el->el_line.cursor = el->el_line.lastchar;
362 * Set the mark at cursor
365 protected el_action_t
367 em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
370 el->el_chared.c_kill.mark = el->el_line.cursor;
375 /* em_exchange_mark():
376 * Exchange the cursor and mark
379 protected el_action_t
381 em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
385 cp = el->el_line.cursor;
386 el->el_line.cursor = el->el_chared.c_kill.mark;
387 el->el_chared.c_kill.mark = cp;
392 /* em_universal_argument():
393 * Universal argument (argument times 4)
396 protected el_action_t
398 em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
399 { /* multiply current argument by 4 */
401 if (el->el_state.argument > 1000000)
403 el->el_state.doingarg = 1;
404 el->el_state.argument *= 4;
410 * Add 8th bit to next character typed
413 protected el_action_t
415 em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
418 el->el_state.metanext = 1;
423 /* em_toggle_overwrite():
424 * Switch from insert to overwrite mode or vice versa
426 protected el_action_t
428 em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
431 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
432 MODE_REPLACE : MODE_INSERT;
437 /* em_copy_prev_word():
438 * Copy current word to cursor
440 protected el_action_t
442 em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
444 Char *cp, *oldc, *dp;
446 if (el->el_line.cursor == el->el_line.buffer)
449 oldc = el->el_line.cursor;
450 /* does a bounds check */
451 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
452 el->el_state.argument, ce__isword);
454 c_insert(el, (int)(oldc - cp));
455 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
458 el->el_line.cursor = dp;/* put cursor at end */
464 /* em_inc_search_next():
465 * Emacs incremental next search
467 protected el_action_t
469 em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
472 el->el_search.patlen = 0;
473 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
477 /* em_inc_search_prev():
478 * Emacs incremental reverse search
480 protected el_action_t
482 em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
485 el->el_search.patlen = 0;
486 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
490 /* em_delete_prev_char():
491 * Delete the character to the left of the cursor
494 protected el_action_t
496 em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
499 if (el->el_line.cursor <= el->el_line.buffer)
502 if (el->el_state.doingarg)
503 c_delbefore(el, el->el_state.argument);
506 el->el_line.cursor -= el->el_state.argument;
507 if (el->el_line.cursor < el->el_line.buffer)
508 el->el_line.cursor = el->el_line.buffer;