Ignore machine-check MSRs
[freebsd-src/fkvm-freebsd.git] / lib / libedit / emacs.c
bloba285b1c305eeae5a98cdc49cd29d3d4797d166e5
1 /*-
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
10 * are met:
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
30 * SUCH DAMAGE.
32 * $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $
35 #if !defined(lint) && !defined(SCCSID)
36 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
37 #endif /* not lint && not SCCSID */
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
42 * emacs.c: Emacs functions
44 #include "sys.h"
45 #include "el.h"
47 /* em_delete_or_list():
48 * Delete character under cursor or list completions if at end of line
49 * [^D]
51 protected el_action_t
52 /*ARGSUSED*/
53 em_delete_or_list(EditLine *el, int c)
56 if (el->el_line.cursor == el->el_line.lastchar) {
57 /* if I'm at the end */
58 if (el->el_line.cursor == el->el_line.buffer) {
59 /* and the beginning */
60 term_writec(el, c); /* then do an EOF */
61 return (CC_EOF);
62 } else {
64 * Here we could list completions, but it is an
65 * error right now
67 term_beep(el);
68 return (CC_ERROR);
70 } else {
71 if (el->el_state.doingarg)
72 c_delafter(el, el->el_state.argument);
73 else
74 c_delafter1(el);
75 if (el->el_line.cursor > el->el_line.lastchar)
76 el->el_line.cursor = el->el_line.lastchar;
77 /* bounds check */
78 return (CC_REFRESH);
83 /* em_delete_next_word():
84 * Cut from cursor to end of current word
85 * [M-d]
87 protected el_action_t
88 /*ARGSUSED*/
89 em_delete_next_word(EditLine *el, int c __unused)
91 char *cp, *p, *kp;
93 if (el->el_line.cursor == el->el_line.lastchar)
94 return (CC_ERROR);
96 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
97 el->el_state.argument, ce__isword);
99 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
100 /* save the text */
101 *kp++ = *p;
102 el->el_chared.c_kill.last = kp;
104 c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
105 if (el->el_line.cursor > el->el_line.lastchar)
106 el->el_line.cursor = el->el_line.lastchar;
107 /* bounds check */
108 return (CC_REFRESH);
112 /* em_yank():
113 * Paste cut buffer at cursor position
114 * [^Y]
116 protected el_action_t
117 /*ARGSUSED*/
118 em_yank(EditLine *el, int c __unused)
120 char *kp, *cp;
122 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
123 return (CC_NORM);
125 if (el->el_line.lastchar +
126 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
127 el->el_line.limit)
128 return (CC_ERROR);
130 el->el_chared.c_kill.mark = el->el_line.cursor;
131 cp = el->el_line.cursor;
133 /* open the space, */
134 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
135 /* copy the chars */
136 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
137 *cp++ = *kp;
139 /* if an arg, cursor at beginning else cursor at end */
140 if (el->el_state.argument == 1)
141 el->el_line.cursor = cp;
143 return (CC_REFRESH);
147 /* em_kill_line():
148 * Cut the entire line and save in cut buffer
149 * [^U]
151 protected el_action_t
152 /*ARGSUSED*/
153 em_kill_line(EditLine *el, int c __unused)
155 char *kp, *cp;
157 cp = el->el_line.buffer;
158 kp = el->el_chared.c_kill.buf;
159 while (cp < el->el_line.lastchar)
160 *kp++ = *cp++; /* copy it */
161 el->el_chared.c_kill.last = kp;
162 /* zap! -- delete all of it */
163 el->el_line.lastchar = el->el_line.buffer;
164 el->el_line.cursor = el->el_line.buffer;
165 return (CC_REFRESH);
169 /* em_kill_region():
170 * Cut area between mark and cursor and save in cut buffer
171 * [^W]
173 protected el_action_t
174 /*ARGSUSED*/
175 em_kill_region(EditLine *el, int c __unused)
177 char *kp, *cp;
179 if (!el->el_chared.c_kill.mark)
180 return (CC_ERROR);
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);
189 } else { /* mark is before cursor */
190 cp = el->el_chared.c_kill.mark;
191 kp = el->el_chared.c_kill.buf;
192 while (cp < el->el_line.cursor)
193 *kp++ = *cp++; /* copy it */
194 el->el_chared.c_kill.last = kp;
195 c_delbefore(el, cp - el->el_chared.c_kill.mark);
196 el->el_line.cursor = el->el_chared.c_kill.mark;
198 return (CC_REFRESH);
202 /* em_copy_region():
203 * Copy area between mark and cursor to cut buffer
204 * [M-W]
206 protected el_action_t
207 /*ARGSUSED*/
208 em_copy_region(EditLine *el, int c __unused)
210 char *kp, *cp;
212 if (!el->el_chared.c_kill.mark)
213 return (CC_ERROR);
215 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
216 cp = el->el_line.cursor;
217 kp = el->el_chared.c_kill.buf;
218 while (cp < el->el_chared.c_kill.mark)
219 *kp++ = *cp++; /* copy it */
220 el->el_chared.c_kill.last = kp;
221 } else {
222 cp = el->el_chared.c_kill.mark;
223 kp = el->el_chared.c_kill.buf;
224 while (cp < el->el_line.cursor)
225 *kp++ = *cp++; /* copy it */
226 el->el_chared.c_kill.last = kp;
228 return (CC_NORM);
232 /* em_gosmacs_transpose():
233 * Exchange the two characters before the cursor
234 * Gosling emacs transpose chars [^T]
236 protected el_action_t
237 em_gosmacs_transpose(EditLine *el, int c)
240 if (el->el_line.cursor > &el->el_line.buffer[1]) {
241 /* must have at least two chars entered */
242 c = el->el_line.cursor[-2];
243 el->el_line.cursor[-2] = el->el_line.cursor[-1];
244 el->el_line.cursor[-1] = c;
245 return (CC_REFRESH);
246 } else
247 return (CC_ERROR);
251 /* em_next_word():
252 * Move next to end of current word
253 * [M-f]
255 protected el_action_t
256 /*ARGSUSED*/
257 em_next_word(EditLine *el, int c __unused)
259 if (el->el_line.cursor == el->el_line.lastchar)
260 return (CC_ERROR);
262 el->el_line.cursor = c__next_word(el->el_line.cursor,
263 el->el_line.lastchar,
264 el->el_state.argument,
265 ce__isword);
267 if (el->el_map.type == MAP_VI)
268 if (el->el_chared.c_vcmd.action != NOP) {
269 cv_delfini(el);
270 return (CC_REFRESH);
272 return (CC_CURSOR);
276 /* em_upper_case():
277 * Uppercase the characters from cursor to end of current word
278 * [M-u]
280 protected el_action_t
281 /*ARGSUSED*/
282 em_upper_case(EditLine *el, int c __unused)
284 char *cp, *ep;
286 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
287 el->el_state.argument, ce__isword);
289 for (cp = el->el_line.cursor; cp < ep; cp++)
290 if (islower((unsigned char)*cp))
291 *cp = toupper((unsigned char)*cp);
293 el->el_line.cursor = ep;
294 if (el->el_line.cursor > el->el_line.lastchar)
295 el->el_line.cursor = el->el_line.lastchar;
296 return (CC_REFRESH);
300 /* em_capitol_case():
301 * Capitalize the characters from cursor to end of current word
302 * [M-c]
304 protected el_action_t
305 /*ARGSUSED*/
306 em_capitol_case(EditLine *el, int c __unused)
308 char *cp, *ep;
310 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
311 el->el_state.argument, ce__isword);
313 for (cp = el->el_line.cursor; cp < ep; cp++) {
314 if (isalpha((unsigned char)*cp)) {
315 if (islower((unsigned char)*cp))
316 *cp = toupper((unsigned char)*cp);
317 cp++;
318 break;
321 for (; cp < ep; cp++)
322 if (isupper((unsigned char)*cp))
323 *cp = tolower((unsigned char)*cp);
325 el->el_line.cursor = ep;
326 if (el->el_line.cursor > el->el_line.lastchar)
327 el->el_line.cursor = el->el_line.lastchar;
328 return (CC_REFRESH);
332 /* em_lower_case():
333 * Lowercase the characters from cursor to end of current word
334 * [M-l]
336 protected el_action_t
337 /*ARGSUSED*/
338 em_lower_case(EditLine *el, int c __unused)
340 char *cp, *ep;
342 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
343 el->el_state.argument, ce__isword);
345 for (cp = el->el_line.cursor; cp < ep; cp++)
346 if (isupper((unsigned char)*cp))
347 *cp = tolower((unsigned char)*cp);
349 el->el_line.cursor = ep;
350 if (el->el_line.cursor > el->el_line.lastchar)
351 el->el_line.cursor = el->el_line.lastchar;
352 return (CC_REFRESH);
356 /* em_set_mark():
357 * Set the mark at cursor
358 * [^@]
360 protected el_action_t
361 /*ARGSUSED*/
362 em_set_mark(EditLine *el, int c __unused)
365 el->el_chared.c_kill.mark = el->el_line.cursor;
366 return (CC_NORM);
370 /* em_exchange_mark():
371 * Exchange the cursor and mark
372 * [^X^X]
374 protected el_action_t
375 /*ARGSUSED*/
376 em_exchange_mark(EditLine *el, int c __unused)
378 char *cp;
380 cp = el->el_line.cursor;
381 el->el_line.cursor = el->el_chared.c_kill.mark;
382 el->el_chared.c_kill.mark = cp;
383 return (CC_CURSOR);
387 /* em_universal_argument():
388 * Universal argument (argument times 4)
389 * [^U]
391 protected el_action_t
392 /*ARGSUSED*/
393 em_universal_argument(EditLine *el, int c __unused)
394 { /* multiply current argument by 4 */
396 if (el->el_state.argument > 1000000)
397 return (CC_ERROR);
398 el->el_state.doingarg = 1;
399 el->el_state.argument *= 4;
400 return (CC_ARGHACK);
404 /* em_meta_next():
405 * Add 8th bit to next character typed
406 * [<ESC>]
408 protected el_action_t
409 /*ARGSUSED*/
410 em_meta_next(EditLine *el, int c __unused)
413 el->el_state.metanext = 1;
414 return (CC_ARGHACK);
418 /* em_toggle_overwrite():
419 * Switch from insert to overwrite mode or vice versa
421 protected el_action_t
422 /*ARGSUSED*/
423 em_toggle_overwrite(EditLine *el, int c __unused)
426 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
427 MODE_REPLACE : MODE_INSERT;
428 return (CC_NORM);
432 /* em_copy_prev_word():
433 * Copy current word to cursor
435 protected el_action_t
436 /*ARGSUSED*/
437 em_copy_prev_word(EditLine *el, int c __unused)
439 char *cp, *oldc, *dp;
441 if (el->el_line.cursor == el->el_line.buffer)
442 return (CC_ERROR);
444 oldc = el->el_line.cursor;
445 /* does a bounds check */
446 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
447 el->el_state.argument, ce__isword);
449 c_insert(el, oldc - cp);
450 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
451 *dp++ = *cp;
453 el->el_line.cursor = dp;/* put cursor at end */
455 return (CC_REFRESH);
459 /* em_inc_search_next():
460 * Emacs incremental next search
462 protected el_action_t
463 /*ARGSUSED*/
464 em_inc_search_next(EditLine *el, int c __unused)
467 el->el_search.patlen = 0;
468 return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
472 /* em_inc_search_prev():
473 * Emacs incremental reverse search
475 protected el_action_t
476 /*ARGSUSED*/
477 em_inc_search_prev(EditLine *el, int c __unused)
480 el->el_search.patlen = 0;
481 return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
485 /* em_delete_prev_char():
486 * Delete the character to the left of the cursor
487 * [^?]
489 protected el_action_t
490 /*ARGSUSED*/
491 em_delete_prev_char(EditLine *el, int c __unused)
494 if (el->el_line.cursor <= el->el_line.buffer)
495 return (CC_ERROR);
497 if (el->el_state.doingarg)
498 c_delbefore(el, el->el_state.argument);
499 else
500 c_delbefore1(el);
501 el->el_line.cursor -= el->el_state.argument;
502 if (el->el_line.cursor < el->el_line.buffer)
503 el->el_line.cursor = el->el_line.buffer;
504 return (CC_REFRESH);