1 /* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 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.36 2016/05/09 21:46:56 christos Exp $");
42 #endif /* not lint && not SCCSID */
45 * emacs.c: Emacs functions
53 /* em_delete_or_list():
54 * Delete character under cursor or list completions if at end of line
57 libedit_private el_action_t
59 em_delete_or_list(EditLine *el, wint_t c)
62 if (el->el_line.cursor == el->el_line.lastchar) {
63 /* if I'm at the end */
64 if (el->el_line.cursor == el->el_line.buffer) {
65 /* and the beginning */
66 terminal_writec(el, c); /* then do an EOF */
70 * Here we could list completions, but it is an
77 if (el->el_state.doingarg)
78 c_delafter(el, el->el_state.argument);
81 if (el->el_line.cursor > el->el_line.lastchar)
82 el->el_line.cursor = el->el_line.lastchar;
89 /* em_delete_next_word():
90 * Cut from cursor to end of current word
93 libedit_private el_action_t
95 em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
99 if (el->el_line.cursor == el->el_line.lastchar)
102 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
103 el->el_state.argument, ce__isword);
105 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
108 el->el_chared.c_kill.last = kp;
110 c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
111 if (el->el_line.cursor > el->el_line.lastchar)
112 el->el_line.cursor = el->el_line.lastchar;
119 * Paste cut buffer at cursor position
122 libedit_private el_action_t
124 em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
128 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
131 if (el->el_line.lastchar +
132 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
136 el->el_chared.c_kill.mark = el->el_line.cursor;
137 cp = el->el_line.cursor;
139 /* open the space, */
141 (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
143 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
146 /* if an arg, cursor at beginning else cursor at end */
147 if (el->el_state.argument == 1)
148 el->el_line.cursor = cp;
155 * Cut the entire line and save in cut buffer
158 libedit_private el_action_t
160 em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
164 cp = el->el_line.buffer;
165 kp = el->el_chared.c_kill.buf;
166 while (cp < el->el_line.lastchar)
167 *kp++ = *cp++; /* copy it */
168 el->el_chared.c_kill.last = kp;
169 /* zap! -- delete all of it */
170 el->el_line.lastchar = el->el_line.buffer;
171 el->el_line.cursor = el->el_line.buffer;
177 * Cut area between mark and cursor and save in cut buffer
180 libedit_private el_action_t
182 em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
186 if (!el->el_chared.c_kill.mark)
189 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
190 cp = el->el_line.cursor;
191 kp = el->el_chared.c_kill.buf;
192 while (cp < el->el_chared.c_kill.mark)
193 *kp++ = *cp++; /* copy it */
194 el->el_chared.c_kill.last = kp;
195 c_delafter(el, (int)(cp - el->el_line.cursor));
196 } else { /* mark is before cursor */
197 cp = el->el_chared.c_kill.mark;
198 kp = el->el_chared.c_kill.buf;
199 while (cp < el->el_line.cursor)
200 *kp++ = *cp++; /* copy it */
201 el->el_chared.c_kill.last = kp;
202 c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
203 el->el_line.cursor = el->el_chared.c_kill.mark;
210 * Copy area between mark and cursor to cut buffer
213 libedit_private el_action_t
215 em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
219 if (!el->el_chared.c_kill.mark)
222 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
223 cp = el->el_line.cursor;
224 kp = el->el_chared.c_kill.buf;
225 while (cp < el->el_chared.c_kill.mark)
226 *kp++ = *cp++; /* copy it */
227 el->el_chared.c_kill.last = kp;
229 cp = el->el_chared.c_kill.mark;
230 kp = el->el_chared.c_kill.buf;
231 while (cp < el->el_line.cursor)
232 *kp++ = *cp++; /* copy it */
233 el->el_chared.c_kill.last = kp;
239 /* em_gosmacs_transpose():
240 * Exchange the two characters before the cursor
241 * Gosling emacs transpose chars [^T]
243 libedit_private el_action_t
244 em_gosmacs_transpose(EditLine *el, wint_t c)
247 if (el->el_line.cursor > &el->el_line.buffer[1]) {
248 /* must have at least two chars entered */
249 c = el->el_line.cursor[-2];
250 el->el_line.cursor[-2] = el->el_line.cursor[-1];
251 el->el_line.cursor[-1] = c;
259 * Move next to end of current word
262 libedit_private el_action_t
264 em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
266 if (el->el_line.cursor == el->el_line.lastchar)
269 el->el_line.cursor = c__next_word(el->el_line.cursor,
270 el->el_line.lastchar,
271 el->el_state.argument,
274 if (el->el_map.type == MAP_VI)
275 if (el->el_chared.c_vcmd.action != NOP) {
284 * Uppercase the characters from cursor to end of current word
287 libedit_private el_action_t
289 em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
293 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
294 el->el_state.argument, ce__isword);
296 for (cp = el->el_line.cursor; cp < ep; cp++)
300 el->el_line.cursor = ep;
301 if (el->el_line.cursor > el->el_line.lastchar)
302 el->el_line.cursor = el->el_line.lastchar;
307 /* em_capitol_case():
308 * Capitalize the characters from cursor to end of current word
311 libedit_private el_action_t
313 em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
317 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
318 el->el_state.argument, ce__isword);
320 for (cp = el->el_line.cursor; cp < ep; cp++) {
328 for (; cp < ep; cp++)
332 el->el_line.cursor = ep;
333 if (el->el_line.cursor > el->el_line.lastchar)
334 el->el_line.cursor = el->el_line.lastchar;
340 * Lowercase the characters from cursor to end of current word
343 libedit_private el_action_t
345 em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
349 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
350 el->el_state.argument, ce__isword);
352 for (cp = el->el_line.cursor; cp < ep; cp++)
356 el->el_line.cursor = ep;
357 if (el->el_line.cursor > el->el_line.lastchar)
358 el->el_line.cursor = el->el_line.lastchar;
364 * Set the mark at cursor
367 libedit_private el_action_t
369 em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
372 el->el_chared.c_kill.mark = el->el_line.cursor;
377 /* em_exchange_mark():
378 * Exchange the cursor and mark
381 libedit_private el_action_t
383 em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
387 cp = el->el_line.cursor;
388 el->el_line.cursor = el->el_chared.c_kill.mark;
389 el->el_chared.c_kill.mark = cp;
394 /* em_universal_argument():
395 * Universal argument (argument times 4)
398 libedit_private el_action_t
400 em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
401 { /* multiply current argument by 4 */
403 if (el->el_state.argument > 1000000)
405 el->el_state.doingarg = 1;
406 el->el_state.argument *= 4;
412 * Add 8th bit to next character typed
415 libedit_private el_action_t
417 em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
420 el->el_state.metanext = 1;
425 /* em_toggle_overwrite():
426 * Switch from insert to overwrite mode or vice versa
428 libedit_private el_action_t
430 em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
433 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
434 MODE_REPLACE : MODE_INSERT;
439 /* em_copy_prev_word():
440 * Copy current word to cursor
442 libedit_private el_action_t
444 em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
446 wchar_t *cp, *oldc, *dp;
448 if (el->el_line.cursor == el->el_line.buffer)
451 oldc = el->el_line.cursor;
452 /* does a bounds check */
453 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
454 el->el_state.argument, ce__isword);
456 c_insert(el, (int)(oldc - cp));
457 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
460 el->el_line.cursor = dp;/* put cursor at end */
466 /* em_inc_search_next():
467 * Emacs incremental next search
469 libedit_private el_action_t
471 em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
474 el->el_search.patlen = 0;
475 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
479 /* em_inc_search_prev():
480 * Emacs incremental reverse search
482 libedit_private el_action_t
484 em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
487 el->el_search.patlen = 0;
488 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
492 /* em_delete_prev_char():
493 * Delete the character to the left of the cursor
496 libedit_private el_action_t
498 em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
501 if (el->el_line.cursor <= el->el_line.buffer)
504 if (el->el_state.doingarg)
505 c_delbefore(el, el->el_state.argument);
508 el->el_line.cursor -= el->el_state.argument;
509 if (el->el_line.cursor < el->el_line.buffer)
510 el->el_line.cursor = el->el_line.buffer;