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
37 #if !defined(lint) && !defined(SCCSID)
38 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
39 #endif /* not lint && not SCCSID */
42 * emacs.c: Emacs functions
47 /* em_delete_or_list():
48 * Delete character under cursor or list completions if at end of line
53 em_delete_or_list(el, c)
57 if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */
58 if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */
59 term_overwrite(el, STReof, 4);/* then do a EOF */
64 /* Here we could list completions, but it is an error right now */
70 c_delafter(el, el->el_state.argument); /* delete after dot */
71 if (el->el_line.cursor > el->el_line.lastchar)
72 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
78 /* em_delete_next_word():
79 * Cut from cursor to end of current word
84 em_delete_next_word(el, c)
90 if (el->el_line.cursor == el->el_line.lastchar)
93 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
94 el->el_state.argument, ce__isword);
96 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
99 el->el_chared.c_kill.last = kp;
101 c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
102 if (el->el_line.cursor > el->el_line.lastchar)
103 el->el_line.cursor = el->el_line.lastchar; /* bounds check */
109 * Paste cut buffer at cursor position
112 protected el_action_t
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
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 el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */
163 el->el_line.cursor = el->el_line.buffer;
169 * Cut area between mark and cursor and save in cut buffer
172 protected el_action_t
174 em_kill_region(el, c)
180 if (!el->el_chared.c_kill.mark)
183 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
184 cp = el->el_line.cursor;
185 kp = el->el_chared.c_kill.buf;
186 while (cp < el->el_chared.c_kill.mark)
187 *kp++ = *cp++; /* copy it */
188 el->el_chared.c_kill.last = kp;
189 c_delafter(el, cp - el->el_line.cursor);
191 else { /* mark is before cursor */
192 cp = el->el_chared.c_kill.mark;
193 kp = el->el_chared.c_kill.buf;
194 while (cp < el->el_line.cursor)
195 *kp++ = *cp++; /* copy it */
196 el->el_chared.c_kill.last = kp;
197 c_delbefore(el, cp - el->el_chared.c_kill.mark);
198 el->el_line.cursor = el->el_chared.c_kill.mark;
205 * Copy area between mark and cursor to cut buffer
208 protected el_action_t
210 em_copy_region(el, c)
216 if (el->el_chared.c_kill.mark)
219 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
220 cp = el->el_line.cursor;
221 kp = el->el_chared.c_kill.buf;
222 while (cp < el->el_chared.c_kill.mark)
223 *kp++ = *cp++; /* copy it */
224 el->el_chared.c_kill.last = kp;
227 cp = el->el_chared.c_kill.mark;
228 kp = el->el_chared.c_kill.buf;
229 while (cp < el->el_line.cursor)
230 *kp++ = *cp++; /* copy it */
231 el->el_chared.c_kill.last = kp;
237 /* em_gosmacs_traspose():
238 * Exchange the two characters before the cursor
239 * Gosling emacs transpose chars [^T]
241 protected el_action_t
242 em_gosmacs_traspose(el, 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;
260 * Move next to end of current word
263 protected el_action_t
269 if (el->el_line.cursor == el->el_line.lastchar)
272 el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar,
273 el->el_state.argument,
276 if (el->el_map.type == MAP_VI)
277 if (el->el_chared.c_vcmd.action & DELETE) {
286 * Uppercase the characters from cursor to end of current word
289 protected el_action_t
297 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
298 el->el_state.argument, ce__isword);
300 for (cp = el->el_line.cursor; cp < ep; cp++)
301 if (islower((unsigned char)*cp))
302 *cp = toupper((unsigned char)*cp);
304 el->el_line.cursor = ep;
305 if (el->el_line.cursor > el->el_line.lastchar)
306 el->el_line.cursor = el->el_line.lastchar;
311 /* em_capitol_case():
312 * Capitalize the characters from cursor to end of current word
315 protected el_action_t
317 em_capitol_case(el, c)
323 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
324 el->el_state.argument, ce__isword);
326 for (cp = el->el_line.cursor; cp < ep; cp++) {
327 if (isalpha((unsigned char)*cp)) {
328 if (islower((unsigned char)*cp))
329 *cp = toupper((unsigned char)*cp);
334 for (; cp < ep; cp++)
335 if (isupper((unsigned char)*cp))
336 *cp = tolower((unsigned char)*cp);
338 el->el_line.cursor = ep;
339 if (el->el_line.cursor > el->el_line.lastchar)
340 el->el_line.cursor = el->el_line.lastchar;
345 * Lowercase the characters from cursor to end of current word
348 protected el_action_t
356 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
357 el->el_state.argument, ce__isword);
359 for (cp = el->el_line.cursor; cp < ep; cp++)
360 if (isupper((unsigned char)*cp))
361 *cp = tolower((unsigned char)*cp);
363 el->el_line.cursor = ep;
364 if (el->el_line.cursor > el->el_line.lastchar)
365 el->el_line.cursor = el->el_line.lastchar;
371 * Set the mark at cursor
374 protected el_action_t
380 el->el_chared.c_kill.mark = el->el_line.cursor;
385 /* em_exchange_mark():
386 * Exchange the cursor and mark
389 protected el_action_t
391 em_exchange_mark(el, c)
397 cp = el->el_line.cursor;
398 el->el_line.cursor = el->el_chared.c_kill.mark;
399 el->el_chared.c_kill.mark = cp;
403 /* em_universal_argument():
404 * Universal argument (argument times 4)
407 protected el_action_t
409 em_universal_argument(el, c)
412 { /* multiply current argument by 4 */
413 if (el->el_state.argument > 1000000)
415 el->el_state.doingarg = 1;
416 el->el_state.argument *= 4;
421 * Add 8th bit to next character typed
424 protected el_action_t
430 el->el_state.metanext = 1;
435 /* em_toggle_overwrite():
436 * Switch from insert to overwrite mode or vice versa
438 protected el_action_t
440 em_toggle_overwrite(el, c)
444 el->el_state.inputmode =
445 (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
450 /* em_copy_prev_word():
451 * Copy current word to cursor
453 protected el_action_t
455 em_copy_prev_word(el, c)
459 char *cp, *oldc, *dp;
461 if (el->el_line.cursor == el->el_line.buffer)
464 oldc = el->el_line.cursor;
465 /* does a bounds check */
466 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
467 el->el_state.argument, ce__isword);
469 c_insert(el, oldc - cp);
470 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
473 el->el_line.cursor = dp; /* put cursor at end */
479 /* em_inc_search_next():
480 * Emacs incremental next search
482 protected el_action_t
484 em_inc_search_next(el, c)
488 el->el_search.patlen = 0;
489 return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
493 /* em_inc_search_prev():
494 * Emacs incremental reverse search
496 protected el_action_t
498 em_inc_search_prev(el, c)
502 el->el_search.patlen = 0;
503 return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);