Titan Core Initial Contribution
[deliverable/titan.core.git] / mctr2 / editline / libedit / src / emacs.c
CommitLineData
970ed795
EL
1/* $NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
21 *
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
32 * SUCH DAMAGE.
33 */
34
35#include "config.h"
36#if !defined(lint) && !defined(SCCSID)
37#if 0
38static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
39#else
40__RCSID("$NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
41#endif
42#endif /* not lint && not SCCSID */
43
44/*
45 * emacs.c: Emacs functions
46 */
47#include "el.h"
48
49/* em_delete_or_list():
50 * Delete character under cursor or list completions if at end of line
51 * [^D]
52 */
53protected el_action_t
54/*ARGSUSED*/
55em_delete_or_list(EditLine *el, Int c)
56{
57
58 if (el->el_line.cursor == el->el_line.lastchar) {
59 /* if I'm at the end */
60 if (el->el_line.cursor == el->el_line.buffer) {
61 /* and the beginning */
62 term_writec(el, c); /* then do an EOF */
63 return (CC_EOF);
64 } else {
65 /*
66 * Here we could list completions, but it is an
67 * error right now
68 */
69 term_beep(el);
70 return (CC_ERROR);
71 }
72 } else {
73 if (el->el_state.doingarg)
74 c_delafter(el, el->el_state.argument);
75 else
76 c_delafter1(el);
77 if (el->el_line.cursor > el->el_line.lastchar)
78 el->el_line.cursor = el->el_line.lastchar;
79 /* bounds check */
80 return (CC_REFRESH);
81 }
82}
83
84
85/* em_delete_next_word():
86 * Cut from cursor to end of current word
87 * [M-d]
88 */
89protected el_action_t
90/*ARGSUSED*/
91em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
92{
93 Char *cp, *p, *kp;
94
95 if (el->el_line.cursor == el->el_line.lastchar)
96 return (CC_ERROR);
97
98 cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
99 el->el_state.argument, ce__isword);
100
101 for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
102 /* save the text */
103 *kp++ = *p;
104 el->el_chared.c_kill.last = kp;
105
106 c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
107 if (el->el_line.cursor > el->el_line.lastchar)
108 el->el_line.cursor = el->el_line.lastchar;
109 /* bounds check */
110 return (CC_REFRESH);
111}
112
113
114/* em_yank():
115 * Paste cut buffer at cursor position
116 * [^Y]
117 */
118protected el_action_t
119/*ARGSUSED*/
120em_yank(EditLine *el, Int c __attribute__((__unused__)))
121{
122 Char *kp, *cp;
123
124 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
125 return (CC_NORM);
126
127 if (el->el_line.lastchar +
128 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
129 el->el_line.limit)
130 return (CC_ERROR);
131
132 el->el_chared.c_kill.mark = el->el_line.cursor;
133 cp = el->el_line.cursor;
134
135 /* open the space, */
136 c_insert(el,
137 (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
138 /* copy the chars */
139 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
140 *cp++ = *kp;
141
142 /* if an arg, cursor at beginning else cursor at end */
143 if (el->el_state.argument == 1)
144 el->el_line.cursor = cp;
145
146 return (CC_REFRESH);
147}
148
149
150/* em_kill_line():
151 * Cut the entire line and save in cut buffer
152 * [^U]
153 */
154protected el_action_t
155/*ARGSUSED*/
156em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
157{
158 Char *kp, *cp;
159
160 cp = el->el_line.buffer;
161 kp = el->el_chared.c_kill.buf;
162 while (cp < el->el_line.lastchar)
163 *kp++ = *cp++; /* copy it */
164 el->el_chared.c_kill.last = kp;
165 /* zap! -- delete all of it */
166 el->el_line.lastchar = el->el_line.buffer;
167 el->el_line.cursor = el->el_line.buffer;
168 return (CC_REFRESH);
169}
170
171
172/* em_kill_region():
173 * Cut area between mark and cursor and save in cut buffer
174 * [^W]
175 */
176protected el_action_t
177/*ARGSUSED*/
178em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
179{
180 Char *kp, *cp;
181
182 if (!el->el_chared.c_kill.mark)
183 return (CC_ERROR);
184
185 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
186 cp = el->el_line.cursor;
187 kp = el->el_chared.c_kill.buf;
188 while (cp < el->el_chared.c_kill.mark)
189 *kp++ = *cp++; /* copy it */
190 el->el_chared.c_kill.last = kp;
191 c_delafter(el, (int)(cp - el->el_line.cursor));
192 } else { /* mark is before cursor */
193 cp = el->el_chared.c_kill.mark;
194 kp = el->el_chared.c_kill.buf;
195 while (cp < el->el_line.cursor)
196 *kp++ = *cp++; /* copy it */
197 el->el_chared.c_kill.last = kp;
198 c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
199 el->el_line.cursor = el->el_chared.c_kill.mark;
200 }
201 return (CC_REFRESH);
202}
203
204
205/* em_copy_region():
206 * Copy area between mark and cursor to cut buffer
207 * [M-W]
208 */
209protected el_action_t
210/*ARGSUSED*/
211em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
212{
213 Char *kp, *cp;
214
215 if (!el->el_chared.c_kill.mark)
216 return (CC_ERROR);
217
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;
224 } else {
225 cp = el->el_chared.c_kill.mark;
226 kp = el->el_chared.c_kill.buf;
227 while (cp < el->el_line.cursor)
228 *kp++ = *cp++; /* copy it */
229 el->el_chared.c_kill.last = kp;
230 }
231 return (CC_NORM);
232}
233
234
235/* em_gosmacs_transpose():
236 * Exchange the two characters before the cursor
237 * Gosling emacs transpose chars [^T]
238 */
239protected el_action_t
240em_gosmacs_transpose(EditLine *el, Int c)
241{
242
243 if (el->el_line.cursor > &el->el_line.buffer[1]) {
244 /* must have at least two chars entered */
245 c = el->el_line.cursor[-2];
246 el->el_line.cursor[-2] = el->el_line.cursor[-1];
247 el->el_line.cursor[-1] = c;
248 return (CC_REFRESH);
249 } else
250 return (CC_ERROR);
251}
252
253
254/* em_next_word():
255 * Move next to end of current word
256 * [M-f]
257 */
258protected el_action_t
259/*ARGSUSED*/
260em_next_word(EditLine *el, Int c __attribute__((__unused__)))
261{
262 if (el->el_line.cursor == el->el_line.lastchar)
263 return (CC_ERROR);
264
265 el->el_line.cursor = c__next_word(el->el_line.cursor,
266 el->el_line.lastchar,
267 el->el_state.argument,
268 ce__isword);
269
270 if (el->el_map.type == MAP_VI)
271 if (el->el_chared.c_vcmd.action != NOP) {
272 cv_delfini(el);
273 return (CC_REFRESH);
274 }
275 return (CC_CURSOR);
276}
277
278
279/* em_upper_case():
280 * Uppercase the characters from cursor to end of current word
281 * [M-u]
282 */
283protected el_action_t
284/*ARGSUSED*/
285em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
286{
287 Char *cp, *ep;
288
289 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
290 el->el_state.argument, ce__isword);
291
292 for (cp = el->el_line.cursor; cp < ep; cp++)
293 if (Islower(*cp))
294 *cp = Toupper(*cp);
295
296 el->el_line.cursor = ep;
297 if (el->el_line.cursor > el->el_line.lastchar)
298 el->el_line.cursor = el->el_line.lastchar;
299 return (CC_REFRESH);
300}
301
302
303/* em_capitol_case():
304 * Capitalize the characters from cursor to end of current word
305 * [M-c]
306 */
307protected el_action_t
308/*ARGSUSED*/
309em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
310{
311 Char *cp, *ep;
312
313 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
314 el->el_state.argument, ce__isword);
315
316 for (cp = el->el_line.cursor; cp < ep; cp++) {
317 if (Isalpha(*cp)) {
318 if (Islower(*cp))
319 *cp = Toupper(*cp);
320 cp++;
321 break;
322 }
323 }
324 for (; cp < ep; cp++)
325 if (Isupper(*cp))
326 *cp = Tolower(*cp);
327
328 el->el_line.cursor = ep;
329 if (el->el_line.cursor > el->el_line.lastchar)
330 el->el_line.cursor = el->el_line.lastchar;
331 return (CC_REFRESH);
332}
333
334
335/* em_lower_case():
336 * Lowercase the characters from cursor to end of current word
337 * [M-l]
338 */
339protected el_action_t
340/*ARGSUSED*/
341em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
342{
343 Char *cp, *ep;
344
345 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
346 el->el_state.argument, ce__isword);
347
348 for (cp = el->el_line.cursor; cp < ep; cp++)
349 if (Isupper(*cp))
350 *cp = Tolower(*cp);
351
352 el->el_line.cursor = ep;
353 if (el->el_line.cursor > el->el_line.lastchar)
354 el->el_line.cursor = el->el_line.lastchar;
355 return (CC_REFRESH);
356}
357
358
359/* em_set_mark():
360 * Set the mark at cursor
361 * [^@]
362 */
363protected el_action_t
364/*ARGSUSED*/
365em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
366{
367
368 el->el_chared.c_kill.mark = el->el_line.cursor;
369 return (CC_NORM);
370}
371
372
373/* em_exchange_mark():
374 * Exchange the cursor and mark
375 * [^X^X]
376 */
377protected el_action_t
378/*ARGSUSED*/
379em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
380{
381 Char *cp;
382
383 cp = el->el_line.cursor;
384 el->el_line.cursor = el->el_chared.c_kill.mark;
385 el->el_chared.c_kill.mark = cp;
386 return (CC_CURSOR);
387}
388
389
390/* em_universal_argument():
391 * Universal argument (argument times 4)
392 * [^U]
393 */
394protected el_action_t
395/*ARGSUSED*/
396em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
397{ /* multiply current argument by 4 */
398
399 if (el->el_state.argument > 1000000)
400 return (CC_ERROR);
401 el->el_state.doingarg = 1;
402 el->el_state.argument *= 4;
403 return (CC_ARGHACK);
404}
405
406
407/* em_meta_next():
408 * Add 8th bit to next character typed
409 * [<ESC>]
410 */
411protected el_action_t
412/*ARGSUSED*/
413em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
414{
415
416 el->el_state.metanext = 1;
417 return (CC_ARGHACK);
418}
419
420
421/* em_toggle_overwrite():
422 * Switch from insert to overwrite mode or vice versa
423 */
424protected el_action_t
425/*ARGSUSED*/
426em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
427{
428
429 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
430 MODE_REPLACE : MODE_INSERT;
431 return (CC_NORM);
432}
433
434
435/* em_copy_prev_word():
436 * Copy current word to cursor
437 */
438protected el_action_t
439/*ARGSUSED*/
440em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
441{
442 Char *cp, *oldc, *dp;
443
444 if (el->el_line.cursor == el->el_line.buffer)
445 return (CC_ERROR);
446
447 oldc = el->el_line.cursor;
448 /* does a bounds check */
449 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
450 el->el_state.argument, ce__isword);
451
452 c_insert(el, (int)(oldc - cp));
453 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
454 *dp++ = *cp;
455
456 el->el_line.cursor = dp;/* put cursor at end */
457
458 return (CC_REFRESH);
459}
460
461
462/* em_inc_search_next():
463 * Emacs incremental next search
464 */
465protected el_action_t
466/*ARGSUSED*/
467em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
468{
469
470 el->el_search.patlen = 0;
471 return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
472}
473
474
475/* em_inc_search_prev():
476 * Emacs incremental reverse search
477 */
478protected el_action_t
479/*ARGSUSED*/
480em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
481{
482
483 el->el_search.patlen = 0;
484 return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
485}
486
487
488/* em_delete_prev_char():
489 * Delete the character to the left of the cursor
490 * [^?]
491 */
492protected el_action_t
493/*ARGSUSED*/
494em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
495{
496
497 if (el->el_line.cursor <= el->el_line.buffer)
498 return (CC_ERROR);
499
500 if (el->el_state.doingarg)
501 c_delbefore(el, el->el_state.argument);
502 else
503 c_delbefore1(el);
504 el->el_line.cursor -= el->el_state.argument;
505 if (el->el_line.cursor < el->el_line.buffer)
506 el->el_line.cursor = el->el_line.buffer;
507 return (CC_REFRESH);
508}
This page took 0.042784 seconds and 5 git commands to generate.