root/src/noitedit/emacs.c

Revision bf48400f31e06fe8d9986bb2cf8962ed979c3a85, 11.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 4 years ago)

this is backwards... I can't simluate a meta to crash it though, refs #284

  • Property mode set to 100644
Line 
1 /*      $NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek 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. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #include "noitedit/compat.h"
40 #if !defined(lint) && !defined(SCCSID)
41 #if 0
42 static char sccsid[] = "@(#)emacs.c     8.1 (Berkeley) 6/4/93";
43 #else
44 __RCSID("$NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $");
45 #endif
46 #endif /* not lint && not SCCSID */
47
48 /*
49  * emacs.c: Emacs functions
50  */
51 #include "noitedit/sys.h"
52 #include "noitedit/el.h"
53
54 /* em_delete_or_list():
55  *      Delete character under cursor or list completions if at end of line
56  *      [^D]
57  */
58 protected el_action_t
59 /*ARGSUSED*/
60 em_delete_or_list(EditLine *el, int c)
61 {
62
63         if (el->el_line.cursor == el->el_line.lastchar) {
64                                         /* if I'm at the end */
65                 if (el->el_line.cursor == el->el_line.buffer) {
66                                         /* and the beginning */
67                         term_overwrite(el, STReof, 4);  /* then do a EOF */
68                         term__flush();
69                         return (CC_EOF);
70                 } else {
71                         /*
72                          * Here we could list completions, but it is an
73                          * error right now
74                          */
75                         term_beep(el);
76                         return (CC_ERROR);
77                 }
78         } else {
79                 c_delafter(el, el->el_state.argument);  /* delete after dot */
80                 if (el->el_line.cursor > el->el_line.lastchar)
81                         el->el_line.cursor = el->el_line.lastchar;
82                                 /* bounds check */
83                 return (CC_REFRESH);
84         }
85 }
86
87
88 /* em_delete_next_word():
89  *      Cut from cursor to end of current word
90  *      [M-d]
91  */
92 protected el_action_t
93 /*ARGSUSED*/
94 em_delete_next_word(EditLine *el, int c)
95 {
96         char *cp, *p, *kp;
97
98         if (el->el_line.cursor == el->el_line.lastchar)
99                 return (CC_ERROR);
100
101         cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
102             el->el_state.argument, ce__isword);
103
104         for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
105                                 /* save the text */
106                 *kp++ = *p;
107         el->el_chared.c_kill.last = kp;
108
109         c_delafter(el, cp - el->el_line.cursor);        /* delete after dot */
110         if (el->el_line.cursor > el->el_line.lastchar)
111                 el->el_line.cursor = el->el_line.lastchar;
112                                 /* bounds check */
113         return (CC_REFRESH);
114 }
115
116
117 /* em_yank():
118  *      Paste cut buffer at cursor position
119  *      [^Y]
120  */
121 protected el_action_t
122 /*ARGSUSED*/
123 em_yank(EditLine *el, int c)
124 {
125         char *kp, *cp;
126
127         if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
128                 if (!ch_enlargebufs(el, 1))
129                         return (CC_ERROR);
130         }
131
132         if (el->el_line.lastchar +
133             (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
134             el->el_line.limit)
135                 return (CC_ERROR);
136
137         el->el_chared.c_kill.mark = el->el_line.cursor;
138         cp = el->el_line.cursor;
139
140         /* open the space, */
141         c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
142         /* copy the chars */
143         for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
144                 *cp++ = *kp;
145
146         /* if an arg, cursor at beginning else cursor at end */
147         if (el->el_state.argument == 1)
148                 el->el_line.cursor = cp;
149
150         return (CC_REFRESH);
151 }
152
153
154 /* em_kill_line():
155  *      Cut the entire line and save in cut buffer
156  *      [^U]
157  */
158 protected el_action_t
159 /*ARGSUSED*/
160 em_kill_line(EditLine *el, int c)
161 {
162         char *kp, *cp;
163
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;
172         return (CC_REFRESH);
173 }
174
175
176 /* em_kill_region():
177  *      Cut area between mark and cursor and save in cut buffer
178  *      [^W]
179  */
180 protected el_action_t
181 /*ARGSUSED*/
182 em_kill_region(EditLine *el, int c)
183 {
184         char *kp, *cp;
185
186         if (!el->el_chared.c_kill.mark)
187                 return (CC_ERROR);
188
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, 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, cp - el->el_chared.c_kill.mark);
203                 el->el_line.cursor = el->el_chared.c_kill.mark;
204         }
205         return (CC_REFRESH);
206 }
207
208
209 /* em_copy_region():
210  *      Copy area between mark and cursor to cut buffer
211  *      [M-W]
212  */
213 protected el_action_t
214 /*ARGSUSED*/
215 em_copy_region(EditLine *el, int c)
216 {
217         char *kp, *cp;
218
219         if (!el->el_chared.c_kill.mark)
220                 return (CC_ERROR);
221
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;
228         } else {
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;
234         }
235         return (CC_NORM);
236 }
237
238
239 /* em_gosmacs_traspose():
240  *      Exchange the two characters before the cursor
241  *      Gosling emacs transpose chars [^T]
242  */
243 protected el_action_t
244 em_gosmacs_traspose(EditLine *el, int c)
245 {
246
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;
252                 return (CC_REFRESH);
253         } else
254                 return (CC_ERROR);
255 }
256
257
258 /* em_next_word():
259  *      Move next to end of current word
260  *      [M-f]
261  */
262 protected el_action_t
263 /*ARGSUSED*/
264 em_next_word(EditLine *el, int c)
265 {
266         if (el->el_line.cursor == el->el_line.lastchar)
267                 return (CC_ERROR);
268
269         el->el_line.cursor = c__next_word(el->el_line.cursor,
270             el->el_line.lastchar,
271             el->el_state.argument,
272             ce__isword);
273
274         if (el->el_map.type == MAP_VI)
275                 if (el->el_chared.c_vcmd.action & DELETE) {
276                         cv_delfini(el);
277                         return (CC_REFRESH);
278                 }
279         return (CC_CURSOR);
280 }
281
282
283 /* em_upper_case():
284  *      Uppercase the characters from cursor to end of current word
285  *      [M-u]
286  */
287 protected el_action_t
288 /*ARGSUSED*/
289 em_upper_case(EditLine *el, int c)
290 {
291         char *cp, *ep;
292
293         ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
294             el->el_state.argument, ce__isword);
295
296         for (cp = el->el_line.cursor; cp < ep; cp++)
297                 if (islower((unsigned char) *cp))
298                         *cp = toupper(*cp);
299
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;
303         return (CC_REFRESH);
304 }
305
306
307 /* em_capitol_case():
308  *      Capitalize the characters from cursor to end of current word
309  *      [M-c]
310  */
311 protected el_action_t
312 /*ARGSUSED*/
313 em_capitol_case(EditLine *el, int c)
314 {
315         char *cp, *ep;
316
317         ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
318             el->el_state.argument, ce__isword);
319
320         for (cp = el->el_line.cursor; cp < ep; cp++) {
321                 if (isalpha((unsigned char) *cp)) {
322                         if (islower((unsigned char) *cp))
323                                 *cp = toupper(*cp);
324                         cp++;
325                         break;
326                 }
327         }
328         for (; cp < ep; cp++)
329                 if (isupper((unsigned char) *cp))
330                         *cp = tolower(*cp);
331
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;
335         return (CC_REFRESH);
336 }
337
338
339 /* em_lower_case():
340  *      Lowercase the characters from cursor to end of current word
341  *      [M-l]
342  */
343 protected el_action_t
344 /*ARGSUSED*/
345 em_lower_case(EditLine *el, int c)
346 {
347         char *cp, *ep;
348
349         ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
350             el->el_state.argument, ce__isword);
351
352         for (cp = el->el_line.cursor; cp < ep; cp++)
353                 if (isupper((unsigned char) *cp))
354                         *cp = tolower(*cp);
355
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;
359         return (CC_REFRESH);
360 }
361
362
363 /* em_set_mark():
364  *      Set the mark at cursor
365  *      [^@]
366  */
367 protected el_action_t
368 /*ARGSUSED*/
369 em_set_mark(EditLine *el, int c)
370 {
371
372         el->el_chared.c_kill.mark = el->el_line.cursor;
373         return (CC_NORM);
374 }
375
376
377 /* em_exchange_mark():
378  *      Exchange the cursor and mark
379  *      [^X^X]
380  */
381 protected el_action_t
382 /*ARGSUSED*/
383 em_exchange_mark(EditLine *el, int c)
384 {
385         char *cp;
386
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;
390         return (CC_CURSOR);
391 }
392
393
394 /* em_universal_argument():
395  *      Universal argument (argument times 4)
396  *      [^U]
397  */
398 protected el_action_t
399 /*ARGSUSED*/
400 em_universal_argument(EditLine *el, int c)
401 {                               /* multiply current argument by 4 */
402
403         if (el->el_state.argument > 1000000)
404                 return (CC_ERROR);
405         el->el_state.doingarg = 1;
406         el->el_state.argument *= 4;
407         return (CC_ARGHACK);
408 }
409
410
411 /* em_meta_next():
412  *      Add 8th bit to next character typed
413  *      [<ESC>]
414  */
415 protected el_action_t
416 /*ARGSUSED*/
417 em_meta_next(EditLine *el, int c)
418 {
419
420         el->el_state.metanext = 1;
421         return (CC_ARGHACK);
422 }
423
424
425 /* em_toggle_overwrite():
426  *      Switch from insert to overwrite mode or vice versa
427  */
428 protected el_action_t
429 /*ARGSUSED*/
430 em_toggle_overwrite(EditLine *el, int c)
431 {
432
433         el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
434             MODE_REPLACE : MODE_INSERT;
435         return (CC_NORM);
436 }
437
438
439 /* em_copy_prev_word():
440  *      Copy current word to cursor
441  */
442 protected el_action_t
443 /*ARGSUSED*/
444 em_copy_prev_word(EditLine *el, int c)
445 {
446         char *cp, *oldc, *dp;
447
448         if (el->el_line.cursor == el->el_line.buffer)
449                 return (CC_ERROR);
450
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);
455
456         c_insert(el, oldc - cp);
457         for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
458                 *dp++ = *cp;
459
460         el->el_line.cursor = dp;/* put cursor at end */
461
462         return (CC_REFRESH);
463 }
464
465
466 /* em_inc_search_next():
467  *      Emacs incremental next search
468  */
469 protected el_action_t
470 /*ARGSUSED*/
471 em_inc_search_next(EditLine *el, int c)
472 {
473
474         el->el_search.patlen = 0;
475         return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
476 }
477
478
479 /* em_inc_search_prev():
480  *      Emacs incremental reverse search
481  */
482 protected el_action_t
483 /*ARGSUSED*/
484 em_inc_search_prev(EditLine *el, int c)
485 {
486
487         el->el_search.patlen = 0;
488         return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
489 }
Note: See TracBrowser for help on using the browser.