1
/* $NetBSD: emacs.c,v 1.20 2005/08/08 14:05:37 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.20 2005/08/08 14:05:37 christos Exp $");
42
#endif /* not lint && not SCCSID */
45
* emacs.c: Emacs functions
49
/* em_delete_or_list():
50
* Delete character under cursor or list completions if at end of line
55
em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
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_overwrite(el, STReof, 4); /* then do an EOF */
67
* Here we could list completions, but it is an
74
if (el->el_state.doingarg)
75
c_delafter(el, el->el_state.argument);
78
if (el->el_line.cursor > el->el_line.lastchar)
79
el->el_line.cursor = el->el_line.lastchar;
86
/* em_delete_next_word():
87
* Cut from cursor to end of current word
92
em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
96
if (el->el_line.cursor == el->el_line.lastchar)
99
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
100
el->el_state.argument, ce__isword);
102
for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
105
el->el_chared.c_kill.last = kp;
107
c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
108
if (el->el_line.cursor > el->el_line.lastchar)
109
el->el_line.cursor = el->el_line.lastchar;
116
* Paste cut buffer at cursor position
119
protected el_action_t
121
em_yank(EditLine *el, int c __attribute__((__unused__)))
125
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
128
if (el->el_line.lastchar +
129
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
133
el->el_chared.c_kill.mark = el->el_line.cursor;
134
cp = el->el_line.cursor;
136
/* open the space, */
137
c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
139
for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
142
/* if an arg, cursor at beginning else cursor at end */
143
if (el->el_state.argument == 1)
144
el->el_line.cursor = cp;
151
* Cut the entire line and save in cut buffer
154
protected el_action_t
156
em_kill_line(EditLine *el, int c __attribute__((__unused__)))
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;
173
* Cut area between mark and cursor and save in cut buffer
176
protected el_action_t
178
em_kill_region(EditLine *el, int c __attribute__((__unused__)))
182
if (!el->el_chared.c_kill.mark)
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, 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, cp - el->el_chared.c_kill.mark);
199
el->el_line.cursor = el->el_chared.c_kill.mark;
206
* Copy area between mark and cursor to cut buffer
209
protected el_action_t
211
em_copy_region(EditLine *el, int c __attribute__((__unused__)))
215
if (!el->el_chared.c_kill.mark)
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;
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;
235
/* em_gosmacs_transpose():
236
* Exchange the two characters before the cursor
237
* Gosling emacs transpose chars [^T]
239
protected el_action_t
240
em_gosmacs_transpose(EditLine *el, int c)
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;
255
* Move next to end of current word
258
protected el_action_t
260
em_next_word(EditLine *el, int c __attribute__((__unused__)))
262
if (el->el_line.cursor == el->el_line.lastchar)
265
el->el_line.cursor = c__next_word(el->el_line.cursor,
266
el->el_line.lastchar,
267
el->el_state.argument,
270
if (el->el_map.type == MAP_VI)
271
if (el->el_chared.c_vcmd.action != NOP) {
280
* Uppercase the characters from cursor to end of current word
283
protected el_action_t
285
em_upper_case(EditLine *el, int c __attribute__((__unused__)))
289
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
290
el->el_state.argument, ce__isword);
292
for (cp = el->el_line.cursor; cp < ep; cp++)
293
if (islower((unsigned char)*cp))
294
*cp = toupper((unsigned char)*cp);
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;
303
/* em_capitol_case():
304
* Capitalize the characters from cursor to end of current word
307
protected el_action_t
309
em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
313
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
314
el->el_state.argument, ce__isword);
316
for (cp = el->el_line.cursor; cp < ep; cp++) {
317
if (isalpha((unsigned char)*cp)) {
318
if (islower((unsigned char)*cp))
319
*cp = toupper((unsigned char)*cp);
324
for (; cp < ep; cp++)
325
if (isupper((unsigned char)*cp))
326
*cp = tolower((unsigned char)*cp);
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;
336
* Lowercase the characters from cursor to end of current word
339
protected el_action_t
341
em_lower_case(EditLine *el, int c __attribute__((__unused__)))
345
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
346
el->el_state.argument, ce__isword);
348
for (cp = el->el_line.cursor; cp < ep; cp++)
349
if (isupper((unsigned char)*cp))
350
*cp = tolower((unsigned char)*cp);
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;
360
* Set the mark at cursor
363
protected el_action_t
365
em_set_mark(EditLine *el, int c __attribute__((__unused__)))
368
el->el_chared.c_kill.mark = el->el_line.cursor;
373
/* em_exchange_mark():
374
* Exchange the cursor and mark
377
protected el_action_t
379
em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
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;
390
/* em_universal_argument():
391
* Universal argument (argument times 4)
394
protected el_action_t
396
em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
397
{ /* multiply current argument by 4 */
399
if (el->el_state.argument > 1000000)
401
el->el_state.doingarg = 1;
402
el->el_state.argument *= 4;
408
* Add 8th bit to next character typed
411
protected el_action_t
413
em_meta_next(EditLine *el, int c __attribute__((__unused__)))
416
el->el_state.metanext = 1;
421
/* em_toggle_overwrite():
422
* Switch from insert to overwrite mode or vice versa
424
protected el_action_t
426
em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
429
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
430
MODE_REPLACE : MODE_INSERT;
435
/* em_copy_prev_word():
436
* Copy current word to cursor
438
protected el_action_t
440
em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
442
char *cp, *oldc, *dp;
444
if (el->el_line.cursor == el->el_line.buffer)
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);
452
c_insert(el, oldc - cp);
453
for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
456
el->el_line.cursor = dp;/* put cursor at end */
462
/* em_inc_search_next():
463
* Emacs incremental next search
465
protected el_action_t
467
em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
470
el->el_search.patlen = 0;
471
return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
475
/* em_inc_search_prev():
476
* Emacs incremental reverse search
478
protected el_action_t
480
em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
483
el->el_search.patlen = 0;
484
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
488
/* em_delete_prev_char():
489
* Delete the character to the left of the cursor
492
protected el_action_t
494
em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
497
if (el->el_line.cursor <= el->el_line.buffer)
500
if (el->el_state.doingarg)
501
c_delbefore(el, el->el_state.argument);
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;