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