Thu Jul 28 00:45:14 2011 UTC ()
term -> terminal


(christos)
diff -r1.34 -r1.35 src/lib/libedit/vi.c

cvs diff -r1.34 -r1.35 src/lib/libedit/vi.c (switch to unified diff)

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