vi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. /* $NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $ */
  2. /*-
  3. * Copyright (c) 1992, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Christos Zoulas of Cornell University.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #if !defined(lint) && !defined(SCCSID)
  39. #if 0
  40. static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
  41. #else
  42. __RCSID("$NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $");
  43. #endif
  44. #endif /* not lint && not SCCSID */
  45. /*
  46. * vi.c: Vi mode commands.
  47. */
  48. #include "el.h"
  49. private el_action_t cv_action(EditLine *, int);
  50. private el_action_t cv_paste(EditLine *, int);
  51. /* cv_action():
  52. * Handle vi actions.
  53. */
  54. private el_action_t
  55. cv_action(EditLine *el, int c)
  56. {
  57. char *cp, *kp;
  58. if (el->el_chared.c_vcmd.action & DELETE) {
  59. el->el_chared.c_vcmd.action = NOP;
  60. el->el_chared.c_vcmd.pos = 0;
  61. el->el_chared.c_undo.isize = 0;
  62. el->el_chared.c_undo.dsize = 0;
  63. kp = el->el_chared.c_undo.buf;
  64. for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
  65. *kp++ = *cp;
  66. el->el_chared.c_undo.dsize++;
  67. }
  68. el->el_chared.c_undo.action = INSERT;
  69. el->el_chared.c_undo.ptr = el->el_line.buffer;
  70. el->el_line.lastchar = el->el_line.buffer;
  71. el->el_line.cursor = el->el_line.buffer;
  72. if (c & INSERT)
  73. el->el_map.current = el->el_map.key;
  74. return (CC_REFRESH);
  75. }
  76. el->el_chared.c_vcmd.pos = el->el_line.cursor;
  77. el->el_chared.c_vcmd.action = c;
  78. return (CC_ARGHACK);
  79. #ifdef notdef
  80. /*
  81. * I don't think that this is needed. But we keep it for now
  82. */
  83. else
  84. if (el_chared.c_vcmd.action == NOP) {
  85. el->el_chared.c_vcmd.pos = el->el_line.cursor;
  86. el->el_chared.c_vcmd.action = c;
  87. return (CC_ARGHACK);
  88. } else {
  89. el->el_chared.c_vcmd.action = 0;
  90. el->el_chared.c_vcmd.pos = 0;
  91. return (CC_ERROR);
  92. }
  93. #endif
  94. }
  95. /* cv_paste():
  96. * Paste previous deletion before or after the cursor
  97. */
  98. private el_action_t
  99. cv_paste(EditLine *el, int c)
  100. {
  101. char *ptr;
  102. c_undo_t *un = &el->el_chared.c_undo;
  103. #ifdef DEBUG_PASTE
  104. (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n",
  105. un->action, un->buf, un->isize, un->dsize);
  106. #endif
  107. if (un->isize == 0)
  108. return (CC_ERROR);
  109. if (!c && el->el_line.cursor < el->el_line.lastchar)
  110. el->el_line.cursor++;
  111. ptr = el->el_line.cursor;
  112. c_insert(el, (int) un->isize);
  113. if (el->el_line.cursor + un->isize > el->el_line.lastchar)
  114. return (CC_ERROR);
  115. (void) memcpy(ptr, un->buf, un->isize);
  116. return (CC_REFRESH);
  117. }
  118. /* vi_paste_next():
  119. * Vi paste previous deletion to the right of the cursor
  120. * [p]
  121. */
  122. protected el_action_t
  123. /*ARGSUSED*/
  124. vi_paste_next(EditLine *el, int c)
  125. {
  126. return (cv_paste(el, 0));
  127. }
  128. /* vi_paste_prev():
  129. * Vi paste previous deletion to the left of the cursor
  130. * [P]
  131. */
  132. protected el_action_t
  133. /*ARGSUSED*/
  134. vi_paste_prev(EditLine *el, int c)
  135. {
  136. return (cv_paste(el, 1));
  137. }
  138. /* vi_prev_space_word():
  139. * Vi move to the previous space delimited word
  140. * [B]
  141. */
  142. protected el_action_t
  143. /*ARGSUSED*/
  144. vi_prev_space_word(EditLine *el, int c)
  145. {
  146. if (el->el_line.cursor == el->el_line.buffer)
  147. return (CC_ERROR);
  148. el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
  149. el->el_line.buffer,
  150. el->el_state.argument,
  151. cv__isword);
  152. if (el->el_chared.c_vcmd.action & DELETE) {
  153. cv_delfini(el);
  154. return (CC_REFRESH);
  155. }
  156. return (CC_CURSOR);
  157. }
  158. /* vi_prev_word():
  159. * Vi move to the previous word
  160. * [B]
  161. */
  162. protected el_action_t
  163. /*ARGSUSED*/
  164. vi_prev_word(EditLine *el, int c)
  165. {
  166. if (el->el_line.cursor == el->el_line.buffer)
  167. return (CC_ERROR);
  168. el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
  169. el->el_line.buffer,
  170. el->el_state.argument,
  171. ce__isword);
  172. if (el->el_chared.c_vcmd.action & DELETE) {
  173. cv_delfini(el);
  174. return (CC_REFRESH);
  175. }
  176. return (CC_CURSOR);
  177. }
  178. /* vi_next_space_word():
  179. * Vi move to the next space delimited word
  180. * [W]
  181. */
  182. protected el_action_t
  183. /*ARGSUSED*/
  184. vi_next_space_word(EditLine *el, int c)
  185. {
  186. if (el->el_line.cursor == el->el_line.lastchar)
  187. return (CC_ERROR);
  188. el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
  189. el->el_line.lastchar,
  190. el->el_state.argument,
  191. cv__isword);
  192. if (el->el_map.type == MAP_VI)
  193. if (el->el_chared.c_vcmd.action & DELETE) {
  194. cv_delfini(el);
  195. return (CC_REFRESH);
  196. }
  197. return (CC_CURSOR);
  198. }
  199. /* vi_next_word():
  200. * Vi move to the next word
  201. * [w]
  202. */
  203. protected el_action_t
  204. /*ARGSUSED*/
  205. vi_next_word(EditLine *el, int c)
  206. {
  207. if (el->el_line.cursor == el->el_line.lastchar)
  208. return (CC_ERROR);
  209. el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
  210. el->el_line.lastchar,
  211. el->el_state.argument,
  212. ce__isword);
  213. if (el->el_map.type == MAP_VI)
  214. if (el->el_chared.c_vcmd.action & DELETE) {
  215. cv_delfini(el);
  216. return (CC_REFRESH);
  217. }
  218. return (CC_CURSOR);
  219. }
  220. /* vi_change_case():
  221. * Vi change case of character under the cursor and advance one character
  222. * [~]
  223. */
  224. protected el_action_t
  225. vi_change_case(EditLine *el, int c)
  226. {
  227. if (el->el_line.cursor < el->el_line.lastchar) {
  228. c = *el->el_line.cursor;
  229. if (isupper(c))
  230. *el->el_line.cursor++ = tolower(c);
  231. else if (islower(c))
  232. *el->el_line.cursor++ = toupper(c);
  233. else
  234. el->el_line.cursor++;
  235. re_fastaddc(el);
  236. return (CC_NORM);
  237. }
  238. return (CC_ERROR);
  239. }
  240. /* vi_change_meta():
  241. * Vi change prefix command
  242. * [c]
  243. */
  244. protected el_action_t
  245. /*ARGSUSED*/
  246. vi_change_meta(EditLine *el, int c)
  247. {
  248. /*
  249. * Delete with insert == change: first we delete and then we leave in
  250. * insert mode.
  251. */
  252. return (cv_action(el, DELETE | INSERT));
  253. }
  254. /* vi_insert_at_bol():
  255. * Vi enter insert mode at the beginning of line
  256. * [I]
  257. */
  258. protected el_action_t
  259. /*ARGSUSED*/
  260. vi_insert_at_bol(EditLine *el, int c)
  261. {
  262. el->el_line.cursor = el->el_line.buffer;
  263. el->el_chared.c_vcmd.ins = el->el_line.cursor;
  264. el->el_chared.c_undo.ptr = el->el_line.cursor;
  265. el->el_chared.c_undo.action = DELETE;
  266. el->el_map.current = el->el_map.key;
  267. return (CC_CURSOR);
  268. }
  269. /* vi_replace_char():
  270. * Vi replace character under the cursor with the next character typed
  271. * [r]
  272. */
  273. protected el_action_t
  274. /*ARGSUSED*/
  275. vi_replace_char(EditLine *el, int c)
  276. {
  277. el->el_map.current = el->el_map.key;
  278. el->el_state.inputmode = MODE_REPLACE_1;
  279. el->el_chared.c_undo.action = CHANGE;
  280. el->el_chared.c_undo.ptr = el->el_line.cursor;
  281. el->el_chared.c_undo.isize = 0;
  282. el->el_chared.c_undo.dsize = 0;
  283. return (CC_NORM);
  284. }
  285. /* vi_replace_mode():
  286. * Vi enter replace mode
  287. * [R]
  288. */
  289. protected el_action_t
  290. /*ARGSUSED*/
  291. vi_replace_mode(EditLine *el, int c)
  292. {
  293. el->el_map.current = el->el_map.key;
  294. el->el_state.inputmode = MODE_REPLACE;
  295. el->el_chared.c_undo.action = CHANGE;
  296. el->el_chared.c_undo.ptr = el->el_line.cursor;
  297. el->el_chared.c_undo.isize = 0;
  298. el->el_chared.c_undo.dsize = 0;
  299. return (CC_NORM);
  300. }
  301. /* vi_substitute_char():
  302. * Vi replace character under the cursor and enter insert mode
  303. * [r]
  304. */
  305. protected el_action_t
  306. /*ARGSUSED*/
  307. vi_substitute_char(EditLine *el, int c)
  308. {
  309. c_delafter(el, el->el_state.argument);
  310. el->el_map.current = el->el_map.key;
  311. return (CC_REFRESH);
  312. }
  313. /* vi_substitute_line():
  314. * Vi substitute entire line
  315. * [S]
  316. */
  317. protected el_action_t
  318. /*ARGSUSED*/
  319. vi_substitute_line(EditLine *el, int c)
  320. {
  321. (void) em_kill_line(el, 0);
  322. el->el_map.current = el->el_map.key;
  323. return (CC_REFRESH);
  324. }
  325. /* vi_change_to_eol():
  326. * Vi change to end of line
  327. * [C]
  328. */
  329. protected el_action_t
  330. /*ARGSUSED*/
  331. vi_change_to_eol(EditLine *el, int c)
  332. {
  333. (void) ed_kill_line(el, 0);
  334. el->el_map.current = el->el_map.key;
  335. return (CC_REFRESH);
  336. }
  337. /* vi_insert():
  338. * Vi enter insert mode
  339. * [i]
  340. */
  341. protected el_action_t
  342. /*ARGSUSED*/
  343. vi_insert(EditLine *el, int c)
  344. {
  345. el->el_map.current = el->el_map.key;
  346. el->el_chared.c_vcmd.ins = el->el_line.cursor;
  347. el->el_chared.c_undo.ptr = el->el_line.cursor;
  348. el->el_chared.c_undo.action = DELETE;
  349. return (CC_NORM);
  350. }
  351. /* vi_add():
  352. * Vi enter insert mode after the cursor
  353. * [a]
  354. */
  355. protected el_action_t
  356. /*ARGSUSED*/
  357. vi_add(EditLine *el, int c)
  358. {
  359. int ret;
  360. el->el_map.current = el->el_map.key;
  361. if (el->el_line.cursor < el->el_line.lastchar) {
  362. el->el_line.cursor++;
  363. if (el->el_line.cursor > el->el_line.lastchar)
  364. el->el_line.cursor = el->el_line.lastchar;
  365. ret = CC_CURSOR;
  366. } else
  367. ret = CC_NORM;
  368. el->el_chared.c_vcmd.ins = el->el_line.cursor;
  369. el->el_chared.c_undo.ptr = el->el_line.cursor;
  370. el->el_chared.c_undo.action = DELETE;
  371. return (ret);
  372. }
  373. /* vi_add_at_eol():
  374. * Vi enter insert mode at end of line
  375. * [A]
  376. */
  377. protected el_action_t
  378. /*ARGSUSED*/
  379. vi_add_at_eol(EditLine *el, int c)
  380. {
  381. el->el_map.current = el->el_map.key;
  382. el->el_line.cursor = el->el_line.lastchar;
  383. /* Mark where insertion begins */
  384. el->el_chared.c_vcmd.ins = el->el_line.lastchar;
  385. el->el_chared.c_undo.ptr = el->el_line.lastchar;
  386. el->el_chared.c_undo.action = DELETE;
  387. return (CC_CURSOR);
  388. }
  389. /* vi_delete_meta():
  390. * Vi delete prefix command
  391. * [d]
  392. */
  393. protected el_action_t
  394. /*ARGSUSED*/
  395. vi_delete_meta(EditLine *el, int c)
  396. {
  397. return (cv_action(el, DELETE));
  398. }
  399. /* vi_end_word():
  400. * Vi move to the end of the current space delimited word
  401. * [E]
  402. */
  403. protected el_action_t
  404. /*ARGSUSED*/
  405. vi_end_word(EditLine *el, int c)
  406. {
  407. if (el->el_line.cursor == el->el_line.lastchar)
  408. return (CC_ERROR);
  409. el->el_line.cursor = cv__endword(el->el_line.cursor,
  410. el->el_line.lastchar, el->el_state.argument);
  411. if (el->el_chared.c_vcmd.action & DELETE) {
  412. el->el_line.cursor++;
  413. cv_delfini(el);
  414. return (CC_REFRESH);
  415. }
  416. return (CC_CURSOR);
  417. }
  418. /* vi_to_end_word():
  419. * Vi move to the end of the current word
  420. * [e]
  421. */
  422. protected el_action_t
  423. /*ARGSUSED*/
  424. vi_to_end_word(EditLine *el, int c)
  425. {
  426. if (el->el_line.cursor == el->el_line.lastchar)
  427. return (CC_ERROR);
  428. el->el_line.cursor = cv__endword(el->el_line.cursor,
  429. el->el_line.lastchar, el->el_state.argument);
  430. if (el->el_chared.c_vcmd.action & DELETE) {
  431. el->el_line.cursor++;
  432. cv_delfini(el);
  433. return (CC_REFRESH);
  434. }
  435. return (CC_CURSOR);
  436. }
  437. /* vi_undo():
  438. * Vi undo last change
  439. * [u]
  440. */
  441. protected el_action_t
  442. /*ARGSUSED*/
  443. vi_undo(EditLine *el, int c)
  444. {
  445. char *cp, *kp;
  446. char temp;
  447. int i, size;
  448. c_undo_t *un = &el->el_chared.c_undo;
  449. #ifdef DEBUG_UNDO
  450. (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n",
  451. un->action, un->buf, un->isize, un->dsize);
  452. #endif
  453. switch (un->action) {
  454. case DELETE:
  455. if (un->dsize == 0)
  456. return (CC_NORM);
  457. (void) memcpy(un->buf, un->ptr, un->dsize);
  458. for (cp = un->ptr; cp <= el->el_line.lastchar; cp++)
  459. *cp = cp[un->dsize];
  460. el->el_line.lastchar -= un->dsize;
  461. el->el_line.cursor = un->ptr;
  462. un->action = INSERT;
  463. un->isize = un->dsize;
  464. un->dsize = 0;
  465. break;
  466. case DELETE | INSERT:
  467. size = un->isize - un->dsize;
  468. if (size > 0)
  469. i = un->dsize;
  470. else
  471. i = un->isize;
  472. cp = un->ptr;
  473. kp = un->buf;
  474. while (i-- > 0) {
  475. temp = *kp;
  476. *kp++ = *cp;
  477. *cp++ = temp;
  478. }
  479. if (size > 0) {
  480. el->el_line.cursor = cp;
  481. c_insert(el, size);
  482. while (size-- > 0 && cp < el->el_line.lastchar) {
  483. temp = *kp;
  484. *kp++ = *cp;
  485. *cp++ = temp;
  486. }
  487. } else if (size < 0) {
  488. size = -size;
  489. for (; cp <= el->el_line.lastchar; cp++) {
  490. *kp++ = *cp;
  491. *cp = cp[size];
  492. }
  493. el->el_line.lastchar -= size;
  494. }
  495. el->el_line.cursor = un->ptr;
  496. i = un->dsize;
  497. un->dsize = un->isize;
  498. un->isize = i;
  499. break;
  500. case INSERT:
  501. if (un->isize == 0)
  502. return (CC_NORM);
  503. el->el_line.cursor = un->ptr;
  504. c_insert(el, (int) un->isize);
  505. (void) memcpy(un->ptr, un->buf, un->isize);
  506. un->action = DELETE;
  507. un->dsize = un->isize;
  508. un->isize = 0;
  509. break;
  510. case CHANGE:
  511. if (un->isize == 0)
  512. return (CC_NORM);
  513. el->el_line.cursor = un->ptr;
  514. size = (int) (el->el_line.cursor - el->el_line.lastchar);
  515. if (size < un->isize)
  516. size = un->isize;
  517. cp = un->ptr;
  518. kp = un->buf;
  519. for (i = 0; i < size; i++) {
  520. temp = *kp;
  521. *kp++ = *cp;
  522. *cp++ = temp;
  523. }
  524. un->dsize = 0;
  525. break;
  526. default:
  527. return (CC_ERROR);
  528. }
  529. return (CC_REFRESH);
  530. }
  531. /* vi_command_mode():
  532. * Vi enter command mode (use alternative key bindings)
  533. * [<ESC>]
  534. */
  535. protected el_action_t
  536. /*ARGSUSED*/
  537. vi_command_mode(EditLine *el, int c)
  538. {
  539. int size;
  540. /* [Esc] cancels pending action */
  541. el->el_chared.c_vcmd.ins = 0;
  542. el->el_chared.c_vcmd.action = NOP;
  543. el->el_chared.c_vcmd.pos = 0;
  544. el->el_state.doingarg = 0;
  545. size = el->el_chared.c_undo.ptr - el->el_line.cursor;
  546. if (size < 0)
  547. size = -size;
  548. if (el->el_chared.c_undo.action == (INSERT | DELETE) ||
  549. el->el_chared.c_undo.action == DELETE)
  550. el->el_chared.c_undo.dsize = size;
  551. else
  552. el->el_chared.c_undo.isize = size;
  553. el->el_state.inputmode = MODE_INSERT;
  554. el->el_map.current = el->el_map.alt;
  555. #ifdef VI_MOVE
  556. if (el->el_line.cursor > el->el_line.buffer)
  557. el->el_line.cursor--;
  558. #endif
  559. return (CC_CURSOR);
  560. }
  561. /* vi_zero():
  562. * Vi move to the beginning of line
  563. * [0]
  564. */
  565. protected el_action_t
  566. vi_zero(EditLine *el, int c)
  567. {
  568. if (el->el_state.doingarg) {
  569. if (el->el_state.argument > 1000000)
  570. return (CC_ERROR);
  571. el->el_state.argument =
  572. (el->el_state.argument * 10) + (c - '0');
  573. return (CC_ARGHACK);
  574. } else {
  575. el->el_line.cursor = el->el_line.buffer;
  576. if (el->el_chared.c_vcmd.action & DELETE) {
  577. cv_delfini(el);
  578. return (CC_REFRESH);
  579. }
  580. return (CC_CURSOR);
  581. }
  582. }
  583. /* vi_delete_prev_char():
  584. * Vi move to previous character (backspace)
  585. * [^H]
  586. */
  587. protected el_action_t
  588. /*ARGSUSED*/
  589. vi_delete_prev_char(EditLine *el, int c)
  590. {
  591. if (el->el_chared.c_vcmd.ins == 0)
  592. return (CC_ERROR);
  593. if (el->el_chared.c_vcmd.ins >
  594. el->el_line.cursor - el->el_state.argument)
  595. return (CC_ERROR);
  596. c_delbefore(el, el->el_state.argument);
  597. el->el_line.cursor -= el->el_state.argument;
  598. return (CC_REFRESH);
  599. }
  600. /* vi_list_or_eof():
  601. * Vi list choices for completion or indicate end of file if empty line
  602. * [^D]
  603. */
  604. protected el_action_t
  605. /*ARGSUSED*/
  606. vi_list_or_eof(EditLine *el, int c)
  607. {
  608. #ifdef notyet
  609. if (el->el_line.cursor == el->el_line.lastchar &&
  610. el->el_line.cursor == el->el_line.buffer) {
  611. #endif
  612. term_overwrite(el, STReof, 4); /* then do a EOF */
  613. term__flush();
  614. return (CC_EOF);
  615. #ifdef notyet
  616. } else {
  617. re_goto_bottom(el);
  618. *el->el_line.lastchar = '\0'; /* just in case */
  619. return (CC_LIST_CHOICES);
  620. }
  621. #endif
  622. }
  623. /* vi_kill_line_prev():
  624. * Vi cut from beginning of line to cursor
  625. * [^U]
  626. */
  627. protected el_action_t
  628. /*ARGSUSED*/
  629. vi_kill_line_prev(EditLine *el, int c)
  630. {
  631. char *kp, *cp;
  632. cp = el->el_line.buffer;
  633. kp = el->el_chared.c_kill.buf;
  634. while (cp < el->el_line.cursor)
  635. *kp++ = *cp++; /* copy it */
  636. el->el_chared.c_kill.last = kp;
  637. c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
  638. el->el_line.cursor = el->el_line.buffer; /* zap! */
  639. return (CC_REFRESH);
  640. }
  641. /* vi_search_prev():
  642. * Vi search history previous
  643. * [?]
  644. */
  645. protected el_action_t
  646. /*ARGSUSED*/
  647. vi_search_prev(EditLine *el, int c)
  648. {
  649. return (cv_search(el, ED_SEARCH_PREV_HISTORY));
  650. }
  651. /* vi_search_next():
  652. * Vi search history next
  653. * [/]
  654. */
  655. protected el_action_t
  656. /*ARGSUSED*/
  657. vi_search_next(EditLine *el, int c)
  658. {
  659. return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
  660. }
  661. /* vi_repeat_search_next():
  662. * Vi repeat current search in the same search direction
  663. * [n]
  664. */
  665. protected el_action_t
  666. /*ARGSUSED*/
  667. vi_repeat_search_next(EditLine *el, int c)
  668. {
  669. if (el->el_search.patlen == 0)
  670. return (CC_ERROR);
  671. else
  672. return (cv_repeat_srch(el, el->el_search.patdir));
  673. }
  674. /* vi_repeat_search_prev():
  675. * Vi repeat current search in the opposite search direction
  676. * [N]
  677. */
  678. /*ARGSUSED*/
  679. protected el_action_t
  680. vi_repeat_search_prev(EditLine *el, int c)
  681. {
  682. if (el->el_search.patlen == 0)
  683. return (CC_ERROR);
  684. else
  685. return (cv_repeat_srch(el,
  686. el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
  687. ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
  688. }
  689. /* vi_next_char():
  690. * Vi move to the character specified next
  691. * [f]
  692. */
  693. protected el_action_t
  694. /*ARGSUSED*/
  695. vi_next_char(EditLine *el, int c)
  696. {
  697. char ch;
  698. if (el_getc(el, &ch) != 1)
  699. return (ed_end_of_file(el, 0));
  700. el->el_search.chadir = CHAR_FWD;
  701. el->el_search.chacha = ch;
  702. return (cv_csearch_fwd(el, ch, el->el_state.argument, 0));
  703. }
  704. /* vi_prev_char():
  705. * Vi move to the character specified previous
  706. * [F]
  707. */
  708. protected el_action_t
  709. /*ARGSUSED*/
  710. vi_prev_char(EditLine *el, int c)
  711. {
  712. char ch;
  713. if (el_getc(el, &ch) != 1)
  714. return (ed_end_of_file(el, 0));
  715. el->el_search.chadir = CHAR_BACK;
  716. el->el_search.chacha = ch;
  717. return (cv_csearch_back(el, ch, el->el_state.argument, 0));
  718. }
  719. /* vi_to_next_char():
  720. * Vi move up to the character specified next
  721. * [t]
  722. */
  723. protected el_action_t
  724. /*ARGSUSED*/
  725. vi_to_next_char(EditLine *el, int c)
  726. {
  727. char ch;
  728. if (el_getc(el, &ch) != 1)
  729. return (ed_end_of_file(el, 0));
  730. return (cv_csearch_fwd(el, ch, el->el_state.argument, 1));
  731. }
  732. /* vi_to_prev_char():
  733. * Vi move up to the character specified previous
  734. * [T]
  735. */
  736. protected el_action_t
  737. /*ARGSUSED*/
  738. vi_to_prev_char(EditLine *el, int c)
  739. {
  740. char ch;
  741. if (el_getc(el, &ch) != 1)
  742. return (ed_end_of_file(el, 0));
  743. return (cv_csearch_back(el, ch, el->el_state.argument, 1));
  744. }
  745. /* vi_repeat_next_char():
  746. * Vi repeat current character search in the same search direction
  747. * [;]
  748. */
  749. protected el_action_t
  750. /*ARGSUSED*/
  751. vi_repeat_next_char(EditLine *el, int c)
  752. {
  753. if (el->el_search.chacha == 0)
  754. return (CC_ERROR);
  755. return (el->el_search.chadir == CHAR_FWD
  756. ? cv_csearch_fwd(el, el->el_search.chacha,
  757. el->el_state.argument, 0)
  758. : cv_csearch_back(el, el->el_search.chacha,
  759. el->el_state.argument, 0));
  760. }
  761. /* vi_repeat_prev_char():
  762. * Vi repeat current character search in the opposite search direction
  763. * [,]
  764. */
  765. protected el_action_t
  766. /*ARGSUSED*/
  767. vi_repeat_prev_char(EditLine *el, int c)
  768. {
  769. if (el->el_search.chacha == 0)
  770. return (CC_ERROR);
  771. return el->el_search.chadir == CHAR_BACK ?
  772. cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
  773. cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
  774. }