2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)emacs.c 8.1 (Berkeley) 6/4/93
33 * $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $
34 * $DragonFly: src/lib/libedit/emacs.c,v 1.5 2005/11/13 11:58:30 corecode Exp $
40 * emacs.c: Emacs functions
44 /* em_delete_or_list():
45 * Delete character under cursor or list completions if at end of line
50 em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
53 if (el->el_line.cursor == el->el_line.lastchar) {
54 /* if I'm at the end */
55 if (el->el_line.cursor == el->el_line.buffer) {
56 /* and the beginning */
57 term_overwrite(el, STReof, 4); /* then do a EOF */
62 * Here we could list completions, but it is an
69 if (el->el_state.doingarg)
70 c_delafter(el, el->el_state.argument);
73 if (el->el_line.cursor > el->el_line.lastchar)
74 el->el_line.cursor = el->el_line.lastchar;
81 /* em_delete_next_word():
82 * Cut from cursor to end of current word
87 em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
91 if (el->el_line.cursor == el->el_line.lastchar)
94 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
95 el->el_state.argument, ce__isword);
97 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
100 el->el_chared.c_kill.last = kp;
102 c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
103 if (el->el_line.cursor > el->el_line.lastchar)
104 el->el_line.cursor = el->el_line.lastchar;
111 * Paste cut buffer at cursor position
114 protected el_action_t
116 em_yank(EditLine *el, int c __attribute__((__unused__)))
120 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
123 if (el->el_line.lastchar +
124 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
128 el->el_chared.c_kill.mark = el->el_line.cursor;
129 cp = el->el_line.cursor;
131 /* open the space, */
132 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
134 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
137 /* if an arg, cursor at beginning else cursor at end */
138 if (el->el_state.argument == 1)
139 el->el_line.cursor = cp;
146 * Cut the entire line and save in cut buffer
149 protected el_action_t
151 em_kill_line(EditLine *el, int c __attribute__((__unused__)))
155 cp = el->el_line.buffer;
156 kp = el->el_chared.c_kill.buf;
157 while (cp < el->el_line.lastchar)
158 *kp++ = *cp++; /* copy it */
159 el->el_chared.c_kill.last = kp;
160 /* zap! -- delete all of it */
161 el->el_line.lastchar = el->el_line.buffer;
162 el->el_line.cursor = el->el_line.buffer;
168 * Cut area between mark and cursor and save in cut buffer
171 protected el_action_t
173 em_kill_region(EditLine *el, int c __attribute__((__unused__)))
177 if (!el->el_chared.c_kill.mark)
180 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
181 cp = el->el_line.cursor;
182 kp = el->el_chared.c_kill.buf;
183 while (cp < el->el_chared.c_kill.mark)
184 *kp++ = *cp++; /* copy it */
185 el->el_chared.c_kill.last = kp;
186 c_delafter(el, cp - el->el_line.cursor);
187 } else { /* mark is before cursor */
188 cp = el->el_chared.c_kill.mark;
189 kp = el->el_chared.c_kill.buf;
190 while (cp < el->el_line.cursor)
191 *kp++ = *cp++; /* copy it */
192 el->el_chared.c_kill.last = kp;
193 c_delbefore(el, cp - el->el_chared.c_kill.mark);
194 el->el_line.cursor = el->el_chared.c_kill.mark;
201 * Copy area between mark and cursor to cut buffer
204 protected el_action_t
206 em_copy_region(EditLine *el, int c __attribute__((__unused__)))
210 if (!el->el_chared.c_kill.mark)
213 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
214 cp = el->el_line.cursor;
215 kp = el->el_chared.c_kill.buf;
216 while (cp < el->el_chared.c_kill.mark)
217 *kp++ = *cp++; /* copy it */
218 el->el_chared.c_kill.last = kp;
220 cp = el->el_chared.c_kill.mark;
221 kp = el->el_chared.c_kill.buf;
222 while (cp < el->el_line.cursor)
223 *kp++ = *cp++; /* copy it */
224 el->el_chared.c_kill.last = kp;
230 /* em_gosmacs_transpose():
231 * Exchange the two characters before the cursor
232 * Gosling emacs transpose chars [^T]
234 protected el_action_t
235 em_gosmacs_transpose(EditLine *el, int c)
238 if (el->el_line.cursor > &el->el_line.buffer[1]) {
239 /* must have at least two chars entered */
240 c = el->el_line.cursor[-2];
241 el->el_line.cursor[-2] = el->el_line.cursor[-1];
242 el->el_line.cursor[-1] = c;
250 * Move next to end of current word
253 protected el_action_t
255 em_next_word(EditLine *el, int c __attribute__((__unused__)))
257 if (el->el_line.cursor == el->el_line.lastchar)
260 el->el_line.cursor = c__next_word(el->el_line.cursor,
261 el->el_line.lastchar,
262 el->el_state.argument,
265 if (el->el_map.type == MAP_VI)
266 if (el->el_chared.c_vcmd.action != NOP) {
275 * Uppercase the characters from cursor to end of current word
278 protected el_action_t
280 em_upper_case(EditLine *el, int c __attribute__((__unused__)))
284 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
285 el->el_state.argument, ce__isword);
287 for (cp = el->el_line.cursor; cp < ep; cp++)
288 if (islower((unsigned char)*cp))
289 *cp = toupper((unsigned char)*cp);
291 el->el_line.cursor = ep;
292 if (el->el_line.cursor > el->el_line.lastchar)
293 el->el_line.cursor = el->el_line.lastchar;
298 /* em_capitol_case():
299 * Capitalize the characters from cursor to end of current word
302 protected el_action_t
304 em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
308 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
309 el->el_state.argument, ce__isword);
311 for (cp = el->el_line.cursor; cp < ep; cp++) {
312 if (isalpha((unsigned char)*cp)) {
313 if (islower((unsigned char)*cp))
314 *cp = toupper((unsigned char)*cp);
319 for (; cp < ep; cp++)
320 if (isupper((unsigned char)*cp))
321 *cp = tolower((unsigned char)*cp);
323 el->el_line.cursor = ep;
324 if (el->el_line.cursor > el->el_line.lastchar)
325 el->el_line.cursor = el->el_line.lastchar;
331 * Lowercase the characters from cursor to end of current word
334 protected el_action_t
336 em_lower_case(EditLine *el, int c __attribute__((__unused__)))
340 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
341 el->el_state.argument, ce__isword);
343 for (cp = el->el_line.cursor; cp < ep; cp++)
344 if (isupper((unsigned char)*cp))
345 *cp = tolower((unsigned char)*cp);
347 el->el_line.cursor = ep;
348 if (el->el_line.cursor > el->el_line.lastchar)
349 el->el_line.cursor = el->el_line.lastchar;
355 * Set the mark at cursor
358 protected el_action_t
360 em_set_mark(EditLine *el, int c __attribute__((__unused__)))
363 el->el_chared.c_kill.mark = el->el_line.cursor;
368 /* em_exchange_mark():
369 * Exchange the cursor and mark
372 protected el_action_t
374 em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
378 cp = el->el_line.cursor;
379 el->el_line.cursor = el->el_chared.c_kill.mark;
380 el->el_chared.c_kill.mark = cp;
385 /* em_universal_argument():
386 * Universal argument (argument times 4)
389 protected el_action_t
391 em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
392 { /* multiply current argument by 4 */
394 if (el->el_state.argument > 1000000)
396 el->el_state.doingarg = 1;
397 el->el_state.argument *= 4;
403 * Add 8th bit to next character typed
406 protected el_action_t
408 em_meta_next(EditLine *el, int c __attribute__((__unused__)))
411 el->el_state.metanext = 1;
416 /* em_toggle_overwrite():
417 * Switch from insert to overwrite mode or vice versa
419 protected el_action_t
421 em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
424 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
425 MODE_REPLACE : MODE_INSERT;
430 /* em_copy_prev_word():
431 * Copy current word to cursor
433 protected el_action_t
435 em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
437 char *cp, *oldc, *dp;
439 if (el->el_line.cursor == el->el_line.buffer)
442 oldc = el->el_line.cursor;
443 /* does a bounds check */
444 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
445 el->el_state.argument, ce__isword);
447 c_insert(el, oldc - cp);
448 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
451 el->el_line.cursor = dp;/* put cursor at end */
457 /* em_inc_search_next():
458 * Emacs incremental next search
460 protected el_action_t
462 em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
465 el->el_search.patlen = 0;
466 return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
470 /* em_inc_search_prev():
471 * Emacs incremental reverse search
473 protected el_action_t
475 em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
478 el->el_search.patlen = 0;
479 return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
483 /* em_delete_prev_char():
484 * Delete the character to the left of the cursor
487 protected el_action_t
489 em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
492 if (el->el_line.cursor <= el->el_line.buffer)
495 if (el->el_state.doingarg)
496 c_delbefore(el, el->el_state.argument);
499 el->el_line.cursor -= el->el_state.argument;
500 if (el->el_line.cursor < el->el_line.buffer)
501 el->el_line.cursor = el->el_line.buffer;