vi.c revision 1.38 1 1.38 christos /* $NetBSD: vi.c,v 1.38 2011/07/29 20:58:07 christos Exp $ */
2 1.2 lukem
3 1.1 cgd /*-
4 1.1 cgd * Copyright (c) 1992, 1993
5 1.1 cgd * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * This code is derived from software contributed to Berkeley by
8 1.1 cgd * Christos Zoulas of Cornell University.
9 1.1 cgd *
10 1.1 cgd * Redistribution and use in source and binary forms, with or without
11 1.1 cgd * modification, are permitted provided that the following conditions
12 1.1 cgd * are met:
13 1.1 cgd * 1. Redistributions of source code must retain the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer.
15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cgd * notice, this list of conditions and the following disclaimer in the
17 1.1 cgd * documentation and/or other materials provided with the distribution.
18 1.19 agc * 3. Neither the name of the University nor the names of its contributors
19 1.1 cgd * may be used to endorse or promote products derived from this software
20 1.1 cgd * without specific prior written permission.
21 1.1 cgd *
22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 1.1 cgd * SUCH DAMAGE.
33 1.1 cgd */
34 1.1 cgd
35 1.9 christos #include "config.h"
36 1.12 christos #include <stdlib.h>
37 1.12 christos #include <unistd.h>
38 1.31 christos #include <limits.h>
39 1.12 christos #include <sys/wait.h>
40 1.12 christos
41 1.1 cgd #if !defined(lint) && !defined(SCCSID)
42 1.2 lukem #if 0
43 1.1 cgd static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
44 1.2 lukem #else
45 1.38 christos __RCSID("$NetBSD: vi.c,v 1.38 2011/07/29 20:58:07 christos Exp $");
46 1.2 lukem #endif
47 1.1 cgd #endif /* not lint && not SCCSID */
48 1.1 cgd
49 1.1 cgd /*
50 1.1 cgd * vi.c: Vi mode commands.
51 1.1 cgd */
52 1.1 cgd #include "el.h"
53 1.1 cgd
54 1.31 christos private el_action_t cv_action(EditLine *, Int);
55 1.31 christos private el_action_t cv_paste(EditLine *, Int);
56 1.1 cgd
57 1.1 cgd /* cv_action():
58 1.1 cgd * Handle vi actions.
59 1.1 cgd */
60 1.1 cgd private el_action_t
61 1.31 christos cv_action(EditLine *el, Int c)
62 1.1 cgd {
63 1.1 cgd
64 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
65 1.12 christos /* 'cc', 'dd' and (possibly) friends */
66 1.12 christos if (c != el->el_chared.c_vcmd.action)
67 1.12 christos return CC_ERROR;
68 1.12 christos
69 1.12 christos if (!(c & YANK))
70 1.12 christos cv_undo(el);
71 1.12 christos cv_yank(el, el->el_line.buffer,
72 1.29 christos (int)(el->el_line.lastchar - el->el_line.buffer));
73 1.8 lukem el->el_chared.c_vcmd.action = NOP;
74 1.8 lukem el->el_chared.c_vcmd.pos = 0;
75 1.23 christos if (!(c & YANK)) {
76 1.23 christos el->el_line.lastchar = el->el_line.buffer;
77 1.23 christos el->el_line.cursor = el->el_line.buffer;
78 1.23 christos }
79 1.8 lukem if (c & INSERT)
80 1.8 lukem el->el_map.current = el->el_map.key;
81 1.7 simonb
82 1.37 christos return CC_REFRESH;
83 1.1 cgd }
84 1.8 lukem el->el_chared.c_vcmd.pos = el->el_line.cursor;
85 1.8 lukem el->el_chared.c_vcmd.action = c;
86 1.37 christos return CC_ARGHACK;
87 1.1 cgd }
88 1.1 cgd
89 1.1 cgd /* cv_paste():
90 1.1 cgd * Paste previous deletion before or after the cursor
91 1.1 cgd */
92 1.3 christos private el_action_t
93 1.31 christos cv_paste(EditLine *el, Int c)
94 1.1 cgd {
95 1.12 christos c_kill_t *k = &el->el_chared.c_kill;
96 1.30 christos size_t len = (size_t)(k->last - k->buf);
97 1.8 lukem
98 1.12 christos if (k->buf == NULL || len == 0)
99 1.37 christos return CC_ERROR;
100 1.1 cgd #ifdef DEBUG_PASTE
101 1.30 christos (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
102 1.1 cgd #endif
103 1.1 cgd
104 1.12 christos cv_undo(el);
105 1.10 christos
106 1.8 lukem if (!c && el->el_line.cursor < el->el_line.lastchar)
107 1.8 lukem el->el_line.cursor++;
108 1.8 lukem
109 1.30 christos c_insert(el, (int)len);
110 1.12 christos if (el->el_line.cursor + len > el->el_line.lastchar)
111 1.37 christos return CC_ERROR;
112 1.31 christos (void) memcpy(el->el_line.cursor, k->buf, len *
113 1.31 christos sizeof(*el->el_line.cursor));
114 1.24 christos
115 1.37 christos return CC_REFRESH;
116 1.1 cgd }
117 1.1 cgd
118 1.1 cgd
119 1.7 simonb /* vi_paste_next():
120 1.1 cgd * Vi paste previous deletion to the right of the cursor
121 1.1 cgd * [p]
122 1.1 cgd */
123 1.1 cgd protected el_action_t
124 1.1 cgd /*ARGSUSED*/
125 1.31 christos vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
126 1.1 cgd {
127 1.8 lukem
128 1.37 christos return cv_paste(el, 0);
129 1.1 cgd }
130 1.1 cgd
131 1.1 cgd
132 1.7 simonb /* vi_paste_prev():
133 1.1 cgd * Vi paste previous deletion to the left of the cursor
134 1.1 cgd * [P]
135 1.1 cgd */
136 1.1 cgd protected el_action_t
137 1.1 cgd /*ARGSUSED*/
138 1.31 christos vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
139 1.1 cgd {
140 1.8 lukem
141 1.37 christos return cv_paste(el, 1);
142 1.1 cgd }
143 1.1 cgd
144 1.1 cgd
145 1.10 christos /* vi_prev_big_word():
146 1.1 cgd * Vi move to the previous space delimited word
147 1.1 cgd * [B]
148 1.1 cgd */
149 1.1 cgd protected el_action_t
150 1.1 cgd /*ARGSUSED*/
151 1.31 christos vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
152 1.8 lukem {
153 1.8 lukem
154 1.8 lukem if (el->el_line.cursor == el->el_line.buffer)
155 1.37 christos return CC_ERROR;
156 1.1 cgd
157 1.10 christos el->el_line.cursor = cv_prev_word(el->el_line.cursor,
158 1.8 lukem el->el_line.buffer,
159 1.8 lukem el->el_state.argument,
160 1.10 christos cv__isWord);
161 1.8 lukem
162 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
163 1.8 lukem cv_delfini(el);
164 1.37 christos return CC_REFRESH;
165 1.8 lukem }
166 1.37 christos return CC_CURSOR;
167 1.1 cgd }
168 1.1 cgd
169 1.1 cgd
170 1.7 simonb /* vi_prev_word():
171 1.1 cgd * Vi move to the previous word
172 1.10 christos * [b]
173 1.1 cgd */
174 1.1 cgd protected el_action_t
175 1.1 cgd /*ARGSUSED*/
176 1.31 christos vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
177 1.8 lukem {
178 1.1 cgd
179 1.8 lukem if (el->el_line.cursor == el->el_line.buffer)
180 1.37 christos return CC_ERROR;
181 1.8 lukem
182 1.10 christos el->el_line.cursor = cv_prev_word(el->el_line.cursor,
183 1.8 lukem el->el_line.buffer,
184 1.8 lukem el->el_state.argument,
185 1.10 christos cv__isword);
186 1.8 lukem
187 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
188 1.8 lukem cv_delfini(el);
189 1.37 christos return CC_REFRESH;
190 1.8 lukem }
191 1.37 christos return CC_CURSOR;
192 1.1 cgd }
193 1.1 cgd
194 1.1 cgd
195 1.10 christos /* vi_next_big_word():
196 1.1 cgd * Vi move to the next space delimited word
197 1.1 cgd * [W]
198 1.1 cgd */
199 1.1 cgd protected el_action_t
200 1.1 cgd /*ARGSUSED*/
201 1.31 christos vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
202 1.8 lukem {
203 1.1 cgd
204 1.12 christos if (el->el_line.cursor >= el->el_line.lastchar - 1)
205 1.37 christos return CC_ERROR;
206 1.1 cgd
207 1.8 lukem el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
208 1.12 christos el->el_line.lastchar, el->el_state.argument, cv__isWord);
209 1.8 lukem
210 1.8 lukem if (el->el_map.type == MAP_VI)
211 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
212 1.8 lukem cv_delfini(el);
213 1.37 christos return CC_REFRESH;
214 1.8 lukem }
215 1.37 christos return CC_CURSOR;
216 1.1 cgd }
217 1.1 cgd
218 1.8 lukem
219 1.7 simonb /* vi_next_word():
220 1.1 cgd * Vi move to the next word
221 1.1 cgd * [w]
222 1.1 cgd */
223 1.1 cgd protected el_action_t
224 1.1 cgd /*ARGSUSED*/
225 1.31 christos vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
226 1.8 lukem {
227 1.1 cgd
228 1.12 christos if (el->el_line.cursor >= el->el_line.lastchar - 1)
229 1.37 christos return CC_ERROR;
230 1.1 cgd
231 1.8 lukem el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
232 1.12 christos el->el_line.lastchar, el->el_state.argument, cv__isword);
233 1.8 lukem
234 1.8 lukem if (el->el_map.type == MAP_VI)
235 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
236 1.8 lukem cv_delfini(el);
237 1.37 christos return CC_REFRESH;
238 1.8 lukem }
239 1.37 christos return CC_CURSOR;
240 1.1 cgd }
241 1.1 cgd
242 1.1 cgd
243 1.7 simonb /* vi_change_case():
244 1.1 cgd * Vi change case of character under the cursor and advance one character
245 1.1 cgd * [~]
246 1.1 cgd */
247 1.1 cgd protected el_action_t
248 1.31 christos vi_change_case(EditLine *el, Int c)
249 1.8 lukem {
250 1.10 christos int i;
251 1.10 christos
252 1.10 christos if (el->el_line.cursor >= el->el_line.lastchar)
253 1.37 christos return CC_ERROR;
254 1.12 christos cv_undo(el);
255 1.10 christos for (i = 0; i < el->el_state.argument; i++) {
256 1.8 lukem
257 1.31 christos c = *el->el_line.cursor;
258 1.31 christos if (Isupper(c))
259 1.31 christos *el->el_line.cursor = Tolower(c);
260 1.31 christos else if (Islower(c))
261 1.31 christos *el->el_line.cursor = Toupper(c);
262 1.12 christos
263 1.12 christos if (++el->el_line.cursor >= el->el_line.lastchar) {
264 1.12 christos el->el_line.cursor--;
265 1.12 christos re_fastaddc(el);
266 1.12 christos break;
267 1.12 christos }
268 1.8 lukem re_fastaddc(el);
269 1.8 lukem }
270 1.12 christos return CC_NORM;
271 1.1 cgd }
272 1.1 cgd
273 1.1 cgd
274 1.7 simonb /* vi_change_meta():
275 1.1 cgd * Vi change prefix command
276 1.1 cgd * [c]
277 1.1 cgd */
278 1.1 cgd protected el_action_t
279 1.1 cgd /*ARGSUSED*/
280 1.31 christos vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
281 1.8 lukem {
282 1.8 lukem
283 1.8 lukem /*
284 1.8 lukem * Delete with insert == change: first we delete and then we leave in
285 1.8 lukem * insert mode.
286 1.8 lukem */
287 1.37 christos return cv_action(el, DELETE | INSERT);
288 1.1 cgd }
289 1.1 cgd
290 1.1 cgd
291 1.7 simonb /* vi_insert_at_bol():
292 1.1 cgd * Vi enter insert mode at the beginning of line
293 1.1 cgd * [I]
294 1.1 cgd */
295 1.1 cgd protected el_action_t
296 1.1 cgd /*ARGSUSED*/
297 1.31 christos vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
298 1.1 cgd {
299 1.1 cgd
300 1.8 lukem el->el_line.cursor = el->el_line.buffer;
301 1.12 christos cv_undo(el);
302 1.8 lukem el->el_map.current = el->el_map.key;
303 1.37 christos return CC_CURSOR;
304 1.1 cgd }
305 1.1 cgd
306 1.1 cgd
307 1.7 simonb /* vi_replace_char():
308 1.1 cgd * Vi replace character under the cursor with the next character typed
309 1.1 cgd * [r]
310 1.1 cgd */
311 1.1 cgd protected el_action_t
312 1.1 cgd /*ARGSUSED*/
313 1.31 christos vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
314 1.8 lukem {
315 1.8 lukem
316 1.12 christos if (el->el_line.cursor >= el->el_line.lastchar)
317 1.10 christos return CC_ERROR;
318 1.10 christos
319 1.8 lukem el->el_map.current = el->el_map.key;
320 1.8 lukem el->el_state.inputmode = MODE_REPLACE_1;
321 1.12 christos cv_undo(el);
322 1.37 christos return CC_ARGHACK;
323 1.1 cgd }
324 1.1 cgd
325 1.1 cgd
326 1.7 simonb /* vi_replace_mode():
327 1.1 cgd * Vi enter replace mode
328 1.1 cgd * [R]
329 1.1 cgd */
330 1.1 cgd protected el_action_t
331 1.1 cgd /*ARGSUSED*/
332 1.31 christos vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
333 1.8 lukem {
334 1.8 lukem
335 1.8 lukem el->el_map.current = el->el_map.key;
336 1.8 lukem el->el_state.inputmode = MODE_REPLACE;
337 1.12 christos cv_undo(el);
338 1.37 christos return CC_NORM;
339 1.1 cgd }
340 1.1 cgd
341 1.1 cgd
342 1.7 simonb /* vi_substitute_char():
343 1.1 cgd * Vi replace character under the cursor and enter insert mode
344 1.10 christos * [s]
345 1.1 cgd */
346 1.1 cgd protected el_action_t
347 1.1 cgd /*ARGSUSED*/
348 1.31 christos vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
349 1.8 lukem {
350 1.8 lukem
351 1.8 lukem c_delafter(el, el->el_state.argument);
352 1.8 lukem el->el_map.current = el->el_map.key;
353 1.37 christos return CC_REFRESH;
354 1.1 cgd }
355 1.1 cgd
356 1.1 cgd
357 1.7 simonb /* vi_substitute_line():
358 1.1 cgd * Vi substitute entire line
359 1.1 cgd * [S]
360 1.1 cgd */
361 1.1 cgd protected el_action_t
362 1.1 cgd /*ARGSUSED*/
363 1.31 christos vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
364 1.8 lukem {
365 1.8 lukem
366 1.12 christos cv_undo(el);
367 1.12 christos cv_yank(el, el->el_line.buffer,
368 1.29 christos (int)(el->el_line.lastchar - el->el_line.buffer));
369 1.8 lukem (void) em_kill_line(el, 0);
370 1.8 lukem el->el_map.current = el->el_map.key;
371 1.37 christos return CC_REFRESH;
372 1.1 cgd }
373 1.1 cgd
374 1.1 cgd
375 1.7 simonb /* vi_change_to_eol():
376 1.1 cgd * Vi change to end of line
377 1.1 cgd * [C]
378 1.1 cgd */
379 1.1 cgd protected el_action_t
380 1.1 cgd /*ARGSUSED*/
381 1.31 christos vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
382 1.8 lukem {
383 1.8 lukem
384 1.12 christos cv_undo(el);
385 1.12 christos cv_yank(el, el->el_line.cursor,
386 1.29 christos (int)(el->el_line.lastchar - el->el_line.cursor));
387 1.8 lukem (void) ed_kill_line(el, 0);
388 1.8 lukem el->el_map.current = el->el_map.key;
389 1.37 christos return CC_REFRESH;
390 1.1 cgd }
391 1.1 cgd
392 1.1 cgd
393 1.1 cgd /* vi_insert():
394 1.1 cgd * Vi enter insert mode
395 1.1 cgd * [i]
396 1.1 cgd */
397 1.1 cgd protected el_action_t
398 1.1 cgd /*ARGSUSED*/
399 1.31 christos vi_insert(EditLine *el, Int c __attribute__((__unused__)))
400 1.1 cgd {
401 1.1 cgd
402 1.8 lukem el->el_map.current = el->el_map.key;
403 1.12 christos cv_undo(el);
404 1.37 christos return CC_NORM;
405 1.1 cgd }
406 1.1 cgd
407 1.1 cgd
408 1.1 cgd /* vi_add():
409 1.7 simonb * Vi enter insert mode after the cursor
410 1.1 cgd * [a]
411 1.1 cgd */
412 1.1 cgd protected el_action_t
413 1.1 cgd /*ARGSUSED*/
414 1.31 christos vi_add(EditLine *el, Int c __attribute__((__unused__)))
415 1.8 lukem {
416 1.8 lukem int ret;
417 1.8 lukem
418 1.8 lukem el->el_map.current = el->el_map.key;
419 1.8 lukem if (el->el_line.cursor < el->el_line.lastchar) {
420 1.8 lukem el->el_line.cursor++;
421 1.8 lukem if (el->el_line.cursor > el->el_line.lastchar)
422 1.8 lukem el->el_line.cursor = el->el_line.lastchar;
423 1.8 lukem ret = CC_CURSOR;
424 1.8 lukem } else
425 1.8 lukem ret = CC_NORM;
426 1.8 lukem
427 1.12 christos cv_undo(el);
428 1.1 cgd
429 1.37 christos return ret;
430 1.1 cgd }
431 1.1 cgd
432 1.1 cgd
433 1.1 cgd /* vi_add_at_eol():
434 1.1 cgd * Vi enter insert mode at end of line
435 1.1 cgd * [A]
436 1.1 cgd */
437 1.1 cgd protected el_action_t
438 1.1 cgd /*ARGSUSED*/
439 1.31 christos vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
440 1.8 lukem {
441 1.8 lukem
442 1.8 lukem el->el_map.current = el->el_map.key;
443 1.8 lukem el->el_line.cursor = el->el_line.lastchar;
444 1.12 christos cv_undo(el);
445 1.37 christos return CC_CURSOR;
446 1.1 cgd }
447 1.1 cgd
448 1.1 cgd
449 1.1 cgd /* vi_delete_meta():
450 1.7 simonb * Vi delete prefix command
451 1.1 cgd * [d]
452 1.1 cgd */
453 1.1 cgd protected el_action_t
454 1.1 cgd /*ARGSUSED*/
455 1.31 christos vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
456 1.1 cgd {
457 1.8 lukem
458 1.37 christos return cv_action(el, DELETE);
459 1.1 cgd }
460 1.1 cgd
461 1.1 cgd
462 1.10 christos /* vi_end_big_word():
463 1.7 simonb * Vi move to the end of the current space delimited word
464 1.7 simonb * [E]
465 1.1 cgd */
466 1.1 cgd protected el_action_t
467 1.1 cgd /*ARGSUSED*/
468 1.38 christos vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
469 1.8 lukem {
470 1.8 lukem
471 1.8 lukem if (el->el_line.cursor == el->el_line.lastchar)
472 1.37 christos return CC_ERROR;
473 1.1 cgd
474 1.8 lukem el->el_line.cursor = cv__endword(el->el_line.cursor,
475 1.10 christos el->el_line.lastchar, el->el_state.argument, cv__isWord);
476 1.8 lukem
477 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
478 1.8 lukem el->el_line.cursor++;
479 1.8 lukem cv_delfini(el);
480 1.37 christos return CC_REFRESH;
481 1.8 lukem }
482 1.37 christos return CC_CURSOR;
483 1.1 cgd }
484 1.1 cgd
485 1.1 cgd
486 1.10 christos /* vi_end_word():
487 1.1 cgd * Vi move to the end of the current word
488 1.1 cgd * [e]
489 1.1 cgd */
490 1.1 cgd protected el_action_t
491 1.1 cgd /*ARGSUSED*/
492 1.31 christos vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
493 1.8 lukem {
494 1.8 lukem
495 1.8 lukem if (el->el_line.cursor == el->el_line.lastchar)
496 1.37 christos return CC_ERROR;
497 1.8 lukem
498 1.8 lukem el->el_line.cursor = cv__endword(el->el_line.cursor,
499 1.10 christos el->el_line.lastchar, el->el_state.argument, cv__isword);
500 1.1 cgd
501 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
502 1.8 lukem el->el_line.cursor++;
503 1.8 lukem cv_delfini(el);
504 1.37 christos return CC_REFRESH;
505 1.8 lukem }
506 1.37 christos return CC_CURSOR;
507 1.1 cgd }
508 1.1 cgd
509 1.1 cgd
510 1.1 cgd /* vi_undo():
511 1.1 cgd * Vi undo last change
512 1.1 cgd * [u]
513 1.1 cgd */
514 1.1 cgd protected el_action_t
515 1.1 cgd /*ARGSUSED*/
516 1.31 christos vi_undo(EditLine *el, Int c __attribute__((__unused__)))
517 1.8 lukem {
518 1.10 christos c_undo_t un = el->el_chared.c_undo;
519 1.1 cgd
520 1.10 christos if (un.len == -1)
521 1.10 christos return CC_ERROR;
522 1.1 cgd
523 1.10 christos /* switch line buffer and undo buffer */
524 1.10 christos el->el_chared.c_undo.buf = el->el_line.buffer;
525 1.10 christos el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
526 1.29 christos el->el_chared.c_undo.cursor =
527 1.29 christos (int)(el->el_line.cursor - el->el_line.buffer);
528 1.10 christos el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
529 1.10 christos el->el_line.buffer = un.buf;
530 1.10 christos el->el_line.cursor = un.buf + un.cursor;
531 1.10 christos el->el_line.lastchar = un.buf + un.len;
532 1.1 cgd
533 1.37 christos return CC_REFRESH;
534 1.1 cgd }
535 1.1 cgd
536 1.1 cgd
537 1.1 cgd /* vi_command_mode():
538 1.1 cgd * Vi enter command mode (use alternative key bindings)
539 1.1 cgd * [<ESC>]
540 1.1 cgd */
541 1.1 cgd protected el_action_t
542 1.1 cgd /*ARGSUSED*/
543 1.31 christos vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
544 1.8 lukem {
545 1.8 lukem
546 1.8 lukem /* [Esc] cancels pending action */
547 1.8 lukem el->el_chared.c_vcmd.action = NOP;
548 1.8 lukem el->el_chared.c_vcmd.pos = 0;
549 1.8 lukem
550 1.8 lukem el->el_state.doingarg = 0;
551 1.1 cgd
552 1.8 lukem el->el_state.inputmode = MODE_INSERT;
553 1.8 lukem el->el_map.current = el->el_map.alt;
554 1.1 cgd #ifdef VI_MOVE
555 1.8 lukem if (el->el_line.cursor > el->el_line.buffer)
556 1.8 lukem el->el_line.cursor--;
557 1.1 cgd #endif
558 1.37 christos return CC_CURSOR;
559 1.1 cgd }
560 1.1 cgd
561 1.8 lukem
562 1.1 cgd /* vi_zero():
563 1.7 simonb * Vi move to the beginning of line
564 1.1 cgd * [0]
565 1.1 cgd */
566 1.1 cgd protected el_action_t
567 1.31 christos vi_zero(EditLine *el, Int c)
568 1.8 lukem {
569 1.8 lukem
570 1.12 christos if (el->el_state.doingarg)
571 1.12 christos return ed_argument_digit(el, c);
572 1.12 christos
573 1.12 christos el->el_line.cursor = el->el_line.buffer;
574 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
575 1.12 christos cv_delfini(el);
576 1.37 christos return CC_REFRESH;
577 1.8 lukem }
578 1.37 christos return CC_CURSOR;
579 1.1 cgd }
580 1.1 cgd
581 1.1 cgd
582 1.1 cgd /* vi_delete_prev_char():
583 1.7 simonb * Vi move to previous character (backspace)
584 1.10 christos * [^H] in insert mode only
585 1.7 simonb */
586 1.1 cgd protected el_action_t
587 1.1 cgd /*ARGSUSED*/
588 1.31 christos vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
589 1.8 lukem {
590 1.1 cgd
591 1.20 mycroft if (el->el_line.cursor <= el->el_line.buffer)
592 1.37 christos return CC_ERROR;
593 1.8 lukem
594 1.20 mycroft c_delbefore1(el);
595 1.20 mycroft el->el_line.cursor--;
596 1.37 christos return CC_REFRESH;
597 1.8 lukem }
598 1.1 cgd
599 1.1 cgd
600 1.1 cgd /* vi_list_or_eof():
601 1.1 cgd * Vi list choices for completion or indicate end of file if empty line
602 1.1 cgd * [^D]
603 1.1 cgd */
604 1.1 cgd protected el_action_t
605 1.1 cgd /*ARGSUSED*/
606 1.31 christos vi_list_or_eof(EditLine *el, Int c)
607 1.1 cgd {
608 1.8 lukem
609 1.17 matt if (el->el_line.cursor == el->el_line.lastchar) {
610 1.17 matt if (el->el_line.cursor == el->el_line.buffer) {
611 1.35 christos terminal_writec(el, c); /* then do a EOF */
612 1.37 christos return CC_EOF;
613 1.17 matt } else {
614 1.17 matt /*
615 1.17 matt * Here we could list completions, but it is an
616 1.17 matt * error right now
617 1.17 matt */
618 1.35 christos terminal_beep(el);
619 1.37 christos return CC_ERROR;
620 1.17 matt }
621 1.17 matt } else {
622 1.1 cgd #ifdef notyet
623 1.8 lukem re_goto_bottom(el);
624 1.8 lukem *el->el_line.lastchar = '\0'; /* just in case */
625 1.37 christos return CC_LIST_CHOICES;
626 1.17 matt #else
627 1.17 matt /*
628 1.17 matt * Just complain for now.
629 1.17 matt */
630 1.35 christos terminal_beep(el);
631 1.37 christos return CC_ERROR;
632 1.17 matt #endif
633 1.8 lukem }
634 1.1 cgd }
635 1.1 cgd
636 1.1 cgd
637 1.1 cgd /* vi_kill_line_prev():
638 1.7 simonb * Vi cut from beginning of line to cursor
639 1.1 cgd * [^U]
640 1.1 cgd */
641 1.1 cgd protected el_action_t
642 1.1 cgd /*ARGSUSED*/
643 1.31 christos vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
644 1.8 lukem {
645 1.31 christos Char *kp, *cp;
646 1.8 lukem
647 1.8 lukem cp = el->el_line.buffer;
648 1.8 lukem kp = el->el_chared.c_kill.buf;
649 1.8 lukem while (cp < el->el_line.cursor)
650 1.8 lukem *kp++ = *cp++; /* copy it */
651 1.8 lukem el->el_chared.c_kill.last = kp;
652 1.29 christos c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
653 1.8 lukem el->el_line.cursor = el->el_line.buffer; /* zap! */
654 1.37 christos return CC_REFRESH;
655 1.1 cgd }
656 1.1 cgd
657 1.1 cgd
658 1.1 cgd /* vi_search_prev():
659 1.1 cgd * Vi search history previous
660 1.1 cgd * [?]
661 1.1 cgd */
662 1.1 cgd protected el_action_t
663 1.1 cgd /*ARGSUSED*/
664 1.31 christos vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
665 1.1 cgd {
666 1.8 lukem
667 1.37 christos return cv_search(el, ED_SEARCH_PREV_HISTORY);
668 1.1 cgd }
669 1.1 cgd
670 1.1 cgd
671 1.1 cgd /* vi_search_next():
672 1.1 cgd * Vi search history next
673 1.1 cgd * [/]
674 1.1 cgd */
675 1.1 cgd protected el_action_t
676 1.1 cgd /*ARGSUSED*/
677 1.31 christos vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
678 1.1 cgd {
679 1.8 lukem
680 1.37 christos return cv_search(el, ED_SEARCH_NEXT_HISTORY);
681 1.1 cgd }
682 1.1 cgd
683 1.1 cgd
684 1.1 cgd /* vi_repeat_search_next():
685 1.1 cgd * Vi repeat current search in the same search direction
686 1.1 cgd * [n]
687 1.1 cgd */
688 1.1 cgd protected el_action_t
689 1.1 cgd /*ARGSUSED*/
690 1.31 christos vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
691 1.8 lukem {
692 1.8 lukem
693 1.8 lukem if (el->el_search.patlen == 0)
694 1.37 christos return CC_ERROR;
695 1.8 lukem else
696 1.37 christos return cv_repeat_srch(el, el->el_search.patdir);
697 1.1 cgd }
698 1.1 cgd
699 1.1 cgd
700 1.1 cgd /* vi_repeat_search_prev():
701 1.1 cgd * Vi repeat current search in the opposite search direction
702 1.1 cgd * [N]
703 1.1 cgd */
704 1.1 cgd /*ARGSUSED*/
705 1.1 cgd protected el_action_t
706 1.31 christos vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
707 1.8 lukem {
708 1.8 lukem
709 1.8 lukem if (el->el_search.patlen == 0)
710 1.37 christos return CC_ERROR;
711 1.8 lukem else
712 1.8 lukem return (cv_repeat_srch(el,
713 1.8 lukem el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
714 1.8 lukem ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
715 1.1 cgd }
716 1.1 cgd
717 1.1 cgd
718 1.1 cgd /* vi_next_char():
719 1.1 cgd * Vi move to the character specified next
720 1.1 cgd * [f]
721 1.1 cgd */
722 1.1 cgd protected el_action_t
723 1.1 cgd /*ARGSUSED*/
724 1.31 christos vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
725 1.1 cgd {
726 1.12 christos return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
727 1.1 cgd }
728 1.1 cgd
729 1.1 cgd
730 1.1 cgd /* vi_prev_char():
731 1.1 cgd * Vi move to the character specified previous
732 1.1 cgd * [F]
733 1.1 cgd */
734 1.1 cgd protected el_action_t
735 1.1 cgd /*ARGSUSED*/
736 1.31 christos vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
737 1.1 cgd {
738 1.12 christos return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
739 1.1 cgd }
740 1.1 cgd
741 1.1 cgd
742 1.1 cgd /* vi_to_next_char():
743 1.1 cgd * Vi move up to the character specified next
744 1.1 cgd * [t]
745 1.1 cgd */
746 1.1 cgd protected el_action_t
747 1.1 cgd /*ARGSUSED*/
748 1.31 christos vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
749 1.1 cgd {
750 1.12 christos return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
751 1.1 cgd }
752 1.1 cgd
753 1.1 cgd
754 1.1 cgd /* vi_to_prev_char():
755 1.1 cgd * Vi move up to the character specified previous
756 1.1 cgd * [T]
757 1.1 cgd */
758 1.1 cgd protected el_action_t
759 1.1 cgd /*ARGSUSED*/
760 1.31 christos vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
761 1.8 lukem {
762 1.12 christos return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
763 1.1 cgd }
764 1.1 cgd
765 1.1 cgd
766 1.1 cgd /* vi_repeat_next_char():
767 1.1 cgd * Vi repeat current character search in the same search direction
768 1.1 cgd * [;]
769 1.1 cgd */
770 1.1 cgd protected el_action_t
771 1.1 cgd /*ARGSUSED*/
772 1.31 christos vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
773 1.8 lukem {
774 1.8 lukem
775 1.12 christos return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
776 1.12 christos el->el_state.argument, el->el_search.chatflg);
777 1.1 cgd }
778 1.1 cgd
779 1.1 cgd
780 1.1 cgd /* vi_repeat_prev_char():
781 1.1 cgd * Vi repeat current character search in the opposite search direction
782 1.1 cgd * [,]
783 1.1 cgd */
784 1.1 cgd protected el_action_t
785 1.1 cgd /*ARGSUSED*/
786 1.31 christos vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
787 1.8 lukem {
788 1.12 christos el_action_t r;
789 1.12 christos int dir = el->el_search.chadir;
790 1.8 lukem
791 1.12 christos r = cv_csearch(el, -dir, el->el_search.chacha,
792 1.12 christos el->el_state.argument, el->el_search.chatflg);
793 1.12 christos el->el_search.chadir = dir;
794 1.12 christos return r;
795 1.11 christos }
796 1.11 christos
797 1.11 christos
798 1.11 christos /* vi_match():
799 1.11 christos * Vi go to matching () {} or []
800 1.11 christos * [%]
801 1.11 christos */
802 1.11 christos protected el_action_t
803 1.11 christos /*ARGSUSED*/
804 1.38 christos vi_match(EditLine *el, Int c __attribute__((__unused__)))
805 1.11 christos {
806 1.31 christos const Char match_chars[] = STR("()[]{}");
807 1.31 christos Char *cp;
808 1.29 christos size_t delta, i, count;
809 1.31 christos Char o_ch, c_ch;
810 1.11 christos
811 1.11 christos *el->el_line.lastchar = '\0'; /* just in case */
812 1.11 christos
813 1.31 christos i = Strcspn(el->el_line.cursor, match_chars);
814 1.11 christos o_ch = el->el_line.cursor[i];
815 1.11 christos if (o_ch == 0)
816 1.11 christos return CC_ERROR;
817 1.31 christos delta = Strchr(match_chars, o_ch) - match_chars;
818 1.11 christos c_ch = match_chars[delta ^ 1];
819 1.11 christos count = 1;
820 1.11 christos delta = 1 - (delta & 1) * 2;
821 1.11 christos
822 1.11 christos for (cp = &el->el_line.cursor[i]; count; ) {
823 1.11 christos cp += delta;
824 1.11 christos if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
825 1.11 christos return CC_ERROR;
826 1.11 christos if (*cp == o_ch)
827 1.11 christos count++;
828 1.11 christos else if (*cp == c_ch)
829 1.11 christos count--;
830 1.11 christos }
831 1.11 christos
832 1.11 christos el->el_line.cursor = cp;
833 1.11 christos
834 1.12 christos if (el->el_chared.c_vcmd.action != NOP) {
835 1.12 christos /* NB posix says char under cursor should NOT be deleted
836 1.12 christos for -ve delta - this is different to netbsd vi. */
837 1.11 christos if (delta > 0)
838 1.11 christos el->el_line.cursor++;
839 1.11 christos cv_delfini(el);
840 1.37 christos return CC_REFRESH;
841 1.11 christos }
842 1.37 christos return CC_CURSOR;
843 1.12 christos }
844 1.12 christos
845 1.12 christos /* vi_undo_line():
846 1.12 christos * Vi undo all changes to line
847 1.12 christos * [U]
848 1.12 christos */
849 1.12 christos protected el_action_t
850 1.12 christos /*ARGSUSED*/
851 1.38 christos vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
852 1.12 christos {
853 1.12 christos
854 1.12 christos cv_undo(el);
855 1.12 christos return hist_get(el);
856 1.12 christos }
857 1.12 christos
858 1.12 christos /* vi_to_column():
859 1.12 christos * Vi go to specified column
860 1.12 christos * [|]
861 1.12 christos * NB netbsd vi goes to screen column 'n', posix says nth character
862 1.12 christos */
863 1.12 christos protected el_action_t
864 1.12 christos /*ARGSUSED*/
865 1.38 christos vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
866 1.12 christos {
867 1.12 christos
868 1.12 christos el->el_line.cursor = el->el_line.buffer;
869 1.12 christos el->el_state.argument--;
870 1.12 christos return ed_next_char(el, 0);
871 1.12 christos }
872 1.12 christos
873 1.12 christos /* vi_yank_end():
874 1.12 christos * Vi yank to end of line
875 1.12 christos * [Y]
876 1.12 christos */
877 1.12 christos protected el_action_t
878 1.12 christos /*ARGSUSED*/
879 1.38 christos vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
880 1.12 christos {
881 1.12 christos
882 1.12 christos cv_yank(el, el->el_line.cursor,
883 1.29 christos (int)(el->el_line.lastchar - el->el_line.cursor));
884 1.12 christos return CC_REFRESH;
885 1.12 christos }
886 1.12 christos
887 1.12 christos /* vi_yank():
888 1.12 christos * Vi yank
889 1.12 christos * [y]
890 1.12 christos */
891 1.12 christos protected el_action_t
892 1.12 christos /*ARGSUSED*/
893 1.38 christos vi_yank(EditLine *el, Int c __attribute__((__unused__)))
894 1.12 christos {
895 1.12 christos
896 1.12 christos return cv_action(el, YANK);
897 1.12 christos }
898 1.12 christos
899 1.12 christos /* vi_comment_out():
900 1.12 christos * Vi comment out current command
901 1.22 christos * [#]
902 1.12 christos */
903 1.12 christos protected el_action_t
904 1.12 christos /*ARGSUSED*/
905 1.38 christos vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
906 1.12 christos {
907 1.12 christos
908 1.12 christos el->el_line.cursor = el->el_line.buffer;
909 1.12 christos c_insert(el, 1);
910 1.12 christos *el->el_line.cursor = '#';
911 1.12 christos re_refresh(el);
912 1.12 christos return ed_newline(el, 0);
913 1.12 christos }
914 1.12 christos
915 1.12 christos /* vi_alias():
916 1.12 christos * Vi include shell alias
917 1.12 christos * [@]
918 1.22 christos * NB: posix implies that we should enter insert mode, however
919 1.12 christos * this is against historical precedent...
920 1.12 christos */
921 1.27 mrg #ifdef __weak_reference
922 1.34 joerg __weakref_visible char *my_get_alias_text(const char *)
923 1.34 joerg __weak_reference(get_alias_text);
924 1.33 joerg #endif
925 1.12 christos protected el_action_t
926 1.12 christos /*ARGSUSED*/
927 1.38 christos vi_alias(EditLine *el, Int c __attribute__((__unused__)))
928 1.12 christos {
929 1.26 christos #ifdef __weak_reference
930 1.12 christos char alias_name[3];
931 1.12 christos char *alias_text;
932 1.12 christos
933 1.33 joerg if (my_get_alias_text == 0) {
934 1.33 joerg return CC_ERROR;
935 1.33 joerg }
936 1.14 christos
937 1.12 christos alias_name[0] = '_';
938 1.12 christos alias_name[2] = 0;
939 1.12 christos if (el_getc(el, &alias_name[1]) != 1)
940 1.12 christos return CC_ERROR;
941 1.12 christos
942 1.34 joerg alias_text = my_get_alias_text(alias_name);
943 1.12 christos if (alias_text != NULL)
944 1.31 christos FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
945 1.12 christos return CC_NORM;
946 1.14 christos #else
947 1.14 christos return CC_ERROR;
948 1.14 christos #endif
949 1.12 christos }
950 1.12 christos
951 1.12 christos /* vi_to_history_line():
952 1.12 christos * Vi go to specified history file line.
953 1.12 christos * [G]
954 1.12 christos */
955 1.12 christos protected el_action_t
956 1.12 christos /*ARGSUSED*/
957 1.38 christos vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
958 1.12 christos {
959 1.12 christos int sv_event_no = el->el_history.eventno;
960 1.12 christos el_action_t rval;
961 1.12 christos
962 1.12 christos
963 1.12 christos if (el->el_history.eventno == 0) {
964 1.31 christos (void) Strncpy(el->el_history.buf, el->el_line.buffer,
965 1.12 christos EL_BUFSIZ);
966 1.12 christos el->el_history.last = el->el_history.buf +
967 1.12 christos (el->el_line.lastchar - el->el_line.buffer);
968 1.12 christos }
969 1.12 christos
970 1.12 christos /* Lack of a 'count' means oldest, not 1 */
971 1.12 christos if (!el->el_state.doingarg) {
972 1.12 christos el->el_history.eventno = 0x7fffffff;
973 1.12 christos hist_get(el);
974 1.12 christos } else {
975 1.12 christos /* This is brain dead, all the rest of this code counts
976 1.12 christos * upwards going into the past. Here we need count in the
977 1.12 christos * other direction (to match the output of fc -l).
978 1.12 christos * I could change the world, but this seems to suffice.
979 1.12 christos */
980 1.12 christos el->el_history.eventno = 1;
981 1.12 christos if (hist_get(el) == CC_ERROR)
982 1.12 christos return CC_ERROR;
983 1.12 christos el->el_history.eventno = 1 + el->el_history.ev.num
984 1.12 christos - el->el_state.argument;
985 1.12 christos if (el->el_history.eventno < 0) {
986 1.12 christos el->el_history.eventno = sv_event_no;
987 1.12 christos return CC_ERROR;
988 1.12 christos }
989 1.12 christos }
990 1.12 christos rval = hist_get(el);
991 1.12 christos if (rval == CC_ERROR)
992 1.12 christos el->el_history.eventno = sv_event_no;
993 1.12 christos return rval;
994 1.12 christos }
995 1.12 christos
996 1.12 christos /* vi_histedit():
997 1.12 christos * Vi edit history line with vi
998 1.12 christos * [v]
999 1.12 christos */
1000 1.12 christos protected el_action_t
1001 1.12 christos /*ARGSUSED*/
1002 1.38 christos vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
1003 1.12 christos {
1004 1.12 christos int fd;
1005 1.12 christos pid_t pid;
1006 1.29 christos ssize_t st;
1007 1.29 christos int status;
1008 1.12 christos char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
1009 1.12 christos char *cp;
1010 1.31 christos size_t len;
1011 1.31 christos Char *line;
1012 1.12 christos
1013 1.12 christos if (el->el_state.doingarg) {
1014 1.12 christos if (vi_to_history_line(el, 0) == CC_ERROR)
1015 1.12 christos return CC_ERROR;
1016 1.12 christos }
1017 1.12 christos
1018 1.12 christos fd = mkstemp(tempfile);
1019 1.12 christos if (fd < 0)
1020 1.12 christos return CC_ERROR;
1021 1.31 christos len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
1022 1.31 christos #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
1023 1.36 christos cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
1024 1.32 christos if (cp == NULL) {
1025 1.32 christos unlink(tempfile);
1026 1.32 christos close(fd);
1027 1.31 christos return CC_ERROR;
1028 1.32 christos }
1029 1.31 christos line = el_malloc(len * sizeof(*line));
1030 1.31 christos if (line == NULL) {
1031 1.36 christos el_free(cp);
1032 1.31 christos return CC_ERROR;
1033 1.31 christos }
1034 1.31 christos Strncpy(line, el->el_line.buffer, len);
1035 1.31 christos line[len] = '\0';
1036 1.31 christos ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
1037 1.31 christos cp[TMP_BUFSIZ - 1] = '\0';
1038 1.31 christos len = strlen(cp);
1039 1.31 christos write(fd, cp, len);
1040 1.12 christos write(fd, "\n", 1);
1041 1.12 christos pid = fork();
1042 1.12 christos switch (pid) {
1043 1.12 christos case -1:
1044 1.12 christos close(fd);
1045 1.12 christos unlink(tempfile);
1046 1.31 christos el_free(cp);
1047 1.31 christos el_free(line);
1048 1.12 christos return CC_ERROR;
1049 1.12 christos case 0:
1050 1.12 christos close(fd);
1051 1.28 sketch execlp("vi", "vi", tempfile, (char *)NULL);
1052 1.12 christos exit(0);
1053 1.12 christos /*NOTREACHED*/
1054 1.12 christos default:
1055 1.29 christos while (waitpid(pid, &status, 0) != pid)
1056 1.12 christos continue;
1057 1.29 christos lseek(fd, (off_t)0, SEEK_SET);
1058 1.31 christos st = read(fd, cp, TMP_BUFSIZ);
1059 1.31 christos if (st > 0) {
1060 1.31 christos len = (size_t)(el->el_line.lastchar -
1061 1.31 christos el->el_line.buffer);
1062 1.31 christos len = ct_mbstowcs(el->el_line.buffer, cp, len);
1063 1.31 christos if (len > 0 && el->el_line.buffer[len -1] == '\n')
1064 1.31 christos --len;
1065 1.31 christos }
1066 1.31 christos else
1067 1.31 christos len = 0;
1068 1.31 christos el->el_line.cursor = el->el_line.buffer;
1069 1.31 christos el->el_line.lastchar = el->el_line.buffer + len;
1070 1.31 christos el_free(cp);
1071 1.31 christos el_free(line);
1072 1.12 christos break;
1073 1.12 christos }
1074 1.12 christos
1075 1.12 christos close(fd);
1076 1.12 christos unlink(tempfile);
1077 1.12 christos /* return CC_REFRESH; */
1078 1.12 christos return ed_newline(el, 0);
1079 1.12 christos }
1080 1.12 christos
1081 1.12 christos /* vi_history_word():
1082 1.12 christos * Vi append word from previous input line
1083 1.12 christos * [_]
1084 1.12 christos * Who knows where this one came from!
1085 1.12 christos * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
1086 1.12 christos */
1087 1.12 christos protected el_action_t
1088 1.12 christos /*ARGSUSED*/
1089 1.38 christos vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
1090 1.12 christos {
1091 1.31 christos const Char *wp = HIST_FIRST(el);
1092 1.31 christos const Char *wep, *wsp;
1093 1.12 christos int len;
1094 1.31 christos Char *cp;
1095 1.31 christos const Char *lim;
1096 1.12 christos
1097 1.12 christos if (wp == NULL)
1098 1.12 christos return CC_ERROR;
1099 1.12 christos
1100 1.13 christos wep = wsp = 0;
1101 1.12 christos do {
1102 1.31 christos while (Isspace(*wp))
1103 1.12 christos wp++;
1104 1.12 christos if (*wp == 0)
1105 1.12 christos break;
1106 1.12 christos wsp = wp;
1107 1.31 christos while (*wp && !Isspace(*wp))
1108 1.12 christos wp++;
1109 1.12 christos wep = wp;
1110 1.31 christos } while ((!el->el_state.doingarg || --el->el_state.argument > 0)
1111 1.31 christos && *wp != 0);
1112 1.12 christos
1113 1.12 christos if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
1114 1.12 christos return CC_ERROR;
1115 1.12 christos
1116 1.12 christos cv_undo(el);
1117 1.29 christos len = (int)(wep - wsp);
1118 1.12 christos if (el->el_line.cursor < el->el_line.lastchar)
1119 1.12 christos el->el_line.cursor++;
1120 1.12 christos c_insert(el, len + 1);
1121 1.12 christos cp = el->el_line.cursor;
1122 1.12 christos lim = el->el_line.limit;
1123 1.12 christos if (cp < lim)
1124 1.12 christos *cp++ = ' ';
1125 1.12 christos while (wsp < wep && cp < lim)
1126 1.12 christos *cp++ = *wsp++;
1127 1.12 christos el->el_line.cursor = cp;
1128 1.12 christos
1129 1.12 christos el->el_map.current = el->el_map.key;
1130 1.12 christos return CC_REFRESH;
1131 1.12 christos }
1132 1.12 christos
1133 1.12 christos /* vi_redo():
1134 1.12 christos * Vi redo last non-motion command
1135 1.12 christos * [.]
1136 1.12 christos */
1137 1.12 christos protected el_action_t
1138 1.12 christos /*ARGSUSED*/
1139 1.38 christos vi_redo(EditLine *el, Int c __attribute__((__unused__)))
1140 1.12 christos {
1141 1.12 christos c_redo_t *r = &el->el_chared.c_redo;
1142 1.12 christos
1143 1.12 christos if (!el->el_state.doingarg && r->count) {
1144 1.12 christos el->el_state.doingarg = 1;
1145 1.12 christos el->el_state.argument = r->count;
1146 1.12 christos }
1147 1.12 christos
1148 1.12 christos el->el_chared.c_vcmd.pos = el->el_line.cursor;
1149 1.12 christos el->el_chared.c_vcmd.action = r->action;
1150 1.12 christos if (r->pos != r->buf) {
1151 1.12 christos if (r->pos + 1 > r->lim)
1152 1.12 christos /* sanity */
1153 1.12 christos r->pos = r->lim - 1;
1154 1.12 christos r->pos[0] = 0;
1155 1.31 christos FUN(el,push)(el, r->buf);
1156 1.12 christos }
1157 1.12 christos
1158 1.12 christos el->el_state.thiscmd = r->cmd;
1159 1.12 christos el->el_state.thisch = r->ch;
1160 1.37 christos return (*el->el_map.func[r->cmd])(el, r->ch);
1161 1.1 cgd }
1162