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. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * @(#)emacs.c 8.1 (Berkeley) 6/4/93
37 * $DragonFly: src/lib/libedit/emacs.c,v 1.3 2004/10/25 19:38:45 drhodus Exp $
41 * emacs.c: Emacs functions
46 /* em_delete_or_list():
47 * Delete character under cursor or list completions if at end of line
52 em_delete_or_list(el, c)
56 if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */
57 if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */
58 term_overwrite(el, STReof, 4);/* then do a EOF */
63 /* Here we could list completions, but it is an error right now */
69 c_delafter(el, el->el_state.argument); /* delete after dot */
70 if (el->el_line.cursor > el->el_line.lastchar)
71 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
77 /* em_delete_next_word():
78 * Cut from cursor to end of current word
83 em_delete_next_word(el, c)
89 if (el->el_line.cursor == el->el_line.lastchar)
92 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
93 el->el_state.argument, ce__isword);
95 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
98 el->el_chared.c_kill.last = kp;
100 c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
101 if (el->el_line.cursor > el->el_line.lastchar)
102 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
108 * Paste cut buffer at cursor position
111 protected el_action_t
119 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
122 if (el->el_line.lastchar +
123 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
127 el->el_chared.c_kill.mark = el->el_line.cursor;
128 cp = el->el_line.cursor;
130 /* open the space, */
131 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
133 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
136 /* if an arg, cursor at beginning else cursor at end */
137 if (el->el_state.argument == 1)
138 el->el_line.cursor = cp;
145 * Cut the entire line and save in cut buffer
148 protected el_action_t
156 cp = el->el_line.buffer;
157 kp = el->el_chared.c_kill.buf;
158 while (cp < el->el_line.lastchar)
159 *kp++ = *cp++; /* copy it */
160 el->el_chared.c_kill.last = kp;
161 el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */
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(el, c)
179 if (!el->el_chared.c_kill.mark)
182 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
183 cp = el->el_line.cursor;
184 kp = el->el_chared.c_kill.buf;
185 while (cp < el->el_chared.c_kill.mark)
186 *kp++ = *cp++; /* copy it */
187 el->el_chared.c_kill.last = kp;
188 c_delafter(el, cp - el->el_line.cursor);
190 else { /* mark is before cursor */
191 cp = el->el_chared.c_kill.mark;
192 kp = el->el_chared.c_kill.buf;
193 while (cp < el->el_line.cursor)
194 *kp++ = *cp++; /* copy it */
195 el->el_chared.c_kill.last = kp;
196 c_delbefore(el, cp - el->el_chared.c_kill.mark);
197 el->el_line.cursor = el->el_chared.c_kill.mark;
204 * Copy area between mark and cursor to cut buffer
207 protected el_action_t
209 em_copy_region(el, c)
215 if (el->el_chared.c_kill.mark)
218 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
219 cp = el->el_line.cursor;
220 kp = el->el_chared.c_kill.buf;
221 while (cp < el->el_chared.c_kill.mark)
222 *kp++ = *cp++; /* copy it */
223 el->el_chared.c_kill.last = kp;
226 cp = el->el_chared.c_kill.mark;
227 kp = el->el_chared.c_kill.buf;
228 while (cp < el->el_line.cursor)
229 *kp++ = *cp++; /* copy it */
230 el->el_chared.c_kill.last = kp;
236 /* em_gosmacs_traspose():
237 * Exchange the two characters before the cursor
238 * Gosling emacs transpose chars [^T]
240 protected el_action_t
241 em_gosmacs_traspose(el, c)
246 if (el->el_line.cursor > &el->el_line.buffer[1]) {
247 /* must have at least two chars entered */
248 c = el->el_line.cursor[-2];
249 el->el_line.cursor[-2] = el->el_line.cursor[-1];
250 el->el_line.cursor[-1] = c;
259 * Move next to end of current word
262 protected el_action_t
268 if (el->el_line.cursor == el->el_line.lastchar)
271 el->el_line.cursor = c__next_word(el->el_line.cursor, 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 & DELETE) {
285 * Uppercase the characters from cursor to end of current word
288 protected el_action_t
296 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
297 el->el_state.argument, ce__isword);
299 for (cp = el->el_line.cursor; cp < ep; cp++)
300 if (islower((unsigned char)*cp))
301 *cp = toupper((unsigned char)*cp);
303 el->el_line.cursor = ep;
304 if (el->el_line.cursor > el->el_line.lastchar)
305 el->el_line.cursor = el->el_line.lastchar;
310 /* em_capitol_case():
311 * Capitalize the characters from cursor to end of current word
314 protected el_action_t
316 em_capitol_case(el, c)
322 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
323 el->el_state.argument, ce__isword);
325 for (cp = el->el_line.cursor; cp < ep; cp++) {
326 if (isalpha((unsigned char)*cp)) {
327 if (islower((unsigned char)*cp))
328 *cp = toupper((unsigned char)*cp);
333 for (; cp < ep; cp++)
334 if (isupper((unsigned char)*cp))
335 *cp = tolower((unsigned char)*cp);
337 el->el_line.cursor = ep;
338 if (el->el_line.cursor > el->el_line.lastchar)
339 el->el_line.cursor = el->el_line.lastchar;
344 * Lowercase the characters from cursor to end of current word
347 protected el_action_t
355 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
356 el->el_state.argument, ce__isword);
358 for (cp = el->el_line.cursor; cp < ep; cp++)
359 if (isupper((unsigned char)*cp))
360 *cp = tolower((unsigned char)*cp);
362 el->el_line.cursor = ep;
363 if (el->el_line.cursor > el->el_line.lastchar)
364 el->el_line.cursor = el->el_line.lastchar;
370 * Set the mark at cursor
373 protected el_action_t
379 el->el_chared.c_kill.mark = el->el_line.cursor;
384 /* em_exchange_mark():
385 * Exchange the cursor and mark
388 protected el_action_t
390 em_exchange_mark(el, c)
396 cp = el->el_line.cursor;
397 el->el_line.cursor = el->el_chared.c_kill.mark;
398 el->el_chared.c_kill.mark = cp;
402 /* em_universal_argument():
403 * Universal argument (argument times 4)
406 protected el_action_t
408 em_universal_argument(el, c)
411 { /* multiply current argument by 4 */
412 if (el->el_state.argument > 1000000)
414 el->el_state.doingarg = 1;
415 el->el_state.argument *= 4;
420 * Add 8th bit to next character typed
423 protected el_action_t
429 el->el_state.metanext = 1;
434 /* em_toggle_overwrite():
435 * Switch from insert to overwrite mode or vice versa
437 protected el_action_t
439 em_toggle_overwrite(el, c)
443 el->el_state.inputmode =
444 (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
449 /* em_copy_prev_word():
450 * Copy current word to cursor
452 protected el_action_t
454 em_copy_prev_word(el, c)
458 char *cp, *oldc, *dp;
460 if (el->el_line.cursor == el->el_line.buffer)
463 oldc = el->el_line.cursor;
464 /* does a bounds check */
465 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
466 el->el_state.argument, ce__isword);
468 c_insert(el, oldc - cp);
469 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
472 el->el_line.cursor = dp; /* put cursor at end */
478 /* em_inc_search_next():
479 * Emacs incremental next search
481 protected el_action_t
483 em_inc_search_next(el, c)
487 el->el_search.patlen = 0;
488 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
492 /* em_inc_search_prev():
493 * Emacs incremental reverse search
495 protected el_action_t
497 em_inc_search_prev(el, c)
501 el->el_search.patlen = 0;
502 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);