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.4 2005/08/04 17:27:09 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(EditLine *el, int c)
54 if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */
55 if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */
56 term_overwrite(el, STReof, 4);/* then do a EOF */
61 /* Here we could list completions, but it is an error right now */
67 c_delafter(el, el->el_state.argument); /* delete after dot */
68 if (el->el_line.cursor > el->el_line.lastchar)
69 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
75 /* em_delete_next_word():
76 * Cut from cursor to end of current word
81 em_delete_next_word(EditLine *el, int c)
85 if (el->el_line.cursor == el->el_line.lastchar)
88 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
89 el->el_state.argument, ce__isword);
91 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
94 el->el_chared.c_kill.last = kp;
96 c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
97 if (el->el_line.cursor > el->el_line.lastchar)
98 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
104 * Paste cut buffer at cursor position
107 protected el_action_t
109 em_yank(EditLine *el, int c)
113 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
116 if (el->el_line.lastchar +
117 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
121 el->el_chared.c_kill.mark = el->el_line.cursor;
122 cp = el->el_line.cursor;
124 /* open the space, */
125 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
127 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
130 /* if an arg, cursor at beginning else cursor at end */
131 if (el->el_state.argument == 1)
132 el->el_line.cursor = cp;
139 * Cut the entire line and save in cut buffer
142 protected el_action_t
144 em_kill_line(EditLine *el, int c)
148 cp = el->el_line.buffer;
149 kp = el->el_chared.c_kill.buf;
150 while (cp < el->el_line.lastchar)
151 *kp++ = *cp++; /* copy it */
152 el->el_chared.c_kill.last = kp;
153 el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */
154 el->el_line.cursor = el->el_line.buffer;
160 * Cut area between mark and cursor and save in cut buffer
163 protected el_action_t
165 em_kill_region(EditLine *el, int c)
169 if (!el->el_chared.c_kill.mark)
172 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
173 cp = el->el_line.cursor;
174 kp = el->el_chared.c_kill.buf;
175 while (cp < el->el_chared.c_kill.mark)
176 *kp++ = *cp++; /* copy it */
177 el->el_chared.c_kill.last = kp;
178 c_delafter(el, cp - el->el_line.cursor);
180 else { /* mark is before cursor */
181 cp = el->el_chared.c_kill.mark;
182 kp = el->el_chared.c_kill.buf;
183 while (cp < el->el_line.cursor)
184 *kp++ = *cp++; /* copy it */
185 el->el_chared.c_kill.last = kp;
186 c_delbefore(el, cp - el->el_chared.c_kill.mark);
187 el->el_line.cursor = el->el_chared.c_kill.mark;
194 * Copy area between mark and cursor to cut buffer
197 protected el_action_t
199 em_copy_region(EditLine *el, int c)
203 if (el->el_chared.c_kill.mark)
206 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
207 cp = el->el_line.cursor;
208 kp = el->el_chared.c_kill.buf;
209 while (cp < el->el_chared.c_kill.mark)
210 *kp++ = *cp++; /* copy it */
211 el->el_chared.c_kill.last = kp;
214 cp = el->el_chared.c_kill.mark;
215 kp = el->el_chared.c_kill.buf;
216 while (cp < el->el_line.cursor)
217 *kp++ = *cp++; /* copy it */
218 el->el_chared.c_kill.last = kp;
224 /* em_gosmacs_traspose():
225 * Exchange the two characters before the cursor
226 * Gosling emacs transpose chars [^T]
228 protected el_action_t
229 em_gosmacs_traspose(EditLine *el, int c)
232 if (el->el_line.cursor > &el->el_line.buffer[1]) {
233 /* must have at least two chars entered */
234 c = el->el_line.cursor[-2];
235 el->el_line.cursor[-2] = el->el_line.cursor[-1];
236 el->el_line.cursor[-1] = c;
245 * Move next to end of current word
248 protected el_action_t
250 em_next_word(EditLine *el, int c)
252 if (el->el_line.cursor == el->el_line.lastchar)
255 el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar,
256 el->el_state.argument,
259 if (el->el_map.type == MAP_VI)
260 if (el->el_chared.c_vcmd.action & DELETE) {
269 * Uppercase the characters from cursor to end of current word
272 protected el_action_t
274 em_upper_case(EditLine *el, int c)
278 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
279 el->el_state.argument, ce__isword);
281 for (cp = el->el_line.cursor; cp < ep; cp++)
282 if (islower((unsigned char)*cp))
283 *cp = toupper((unsigned char)*cp);
285 el->el_line.cursor = ep;
286 if (el->el_line.cursor > el->el_line.lastchar)
287 el->el_line.cursor = el->el_line.lastchar;
292 /* em_capitol_case():
293 * Capitalize the characters from cursor to end of current word
296 protected el_action_t
298 em_capitol_case(EditLine *el, int c)
302 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
303 el->el_state.argument, ce__isword);
305 for (cp = el->el_line.cursor; cp < ep; cp++) {
306 if (isalpha((unsigned char)*cp)) {
307 if (islower((unsigned char)*cp))
308 *cp = toupper((unsigned char)*cp);
313 for (; cp < ep; cp++)
314 if (isupper((unsigned char)*cp))
315 *cp = tolower((unsigned char)*cp);
317 el->el_line.cursor = ep;
318 if (el->el_line.cursor > el->el_line.lastchar)
319 el->el_line.cursor = el->el_line.lastchar;
324 * Lowercase the characters from cursor to end of current word
327 protected el_action_t
329 em_lower_case(EditLine *el, int c)
333 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
334 el->el_state.argument, ce__isword);
336 for (cp = el->el_line.cursor; cp < ep; cp++)
337 if (isupper((unsigned char)*cp))
338 *cp = tolower((unsigned char)*cp);
340 el->el_line.cursor = ep;
341 if (el->el_line.cursor > el->el_line.lastchar)
342 el->el_line.cursor = el->el_line.lastchar;
348 * Set the mark at cursor
351 protected el_action_t
353 em_set_mark(EditLine *el, int c)
355 el->el_chared.c_kill.mark = el->el_line.cursor;
360 /* em_exchange_mark():
361 * Exchange the cursor and mark
364 protected el_action_t
366 em_exchange_mark(EditLine *el, int c)
370 cp = el->el_line.cursor;
371 el->el_line.cursor = el->el_chared.c_kill.mark;
372 el->el_chared.c_kill.mark = cp;
376 /* em_universal_argument():
377 * Universal argument (argument times 4)
380 protected el_action_t
382 em_universal_argument(EditLine *el, int c)
383 { /* multiply current argument by 4 */
384 if (el->el_state.argument > 1000000)
386 el->el_state.doingarg = 1;
387 el->el_state.argument *= 4;
392 * Add 8th bit to next character typed
395 protected el_action_t
397 em_meta_next(EditLine *el, int c)
399 el->el_state.metanext = 1;
404 /* em_toggle_overwrite():
405 * Switch from insert to overwrite mode or vice versa
407 protected el_action_t
409 em_toggle_overwrite(EditLine *el, int c)
411 el->el_state.inputmode =
412 (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
417 /* em_copy_prev_word():
418 * Copy current word to cursor
420 protected el_action_t
422 em_copy_prev_word(EditLine *el, int c)
424 char *cp, *oldc, *dp;
426 if (el->el_line.cursor == el->el_line.buffer)
429 oldc = el->el_line.cursor;
430 /* does a bounds check */
431 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
432 el->el_state.argument, ce__isword);
434 c_insert(el, oldc - cp);
435 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
438 el->el_line.cursor = dp; /* put cursor at end */
444 /* em_inc_search_next():
445 * Emacs incremental next search
447 protected el_action_t
449 em_inc_search_next(EditLine *el, int c)
451 el->el_search.patlen = 0;
452 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
456 /* em_inc_search_prev():
457 * Emacs incremental reverse search
459 protected el_action_t
461 em_inc_search_prev(EditLine *el, int c)
463 el->el_search.patlen = 0;
464 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);