1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Christos Zoulas of Cornell University. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if !defined(lint) && !defined(SCCSID) 12 static char sccsid[] = "@(#)vi.c 5.2 (Berkeley) 07/03/92"; 13 #endif /* not lint && not SCCSID */ 14 15 /* 16 * vi.c: Vi mode commands. 17 */ 18 #include "sys.h" 19 #include "el.h" 20 21 private el_action_t cv_action __P((EditLine *, int)); 22 23 /* cv_action(): 24 * Handle vi actions. 25 */ 26 private el_action_t 27 cv_action(el, c) 28 EditLine *el; 29 int c; 30 { 31 register char *cp, *kp; 32 33 if (el->el_chared.c_vcmd.action & DELETE) { 34 el->el_chared.c_vcmd.action = NOP; 35 el->el_chared.c_vcmd.pos = 0; 36 37 el->el_chared.c_undo.isize = 0; 38 el->el_chared.c_undo.dsize = 0; 39 kp = el->el_chared.c_undo.buf; 40 for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { 41 *kp++ = *cp; 42 el->el_chared.c_undo.dsize++; 43 } 44 45 el->el_chared.c_undo.action = INSERT; 46 el->el_chared.c_undo.ptr = el->el_line.buffer; 47 el->el_line.lastchar = el->el_line.buffer; 48 el->el_line.cursor = el->el_line.buffer; 49 if (c & INSERT) 50 el->el_map.current = el->el_map.key; 51 52 return CC_REFRESH; 53 } 54 55 el->el_chared.c_vcmd.pos = el->el_line.cursor; 56 el->el_chared.c_vcmd.action = c; 57 return CC_ARGHACK; 58 59 #ifdef notdef 60 /* 61 * I don't think that this is needed. But we keep it for now 62 */ 63 else if (el_chared.c_vcmd.action == NOP) { 64 el->el_chared.c_vcmd.pos = el->el_line.cursor; 65 el->el_chared.c_vcmd.action = c; 66 return CC_ARGHACK; 67 } 68 else { 69 el->el_chared.c_vcmd.action = 0; 70 el->el_chared.c_vcmd.pos = 0; 71 return CC_ERROR; 72 } 73 #endif 74 } 75 76 77 /* cv_paste(): 78 * Paste previous deletion before or after the cursor 79 */ 80 protected el_action_t 81 cv_paste(el, c) 82 EditLine *el; 83 int c; 84 { 85 char *ptr; 86 c_undo_t *un = &el->el_chared.c_undo; 87 #ifdef DEBUG_PASTE 88 (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", 89 un->action, un->buf, un->isize, un->dsize); 90 #endif 91 if (un->isize == 0) 92 return CC_ERROR; 93 94 if (!c && el->el_line.cursor < el->el_line.lastchar) 95 el->el_line.cursor++; 96 ptr = el->el_line.cursor; 97 98 c_insert(el, un->isize); 99 if (el->el_line.cursor + un->isize > el->el_line.lastchar) 100 return CC_ERROR; 101 (void) memcpy(ptr, un->buf, un->isize); 102 return CC_REFRESH; 103 } 104 105 106 /* vi_paste_next(): 107 * Vi paste previous deletion to the right of the cursor 108 * [p] 109 */ 110 protected el_action_t 111 /*ARGSUSED*/ 112 vi_paste_next(el, c) 113 EditLine *el; 114 int c; 115 { 116 return cv_paste(el, 0); 117 } 118 119 120 /* vi_paste_prev(): 121 * Vi paste previous deletion to the left of the cursor 122 * [P] 123 */ 124 protected el_action_t 125 /*ARGSUSED*/ 126 vi_paste_prev(el, c) 127 EditLine *el; 128 int c; 129 { 130 return cv_paste(el, 1); 131 } 132 133 134 /* vi_prev_space_word(): 135 * Vi move to the previous space delimited word 136 * [B] 137 */ 138 protected el_action_t 139 /*ARGSUSED*/ 140 vi_prev_space_word(el, c) 141 EditLine *el; 142 int c; 143 { 144 if (el->el_line.cursor == el->el_line.buffer) 145 return CC_ERROR; 146 147 el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, 148 el->el_line.buffer, 149 el->el_state.argument, 150 cv__isword); 151 152 if (el->el_chared.c_vcmd.action & DELETE) { 153 cv_delfini(el); 154 return CC_REFRESH; 155 } 156 157 return CC_CURSOR; 158 } 159 160 161 /* vi_prev_word(): 162 * Vi move to the previous word 163 * [B] 164 */ 165 protected el_action_t 166 /*ARGSUSED*/ 167 vi_prev_word(el, c) 168 EditLine *el; 169 int c; 170 { 171 if (el->el_line.cursor == el->el_line.buffer) 172 return CC_ERROR; 173 174 el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, 175 el->el_line.buffer, 176 el->el_state.argument, 177 ce__isword); 178 179 if (el->el_chared.c_vcmd.action & DELETE) { 180 cv_delfini(el); 181 return CC_REFRESH; 182 } 183 184 return CC_CURSOR; 185 } 186 187 188 /* vi_next_space_word(): 189 * Vi move to the next space delimited word 190 * [W] 191 */ 192 protected el_action_t 193 /*ARGSUSED*/ 194 vi_next_space_word(el, c) 195 EditLine *el; 196 int c; 197 { 198 if (el->el_line.cursor == el->el_line.lastchar) 199 return CC_ERROR; 200 201 el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 202 el->el_line.lastchar, 203 el->el_state.argument, 204 cv__isword); 205 206 if (el->el_map.type == MAP_VI) 207 if (el->el_chared.c_vcmd.action & DELETE) { 208 cv_delfini(el); 209 return CC_REFRESH; 210 } 211 212 return CC_CURSOR; 213 } 214 215 /* vi_next_word(): 216 * Vi move to the next word 217 * [w] 218 */ 219 protected el_action_t 220 /*ARGSUSED*/ 221 vi_next_word(el, c) 222 EditLine *el; 223 int c; 224 { 225 if (el->el_line.cursor == el->el_line.lastchar) 226 return CC_ERROR; 227 228 el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 229 el->el_line.lastchar, 230 el->el_state.argument, 231 ce__isword); 232 233 if (el->el_map.type == MAP_VI) 234 if (el->el_chared.c_vcmd.action & DELETE) { 235 cv_delfini(el); 236 return CC_REFRESH; 237 } 238 239 return CC_CURSOR; 240 } 241 242 243 244 /* vi_change_case(): 245 * Vi change case of character under the cursor and advance one character 246 * [~] 247 */ 248 protected el_action_t 249 vi_change_case(el, c) 250 EditLine *el; 251 int c; 252 { 253 if (el->el_line.cursor < el->el_line.lastchar) { 254 c = *el->el_line.cursor; 255 if (isupper(c)) 256 *el->el_line.cursor++ = tolower(c); 257 else if (islower(c)) 258 *el->el_line.cursor++ = toupper(c); 259 else 260 el->el_line.cursor++; 261 re_fastaddc(el); 262 return CC_NORM; 263 } 264 return CC_ERROR; 265 } 266 267 268 /* vi_change_meta(): 269 * Vi change prefix command 270 * [c] 271 */ 272 protected el_action_t 273 /*ARGSUSED*/ 274 vi_change_meta(el, c) 275 EditLine *el; 276 int c; 277 { 278 /* 279 * Delete with insert == change: first we delete and then we leave in 280 * insert mode. 281 */ 282 return cv_action(el, DELETE|INSERT); 283 } 284 285 286 /* vi_insert_at_bol(): 287 * Vi enter insert mode at the beginning of line 288 * [I] 289 */ 290 protected el_action_t 291 /*ARGSUSED*/ 292 vi_insert_at_bol(el, c) 293 EditLine *el; 294 int c; 295 { 296 el->el_line.cursor = el->el_line.buffer; 297 el->el_chared.c_vcmd.ins = el->el_line.cursor; 298 299 el->el_chared.c_undo.ptr = el->el_line.cursor; 300 el->el_chared.c_undo.action = DELETE; 301 302 el->el_map.current = el->el_map.key; 303 return CC_CURSOR; 304 } 305 306 307 /* vi_replace_char(): 308 * Vi replace character under the cursor with the next character typed 309 * [r] 310 */ 311 protected el_action_t 312 /*ARGSUSED*/ 313 vi_replace_char(el, c) 314 EditLine *el; 315 int c; 316 { 317 el->el_map.current = el->el_map.key; 318 el->el_state.inputmode = MODE_REPLACE_1; 319 el->el_chared.c_undo.action = CHANGE; 320 el->el_chared.c_undo.ptr = el->el_line.cursor; 321 el->el_chared.c_undo.isize = 0; 322 el->el_chared.c_undo.dsize = 0; 323 return CC_NORM; 324 } 325 326 327 /* vi_replace_mode(): 328 * Vi enter replace mode 329 * [R] 330 */ 331 protected el_action_t 332 /*ARGSUSED*/ 333 vi_replace_mode(el, c) 334 EditLine *el; 335 int c; 336 { 337 el->el_map.current = el->el_map.key; 338 el->el_state.inputmode = MODE_REPLACE; 339 el->el_chared.c_undo.action = CHANGE; 340 el->el_chared.c_undo.ptr = el->el_line.cursor; 341 el->el_chared.c_undo.isize = 0; 342 el->el_chared.c_undo.dsize = 0; 343 return CC_NORM; 344 } 345 346 347 /* vi_substitute_char(): 348 * Vi replace character under the cursor and enter insert mode 349 * [r] 350 */ 351 protected el_action_t 352 /*ARGSUSED*/ 353 vi_substitute_char(el, c) 354 EditLine *el; 355 int c; 356 { 357 c_delafter(el, el->el_state.argument); 358 el->el_map.current = el->el_map.key; 359 return CC_REFRESH; 360 } 361 362 363 /* vi_substitute_line(): 364 * Vi substitute entire line 365 * [S] 366 */ 367 protected el_action_t 368 /*ARGSUSED*/ 369 vi_substitute_line(el, c) 370 EditLine *el; 371 int c; 372 { 373 (void) em_kill_line(el, 0); 374 el->el_map.current = el->el_map.key; 375 return CC_REFRESH; 376 } 377 378 379 /* vi_change_to_eol(): 380 * Vi change to end of line 381 * [C] 382 */ 383 protected el_action_t 384 /*ARGSUSED*/ 385 vi_change_to_eol(el, c) 386 EditLine *el; 387 int c; 388 { 389 (void) ed_kill_line(el, 0); 390 el->el_map.current = el->el_map.key; 391 return CC_REFRESH; 392 } 393 394 395 /* vi_insert(): 396 * Vi enter insert mode 397 * [i] 398 */ 399 protected el_action_t 400 /*ARGSUSED*/ 401 vi_insert(el, c) 402 EditLine *el; 403 int c; 404 { 405 el->el_map.current = el->el_map.key; 406 407 el->el_chared.c_vcmd.ins = el->el_line.cursor; 408 el->el_chared.c_undo.ptr = el->el_line.cursor; 409 el->el_chared.c_undo.action = DELETE; 410 411 return CC_NORM; 412 } 413 414 415 /* vi_add(): 416 * Vi enter insert mode after the cursor 417 * [a] 418 */ 419 protected el_action_t 420 /*ARGSUSED*/ 421 vi_add(el, c) 422 EditLine *el; 423 int c; 424 { 425 int ret; 426 el->el_map.current = el->el_map.key; 427 if (el->el_line.cursor < el->el_line.lastchar) { 428 el->el_line.cursor++; 429 if (el->el_line.cursor > el->el_line.lastchar) 430 el->el_line.cursor = el->el_line.lastchar; 431 ret = CC_CURSOR; 432 } 433 else 434 ret = CC_NORM; 435 436 el->el_chared.c_vcmd.ins = el->el_line.cursor; 437 el->el_chared.c_undo.ptr = el->el_line.cursor; 438 el->el_chared.c_undo.action = DELETE; 439 440 return ret; 441 } 442 443 444 /* vi_add_at_eol(): 445 * Vi enter insert mode at end of line 446 * [A] 447 */ 448 protected el_action_t 449 /*ARGSUSED*/ 450 vi_add_at_eol(el, c) 451 EditLine *el; 452 int c; 453 { 454 el->el_map.current = el->el_map.key; 455 el->el_line.cursor = el->el_line.lastchar; 456 457 /* Mark where insertion begins */ 458 el->el_chared.c_vcmd.ins = el->el_line.lastchar; 459 el->el_chared.c_undo.ptr = el->el_line.lastchar; 460 el->el_chared.c_undo.action = DELETE; 461 return CC_CURSOR; 462 } 463 464 465 /* vi_delete_meta(): 466 * Vi delete prefix command 467 * [d] 468 */ 469 protected el_action_t 470 /*ARGSUSED*/ 471 vi_delete_meta(el, c) 472 EditLine *el; 473 int c; 474 { 475 return cv_action(el, DELETE); 476 } 477 478 479 /* vi_end_word(): 480 * Vi move to the end of the current space delimited word 481 * [E] 482 */ 483 protected el_action_t 484 /*ARGSUSED*/ 485 vi_end_word(el, c) 486 EditLine *el; 487 int c; 488 { 489 if (el->el_line.cursor == el->el_line.lastchar) 490 return CC_ERROR; 491 492 el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, 493 el->el_state.argument); 494 495 if (el->el_chared.c_vcmd.action & DELETE) { 496 el->el_line.cursor++; 497 cv_delfini(el); 498 return CC_REFRESH; 499 } 500 501 return CC_CURSOR; 502 } 503 504 505 /* vi_to_end_word(): 506 * Vi move to the end of the current word 507 * [e] 508 */ 509 protected el_action_t 510 /*ARGSUSED*/ 511 vi_to_end_word(el, c) 512 EditLine *el; 513 int c; 514 { 515 if (el->el_line.cursor == el->el_line.lastchar) 516 return CC_ERROR; 517 518 el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, 519 el->el_state.argument); 520 521 if (el->el_chared.c_vcmd.action & DELETE) { 522 el->el_line.cursor++; 523 cv_delfini(el); 524 return CC_REFRESH; 525 } 526 527 return CC_CURSOR; 528 } 529 530 531 /* vi_undo(): 532 * Vi undo last change 533 * [u] 534 */ 535 protected el_action_t 536 /*ARGSUSED*/ 537 vi_undo(el, c) 538 EditLine *el; 539 int c; 540 { 541 char *cp, *kp; 542 char temp; 543 int i, size; 544 c_undo_t *un = &el->el_chared.c_undo; 545 546 #ifdef DEBUG_UNDO 547 (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n", 548 un->action, un->buf, un->isize, un->dsize); 549 #endif 550 switch (un->action) { 551 case DELETE: 552 if (un->dsize == 0) 553 return CC_NORM; 554 555 (void) memcpy(un->buf, un->ptr, un->dsize); 556 for (cp = un->ptr; cp <= el->el_line.lastchar; cp++) 557 *cp = cp[un->dsize]; 558 559 el->el_line.lastchar -= un->dsize; 560 el->el_line.cursor = un->ptr; 561 562 un->action = INSERT; 563 un->isize = un->dsize; 564 un->dsize = 0; 565 break; 566 567 case DELETE|INSERT: 568 size = un->isize - un->dsize; 569 if (size > 0) 570 i = un->dsize; 571 else 572 i = un->isize; 573 cp = un->ptr; 574 kp = un->buf; 575 while (i-- > 0) { 576 temp = *kp; 577 *kp++ = *cp; 578 *cp++ = temp; 579 } 580 if (size > 0) { 581 el->el_line.cursor = cp; 582 c_insert(el, size); 583 while (size-- > 0 && cp < el->el_line.lastchar) { 584 temp = *kp; 585 *kp++ = *cp; 586 *cp++ = temp; 587 } 588 } 589 else if (size < 0) { 590 size = -size; 591 for (; cp <= el->el_line.lastchar; cp++) { 592 *kp++ = *cp; 593 *cp = cp[size]; 594 } 595 el->el_line.lastchar -= size; 596 } 597 el->el_line.cursor = un->ptr; 598 i = un->dsize; 599 un->dsize = un->isize; 600 un->isize = i; 601 break; 602 603 case INSERT: 604 if (un->isize == 0) 605 return CC_NORM; 606 607 el->el_line.cursor = un->ptr; 608 c_insert(el, un->isize); 609 memcpy(un->ptr, un->buf, un->isize); 610 un->action = DELETE; 611 un->dsize = un->isize; 612 un->isize = 0; 613 break; 614 615 case CHANGE: 616 if (un->isize == 0) 617 return CC_NORM; 618 619 el->el_line.cursor = un->ptr; 620 size = (int) (el->el_line.cursor - el->el_line.lastchar); 621 if (size < un->isize) 622 size = un->isize; 623 cp = un->ptr; 624 kp = un->buf; 625 for(i = 0; i < size; i++) { 626 temp = *kp; 627 *kp++ = *cp; 628 *cp++ = temp; 629 } 630 un->dsize = 0; 631 break; 632 633 default: 634 return CC_ERROR; 635 } 636 637 return CC_REFRESH; 638 } 639 640 641 /* vi_command_mode(): 642 * Vi enter command mode (use alternative key bindings) 643 * [<ESC>] 644 */ 645 protected el_action_t 646 /*ARGSUSED*/ 647 vi_command_mode(el, c) 648 EditLine *el; 649 int c; 650 { 651 int size; 652 /* [Esc] cancels pending action */ 653 el->el_chared.c_vcmd.ins = 0; 654 el->el_chared.c_vcmd.action = NOP; 655 el->el_chared.c_vcmd.pos = 0; 656 657 el->el_state.doingarg = 0; 658 size = el->el_chared.c_undo.ptr - el->el_line.cursor; 659 if (size < 0) 660 size = -size; 661 if (el->el_chared.c_undo.action == (INSERT|DELETE) || 662 el->el_chared.c_undo.action == DELETE) 663 el->el_chared.c_undo.dsize = size; 664 else 665 el->el_chared.c_undo.isize = size; 666 667 el->el_state.inputmode = MODE_INSERT; 668 el->el_map.current = el->el_map.alt; 669 #ifdef VI_MOVE 670 if (el->el_line.cursor > el->el_line.buffer) 671 el->el_line.cursor--; 672 #endif 673 return CC_CURSOR; 674 } 675 676 /* vi_zero(): 677 * Vi move to the beginning of line 678 * [0] 679 */ 680 protected el_action_t 681 vi_zero(el, c) 682 EditLine *el; 683 int c; 684 { 685 if (el->el_state.doingarg) { 686 if (el->el_state.argument > 1000000) 687 return CC_ERROR; 688 el->el_state.argument = 689 (el->el_state.argument * 10) + (c - '0'); 690 return CC_ARGHACK; 691 } 692 else { 693 el->el_line.cursor = el->el_line.buffer; 694 if (el->el_chared.c_vcmd.action & DELETE) { 695 cv_delfini(el); 696 return CC_REFRESH; 697 } 698 return CC_CURSOR; 699 } 700 } 701 702 703 /* vi_delete_prev_char(): 704 * Vi move to previous character (backspace) 705 * [^H] 706 */ 707 protected el_action_t 708 /*ARGSUSED*/ 709 vi_delete_prev_char(el, c) 710 EditLine *el; 711 int c; 712 { 713 if (el->el_chared.c_vcmd.ins == 0) 714 return CC_ERROR; 715 716 if (el->el_chared.c_vcmd.ins > 717 el->el_line.cursor - el->el_state.argument) 718 return CC_ERROR; 719 720 c_delbefore(el, el->el_state.argument); 721 el->el_line.cursor -= el->el_state.argument; 722 723 return CC_REFRESH; 724 } /* end v_del_char_prev */ 725 726 727 /* vi_list_or_eof(): 728 * Vi list choices for completion or indicate end of file if empty line 729 * [^D] 730 */ 731 protected el_action_t 732 /*ARGSUSED*/ 733 vi_list_or_eof(el, c) 734 EditLine *el; 735 int c; 736 { 737 #ifdef notyet 738 if (el->el_line.cursor == el->el_line.lastchar && 739 el->el_line.cursor == el->el_line.buffer) { 740 #endif 741 term_overwrite(el, STReof, 4); /* then do a EOF */ 742 term__flush(); 743 return CC_EOF; 744 #ifdef notyet 745 } 746 else { 747 re_goto_bottom(el); 748 *el->el_line.lastchar = '\0'; /* just in case */ 749 return CC_LIST_CHOICES; 750 } 751 #endif 752 } 753 754 755 /* vi_kill_line_prev(): 756 * Vi cut from beginning of line to cursor 757 * [^U] 758 */ 759 protected el_action_t 760 /*ARGSUSED*/ 761 vi_kill_line_prev(el, c) 762 EditLine *el; 763 int c; 764 { 765 char *kp, *cp; 766 767 cp = el->el_line.buffer; 768 kp = el->el_chared.c_kill.buf; 769 while (cp < el->el_line.cursor) 770 *kp++ = *cp++; /* copy it */ 771 el->el_chared.c_kill.last = kp; 772 c_delbefore(el, el->el_line.cursor - el->el_line.buffer); 773 el->el_line.cursor = el->el_line.buffer; /* zap! */ 774 return CC_REFRESH; 775 } 776 777 778 /* vi_search_prev(): 779 * Vi search history previous 780 * [?] 781 */ 782 protected el_action_t 783 /*ARGSUSED*/ 784 vi_search_prev(el, c) 785 EditLine *el; 786 int c; 787 { 788 return cv_search(el, ED_SEARCH_PREV_HISTORY); 789 } 790 791 792 /* vi_search_next(): 793 * Vi search history next 794 * [/] 795 */ 796 protected el_action_t 797 /*ARGSUSED*/ 798 vi_search_next(el, c) 799 EditLine *el; 800 int c; 801 { 802 return cv_search(el, ED_SEARCH_NEXT_HISTORY); 803 } 804 805 806 /* vi_repeat_search_next(): 807 * Vi repeat current search in the same search direction 808 * [n] 809 */ 810 protected el_action_t 811 /*ARGSUSED*/ 812 vi_repeat_search_next(el, c) 813 EditLine *el; 814 int c; 815 { 816 if (el->el_search.patlen == 0) 817 return CC_ERROR; 818 else 819 return cv_repeat_srch(el, el->el_search.patdir); 820 } 821 822 823 /* vi_repeat_search_prev(): 824 * Vi repeat current search in the opposite search direction 825 * [N] 826 */ 827 /*ARGSUSED*/ 828 protected el_action_t 829 vi_repeat_search_prev(el, c) 830 EditLine *el; 831 int c; 832 { 833 if (el->el_search.patlen == 0) 834 return CC_ERROR; 835 else 836 return cv_repeat_srch(el, 837 el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? 838 ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY); 839 } 840 841 842 /* vi_next_char(): 843 * Vi move to the character specified next 844 * [f] 845 */ 846 protected el_action_t 847 /*ARGSUSED*/ 848 vi_next_char(el, c) 849 EditLine *el; 850 int c; 851 { 852 char ch; 853 854 if (el_getc(el, &ch) != 1) 855 return ed_end_of_file(el, 0); 856 857 el->el_search.chadir = CHAR_FWD; 858 el->el_search.chacha = ch; 859 860 return cv_csearch_fwd(el, ch, el->el_state.argument, 0); 861 862 } 863 864 865 /* vi_prev_char(): 866 * Vi move to the character specified previous 867 * [F] 868 */ 869 protected el_action_t 870 /*ARGSUSED*/ 871 vi_prev_char(el, c) 872 EditLine *el; 873 int c; 874 { 875 char ch; 876 877 if (el_getc(el, &ch) != 1) 878 return ed_end_of_file(el, 0); 879 880 el->el_search.chadir = CHAR_BACK; 881 el->el_search.chacha = ch; 882 883 return cv_csearch_back(el, ch, el->el_state.argument, 0); 884 } 885 886 887 /* vi_to_next_char(): 888 * Vi move up to the character specified next 889 * [t] 890 */ 891 protected el_action_t 892 /*ARGSUSED*/ 893 vi_to_next_char(el, c) 894 EditLine *el; 895 int c; 896 { 897 char ch; 898 899 if (el_getc(el, &ch) != 1) 900 return ed_end_of_file(el, 0); 901 902 return cv_csearch_fwd(el, ch, el->el_state.argument, 1); 903 904 } 905 906 907 /* vi_to_prev_char(): 908 * Vi move up to the character specified previous 909 * [T] 910 */ 911 protected el_action_t 912 /*ARGSUSED*/ 913 vi_to_prev_char(el, c) 914 EditLine *el; 915 int c; 916 { 917 char ch; 918 if (el_getc(el, &ch) != 1) 919 return ed_end_of_file(el, 0); 920 921 return cv_csearch_back(el, ch, el->el_state.argument, 1); 922 } 923 924 925 /* vi_repeat_next_char(): 926 * Vi repeat current character search in the same search direction 927 * [;] 928 */ 929 protected el_action_t 930 /*ARGSUSED*/ 931 vi_repeat_next_char(el, c) 932 EditLine *el; 933 int c; 934 { 935 if (el->el_search.chacha == 0) 936 return CC_ERROR; 937 938 return el->el_search.chadir == CHAR_FWD ? 939 cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : 940 cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); 941 } 942 943 944 /* vi_repeat_prev_char(): 945 * Vi repeat current character search in the opposite search direction 946 * [,] 947 */ 948 protected el_action_t 949 /*ARGSUSED*/ 950 vi_repeat_prev_char(el, c) 951 EditLine *el; 952 int c; 953 { 954 if (el->el_search.chacha == 0) 955 return CC_ERROR; 956 957 return el->el_search.chadir == CHAR_BACK ? 958 cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : 959 cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); 960 } 961