1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
7 *
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. 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.
23 *
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
34 * SUCH DAMAGE.
35 *
36 * $NetBSD: emacs.c,v 1.8 2000/09/04 22:06:29 lukem Exp $
37 */
38
39#if !defined(lint) && !defined(SCCSID)
40static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
41#endif /* not lint && not SCCSID */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/lib/libedit/emacs.c 108533 2003-01-01 18:49:04Z schweikh $");
44
45/*
46 * emacs.c: Emacs functions
47 */
48#include "sys.h"
49#include "el.h"
50
51/* em_delete_or_list():
52 * Delete character under cursor or list completions if at end of line
53 * [^D]
54 */
55protected el_action_t
56/*ARGSUSED*/
57em_delete_or_list(EditLine *el, int c)
58{
59
60 if (el->el_line.cursor == el->el_line.lastchar) {
61 /* if I'm at the end */
62 if (el->el_line.cursor == el->el_line.buffer) {
63 /* and the beginning */
64 term_overwrite(el, STReof, 4); /* then do an EOF */
65 term__flush();
66 return (CC_EOF);
67 } else {
68 /*
69 * Here we could list completions, but it is an
70 * error right now
71 */
72 term_beep(el);
73 return (CC_ERROR);
74 }
75 } else {
76 c_delafter(el, el->el_state.argument); /* delete after dot */
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)
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, 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)
121{
122 char *kp, *cp;
123
124 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
125 if (!ch_enlargebufs(el, 1))
126 return (CC_ERROR);
127 }
128
129 if (el->el_line.lastchar +
130 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
131 el->el_line.limit)
132 return (CC_ERROR);
133
134 el->el_chared.c_kill.mark = el->el_line.cursor;
135 cp = el->el_line.cursor;
136
137 /* open the space, */
138 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
139 /* copy the chars */
140 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
141 *cp++ = *kp;
142
143 /* if an arg, cursor at beginning else cursor at end */
144 if (el->el_state.argument == 1)
145 el->el_line.cursor = cp;
146
147 return (CC_REFRESH);
148}
149
150
151/* em_kill_line():
152 * Cut the entire line and save in cut buffer
153 * [^U]
154 */
155protected el_action_t
156/*ARGSUSED*/
157em_kill_line(EditLine *el, int c)
158{
159 char *kp, *cp;
160
161 cp = el->el_line.buffer;
162 kp = el->el_chared.c_kill.buf;
163 while (cp < el->el_line.lastchar)
164 *kp++ = *cp++; /* copy it */
165 el->el_chared.c_kill.last = kp;
166 /* zap! -- delete all of it */
167 el->el_line.lastchar = el->el_line.buffer;
168 el->el_line.cursor = el->el_line.buffer;
169 return (CC_REFRESH);
170}
171
172
173/* em_kill_region():
174 * Cut area between mark and cursor and save in cut buffer
175 * [^W]
176 */
177protected el_action_t
178/*ARGSUSED*/
179em_kill_region(EditLine *el, int c)
180{
181 char *kp, *cp;
182
183 if (!el->el_chared.c_kill.mark)
184 return (CC_ERROR);
185
186 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
187 cp = el->el_line.cursor;
188 kp = el->el_chared.c_kill.buf;
189 while (cp < el->el_chared.c_kill.mark)
190 *kp++ = *cp++; /* copy it */
191 el->el_chared.c_kill.last = kp;
192 c_delafter(el, cp - el->el_line.cursor);
193 } else { /* mark is before cursor */
194 cp = el->el_chared.c_kill.mark;
195 kp = el->el_chared.c_kill.buf;
196 while (cp < el->el_line.cursor)
197 *kp++ = *cp++; /* copy it */
198 el->el_chared.c_kill.last = kp;
199 c_delbefore(el, cp - el->el_chared.c_kill.mark);
200 el->el_line.cursor = el->el_chared.c_kill.mark;
201 }
202 return (CC_REFRESH);
203}
204
205
206/* em_copy_region():
207 * Copy area between mark and cursor to cut buffer
208 * [M-W]
209 */
210protected el_action_t
211/*ARGSUSED*/
212em_copy_region(EditLine *el, int c)
213{
214 char *kp, *cp;
215
216 if (el->el_chared.c_kill.mark)
217 return (CC_ERROR);
218
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;
225 } else {
226 cp = el->el_chared.c_kill.mark;
227 kp = el->el_chared.c_kill.buf;
228 while (cp < el->el_line.cursor)
229 *kp++ = *cp++; /* copy it */
230 el->el_chared.c_kill.last = kp;
231 }
232 return (CC_NORM);
233}
234
235
236/* em_gosmacs_traspose():
237 * Exchange the two characters before the cursor
238 * Gosling emacs transpose chars [^T]
239 */
240protected el_action_t
241em_gosmacs_traspose(EditLine *el, int c)
242{
243
244 if (el->el_line.cursor > &el->el_line.buffer[1]) {
245 /* must have at least two chars entered */
246 c = el->el_line.cursor[-2];
247 el->el_line.cursor[-2] = el->el_line.cursor[-1];
248 el->el_line.cursor[-1] = c;
249 return (CC_REFRESH);
250 } else
251 return (CC_ERROR);
252}
253
254
255/* em_next_word():
256 * Move next to end of current word
257 * [M-f]
258 */
259protected el_action_t
260/*ARGSUSED*/
261em_next_word(EditLine *el, int c)
262{
263 if (el->el_line.cursor == el->el_line.lastchar)
264 return (CC_ERROR);
265
266 el->el_line.cursor = c__next_word(el->el_line.cursor,
267 el->el_line.lastchar,
268 el->el_state.argument,
269 ce__isword);
270
271 if (el->el_map.type == MAP_VI)
272 if (el->el_chared.c_vcmd.action & DELETE) {
273 cv_delfini(el);
274 return (CC_REFRESH);
275 }
276 return (CC_CURSOR);
277}
278
279
280/* em_upper_case():
281 * Uppercase the characters from cursor to end of current word
282 * [M-u]
283 */
284protected el_action_t
285/*ARGSUSED*/
286em_upper_case(EditLine *el, int c)
287{
288 char *cp, *ep;
289
290 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
291 el->el_state.argument, ce__isword);
292
293 for (cp = el->el_line.cursor; cp < ep; cp++)
294 if (islower((unsigned char) *cp))
295 *cp = toupper((unsigned char) *cp);
296
297 el->el_line.cursor = ep;
298 if (el->el_line.cursor > el->el_line.lastchar)
299 el->el_line.cursor = el->el_line.lastchar;
300 return (CC_REFRESH);
301}
302
303
304/* em_capitol_case():
305 * Capitalize the characters from cursor to end of current word
306 * [M-c]
307 */
308protected el_action_t
309/*ARGSUSED*/
310em_capitol_case(EditLine *el, int c)
311{
312 char *cp, *ep;
313
314 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
315 el->el_state.argument, ce__isword);
316
317 for (cp = el->el_line.cursor; cp < ep; cp++) {
318 if (isalpha((unsigned char) *cp)) {
319 if (islower((unsigned char) *cp))
320 *cp = toupper((unsigned char) *cp);
321 cp++;
322 break;
323 }
324 }
325 for (; cp < ep; cp++)
326 if (isupper((unsigned char) *cp))
327 *cp = tolower((unsigned char) *cp);
328
329 el->el_line.cursor = ep;
330 if (el->el_line.cursor > el->el_line.lastchar)
331 el->el_line.cursor = el->el_line.lastchar;
332 return (CC_REFRESH);
333}
334
335
336/* em_lower_case():
337 * Lowercase the characters from cursor to end of current word
338 * [M-l]
339 */
340protected el_action_t
341/*ARGSUSED*/
342em_lower_case(EditLine *el, int c)
343{
344 char *cp, *ep;
345
346 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
347 el->el_state.argument, ce__isword);
348
349 for (cp = el->el_line.cursor; cp < ep; cp++)
350 if (isupper((unsigned char) *cp))
351 *cp = tolower((unsigned char) *cp);
352
353 el->el_line.cursor = ep;
354 if (el->el_line.cursor > el->el_line.lastchar)
355 el->el_line.cursor = el->el_line.lastchar;
356 return (CC_REFRESH);
357}
358
359
360/* em_set_mark():
361 * Set the mark at cursor
362 * [^@]
363 */
364protected el_action_t
365/*ARGSUSED*/
366em_set_mark(EditLine *el, int c)
367{
368
369 el->el_chared.c_kill.mark = el->el_line.cursor;
370 return (CC_NORM);
371}
372
373
374/* em_exchange_mark():
375 * Exchange the cursor and mark
376 * [^X^X]
377 */
378protected el_action_t
379/*ARGSUSED*/
380em_exchange_mark(EditLine *el, int c)
381{
382 char *cp;
383
384 cp = el->el_line.cursor;
385 el->el_line.cursor = el->el_chared.c_kill.mark;
386 el->el_chared.c_kill.mark = cp;
387 return (CC_CURSOR);
388}
389
390
391/* em_universal_argument():
392 * Universal argument (argument times 4)
393 * [^U]
394 */
395protected el_action_t
396/*ARGSUSED*/
397em_universal_argument(EditLine *el, int c)
398{ /* multiply current argument by 4 */
399
400 if (el->el_state.argument > 1000000)
401 return (CC_ERROR);
402 el->el_state.doingarg = 1;
403 el->el_state.argument *= 4;
404 return (CC_ARGHACK);
405}
406
407
408/* em_meta_next():
409 * Add 8th bit to next character typed
410 * [<ESC>]
411 */
412protected el_action_t
413/*ARGSUSED*/
414em_meta_next(EditLine *el, int c)
415{
416
417 el->el_state.metanext = 1;
418 return (CC_ARGHACK);
419}
420
421
422/* em_toggle_overwrite():
423 * Switch from insert to overwrite mode or vice versa
424 */
425protected el_action_t
426/*ARGSUSED*/
427em_toggle_overwrite(EditLine *el, int c)
428{
429
430 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
431 MODE_REPLACE : MODE_INSERT;
432 return (CC_NORM);
433}
434
435
436/* em_copy_prev_word():
437 * Copy current word to cursor
438 */
439protected el_action_t
440/*ARGSUSED*/
441em_copy_prev_word(EditLine *el, int c)
442{
443 char *cp, *oldc, *dp;
444
445 if (el->el_line.cursor == el->el_line.buffer)
446 return (CC_ERROR);
447
448 oldc = el->el_line.cursor;
449 /* does a bounds check */
450 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
451 el->el_state.argument, ce__isword);
452
453 c_insert(el, oldc - cp);
454 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
455 *dp++ = *cp;
456
457 el->el_line.cursor = dp;/* put cursor at end */
458
459 return (CC_REFRESH);
460}
461
462
463/* em_inc_search_next():
464 * Emacs incremental next search
465 */
466protected el_action_t
467/*ARGSUSED*/
468em_inc_search_next(EditLine *el, int c)
469{
470
471 el->el_search.patlen = 0;
472 return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
473}
474
475
476/* em_inc_search_prev():
477 * Emacs incremental reverse search
478 */
479protected el_action_t
480/*ARGSUSED*/
481em_inc_search_prev(EditLine *el, int c)
482{
483
484 el->el_search.patlen = 0;
485 return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
486}
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
7 *
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. 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.
23 *
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
34 * SUCH DAMAGE.
35 *
36 * $NetBSD: emacs.c,v 1.8 2000/09/04 22:06:29 lukem Exp $
37 */
38
39#if !defined(lint) && !defined(SCCSID)
40static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
41#endif /* not lint && not SCCSID */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/lib/libedit/emacs.c 108533 2003-01-01 18:49:04Z schweikh $");
44
45/*
46 * emacs.c: Emacs functions
47 */
48#include "sys.h"
49#include "el.h"
50
51/* em_delete_or_list():
52 * Delete character under cursor or list completions if at end of line
53 * [^D]
54 */
55protected el_action_t
56/*ARGSUSED*/
57em_delete_or_list(EditLine *el, int c)
58{
59
60 if (el->el_line.cursor == el->el_line.lastchar) {
61 /* if I'm at the end */
62 if (el->el_line.cursor == el->el_line.buffer) {
63 /* and the beginning */
64 term_overwrite(el, STReof, 4); /* then do an EOF */
65 term__flush();
66 return (CC_EOF);
67 } else {
68 /*
69 * Here we could list completions, but it is an
70 * error right now
71 */
72 term_beep(el);
73 return (CC_ERROR);
74 }
75 } else {
76 c_delafter(el, el->el_state.argument); /* delete after dot */
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)
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, 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)
121{
122 char *kp, *cp;
123
124 if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
125 if (!ch_enlargebufs(el, 1))
126 return (CC_ERROR);
127 }
128
129 if (el->el_line.lastchar +
130 (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
131 el->el_line.limit)
132 return (CC_ERROR);
133
134 el->el_chared.c_kill.mark = el->el_line.cursor;
135 cp = el->el_line.cursor;
136
137 /* open the space, */
138 c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
139 /* copy the chars */
140 for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
141 *cp++ = *kp;
142
143 /* if an arg, cursor at beginning else cursor at end */
144 if (el->el_state.argument == 1)
145 el->el_line.cursor = cp;
146
147 return (CC_REFRESH);
148}
149
150
151/* em_kill_line():
152 * Cut the entire line and save in cut buffer
153 * [^U]
154 */
155protected el_action_t
156/*ARGSUSED*/
157em_kill_line(EditLine *el, int c)
158{
159 char *kp, *cp;
160
161 cp = el->el_line.buffer;
162 kp = el->el_chared.c_kill.buf;
163 while (cp < el->el_line.lastchar)
164 *kp++ = *cp++; /* copy it */
165 el->el_chared.c_kill.last = kp;
166 /* zap! -- delete all of it */
167 el->el_line.lastchar = el->el_line.buffer;
168 el->el_line.cursor = el->el_line.buffer;
169 return (CC_REFRESH);
170}
171
172
173/* em_kill_region():
174 * Cut area between mark and cursor and save in cut buffer
175 * [^W]
176 */
177protected el_action_t
178/*ARGSUSED*/
179em_kill_region(EditLine *el, int c)
180{
181 char *kp, *cp;
182
183 if (!el->el_chared.c_kill.mark)
184 return (CC_ERROR);
185
186 if (el->el_chared.c_kill.mark > el->el_line.cursor) {
187 cp = el->el_line.cursor;
188 kp = el->el_chared.c_kill.buf;
189 while (cp < el->el_chared.c_kill.mark)
190 *kp++ = *cp++; /* copy it */
191 el->el_chared.c_kill.last = kp;
192 c_delafter(el, cp - el->el_line.cursor);
193 } else { /* mark is before cursor */
194 cp = el->el_chared.c_kill.mark;
195 kp = el->el_chared.c_kill.buf;
196 while (cp < el->el_line.cursor)
197 *kp++ = *cp++; /* copy it */
198 el->el_chared.c_kill.last = kp;
199 c_delbefore(el, cp - el->el_chared.c_kill.mark);
200 el->el_line.cursor = el->el_chared.c_kill.mark;
201 }
202 return (CC_REFRESH);
203}
204
205
206/* em_copy_region():
207 * Copy area between mark and cursor to cut buffer
208 * [M-W]
209 */
210protected el_action_t
211/*ARGSUSED*/
212em_copy_region(EditLine *el, int c)
213{
214 char *kp, *cp;
215
216 if (el->el_chared.c_kill.mark)
217 return (CC_ERROR);
218
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;
225 } else {
226 cp = el->el_chared.c_kill.mark;
227 kp = el->el_chared.c_kill.buf;
228 while (cp < el->el_line.cursor)
229 *kp++ = *cp++; /* copy it */
230 el->el_chared.c_kill.last = kp;
231 }
232 return (CC_NORM);
233}
234
235
236/* em_gosmacs_traspose():
237 * Exchange the two characters before the cursor
238 * Gosling emacs transpose chars [^T]
239 */
240protected el_action_t
241em_gosmacs_traspose(EditLine *el, int c)
242{
243
244 if (el->el_line.cursor > &el->el_line.buffer[1]) {
245 /* must have at least two chars entered */
246 c = el->el_line.cursor[-2];
247 el->el_line.cursor[-2] = el->el_line.cursor[-1];
248 el->el_line.cursor[-1] = c;
249 return (CC_REFRESH);
250 } else
251 return (CC_ERROR);
252}
253
254
255/* em_next_word():
256 * Move next to end of current word
257 * [M-f]
258 */
259protected el_action_t
260/*ARGSUSED*/
261em_next_word(EditLine *el, int c)
262{
263 if (el->el_line.cursor == el->el_line.lastchar)
264 return (CC_ERROR);
265
266 el->el_line.cursor = c__next_word(el->el_line.cursor,
267 el->el_line.lastchar,
268 el->el_state.argument,
269 ce__isword);
270
271 if (el->el_map.type == MAP_VI)
272 if (el->el_chared.c_vcmd.action & DELETE) {
273 cv_delfini(el);
274 return (CC_REFRESH);
275 }
276 return (CC_CURSOR);
277}
278
279
280/* em_upper_case():
281 * Uppercase the characters from cursor to end of current word
282 * [M-u]
283 */
284protected el_action_t
285/*ARGSUSED*/
286em_upper_case(EditLine *el, int c)
287{
288 char *cp, *ep;
289
290 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
291 el->el_state.argument, ce__isword);
292
293 for (cp = el->el_line.cursor; cp < ep; cp++)
294 if (islower((unsigned char) *cp))
295 *cp = toupper((unsigned char) *cp);
296
297 el->el_line.cursor = ep;
298 if (el->el_line.cursor > el->el_line.lastchar)
299 el->el_line.cursor = el->el_line.lastchar;
300 return (CC_REFRESH);
301}
302
303
304/* em_capitol_case():
305 * Capitalize the characters from cursor to end of current word
306 * [M-c]
307 */
308protected el_action_t
309/*ARGSUSED*/
310em_capitol_case(EditLine *el, int c)
311{
312 char *cp, *ep;
313
314 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
315 el->el_state.argument, ce__isword);
316
317 for (cp = el->el_line.cursor; cp < ep; cp++) {
318 if (isalpha((unsigned char) *cp)) {
319 if (islower((unsigned char) *cp))
320 *cp = toupper((unsigned char) *cp);
321 cp++;
322 break;
323 }
324 }
325 for (; cp < ep; cp++)
326 if (isupper((unsigned char) *cp))
327 *cp = tolower((unsigned char) *cp);
328
329 el->el_line.cursor = ep;
330 if (el->el_line.cursor > el->el_line.lastchar)
331 el->el_line.cursor = el->el_line.lastchar;
332 return (CC_REFRESH);
333}
334
335
336/* em_lower_case():
337 * Lowercase the characters from cursor to end of current word
338 * [M-l]
339 */
340protected el_action_t
341/*ARGSUSED*/
342em_lower_case(EditLine *el, int c)
343{
344 char *cp, *ep;
345
346 ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
347 el->el_state.argument, ce__isword);
348
349 for (cp = el->el_line.cursor; cp < ep; cp++)
350 if (isupper((unsigned char) *cp))
351 *cp = tolower((unsigned char) *cp);
352
353 el->el_line.cursor = ep;
354 if (el->el_line.cursor > el->el_line.lastchar)
355 el->el_line.cursor = el->el_line.lastchar;
356 return (CC_REFRESH);
357}
358
359
360/* em_set_mark():
361 * Set the mark at cursor
362 * [^@]
363 */
364protected el_action_t
365/*ARGSUSED*/
366em_set_mark(EditLine *el, int c)
367{
368
369 el->el_chared.c_kill.mark = el->el_line.cursor;
370 return (CC_NORM);
371}
372
373
374/* em_exchange_mark():
375 * Exchange the cursor and mark
376 * [^X^X]
377 */
378protected el_action_t
379/*ARGSUSED*/
380em_exchange_mark(EditLine *el, int c)
381{
382 char *cp;
383
384 cp = el->el_line.cursor;
385 el->el_line.cursor = el->el_chared.c_kill.mark;
386 el->el_chared.c_kill.mark = cp;
387 return (CC_CURSOR);
388}
389
390
391/* em_universal_argument():
392 * Universal argument (argument times 4)
393 * [^U]
394 */
395protected el_action_t
396/*ARGSUSED*/
397em_universal_argument(EditLine *el, int c)
398{ /* multiply current argument by 4 */
399
400 if (el->el_state.argument > 1000000)
401 return (CC_ERROR);
402 el->el_state.doingarg = 1;
403 el->el_state.argument *= 4;
404 return (CC_ARGHACK);
405}
406
407
408/* em_meta_next():
409 * Add 8th bit to next character typed
410 * [<ESC>]
411 */
412protected el_action_t
413/*ARGSUSED*/
414em_meta_next(EditLine *el, int c)
415{
416
417 el->el_state.metanext = 1;
418 return (CC_ARGHACK);
419}
420
421
422/* em_toggle_overwrite():
423 * Switch from insert to overwrite mode or vice versa
424 */
425protected el_action_t
426/*ARGSUSED*/
427em_toggle_overwrite(EditLine *el, int c)
428{
429
430 el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
431 MODE_REPLACE : MODE_INSERT;
432 return (CC_NORM);
433}
434
435
436/* em_copy_prev_word():
437 * Copy current word to cursor
438 */
439protected el_action_t
440/*ARGSUSED*/
441em_copy_prev_word(EditLine *el, int c)
442{
443 char *cp, *oldc, *dp;
444
445 if (el->el_line.cursor == el->el_line.buffer)
446 return (CC_ERROR);
447
448 oldc = el->el_line.cursor;
449 /* does a bounds check */
450 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
451 el->el_state.argument, ce__isword);
452
453 c_insert(el, oldc - cp);
454 for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
455 *dp++ = *cp;
456
457 el->el_line.cursor = dp;/* put cursor at end */
458
459 return (CC_REFRESH);
460}
461
462
463/* em_inc_search_next():
464 * Emacs incremental next search
465 */
466protected el_action_t
467/*ARGSUSED*/
468em_inc_search_next(EditLine *el, int c)
469{
470
471 el->el_search.patlen = 0;
472 return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
473}
474
475
476/* em_inc_search_prev():
477 * Emacs incremental reverse search
478 */
479protected el_action_t
480/*ARGSUSED*/
481em_inc_search_prev(EditLine *el, int c)
482{
483
484 el->el_search.patlen = 0;
485 return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
486}