1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. 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[] = "@(#)common.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* not lint && not SCCSID */ 14 15 /* 16 * common.c: Common Editor functions 17 */ 18 #include "sys.h" 19 #include "el.h" 20 21 /* ed_end_of_file(): 22 * Indicate end of file 23 * [^D] 24 */ 25 protected el_action_t 26 /*ARGSUSED*/ 27 ed_end_of_file(el, c) 28 EditLine *el; 29 int c; 30 { 31 re_goto_bottom(el); 32 *el->el_line.lastchar = '\0'; 33 return CC_EOF; 34 } 35 36 37 /* ed_insert(): 38 * Add character to the line 39 * Insert a character [bound to all insert keys] 40 */ 41 protected el_action_t 42 ed_insert(el, c) 43 EditLine *el; 44 int c; 45 { 46 int i; 47 48 if (c == '\0') 49 return CC_ERROR; 50 51 if (el->el_line.lastchar + el->el_state.argument >= 52 el->el_line.limit) 53 return CC_ERROR; /* end of buffer space */ 54 55 if (el->el_state.argument == 1) { 56 if (el->el_state.inputmode != MODE_INSERT) { 57 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = 58 *el->el_line.cursor; 59 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0'; 60 c_delafter(el, 1); 61 } 62 63 c_insert(el, 1); 64 65 *el->el_line.cursor++ = c; 66 el->el_state.doingarg = 0; /* just in case */ 67 re_fastaddc(el); /* fast refresh for one char. */ 68 } 69 else { 70 if (el->el_state.inputmode != MODE_INSERT) { 71 72 for(i = 0;i < el->el_state.argument; i++) 73 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = 74 el->el_line.cursor[i]; 75 76 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0'; 77 c_delafter(el, el->el_state.argument); 78 } 79 80 c_insert(el, el->el_state.argument); 81 82 while (el->el_state.argument--) 83 *el->el_line.cursor++ = c; 84 re_refresh(el); 85 } 86 87 if (el->el_state.inputmode == MODE_REPLACE_1) 88 (void) vi_command_mode(el, 0); 89 90 return CC_NORM; 91 } 92 93 94 /* ed_delete_prev_word(): 95 * Delete from beginning of current word to cursor 96 * [M-^?] [^W] 97 */ 98 protected el_action_t 99 /*ARGSUSED*/ 100 ed_delete_prev_word(el, c) 101 EditLine *el; 102 int c; 103 { 104 char *cp, *p, *kp; 105 106 if (el->el_line.cursor == el->el_line.buffer) 107 return CC_ERROR; 108 109 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, 110 el->el_state.argument, ce__isword); 111 112 for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++) 113 *kp++ = *p; 114 el->el_chared.c_kill.last = kp; 115 116 c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ 117 el->el_line.cursor = cp; 118 if (el->el_line.cursor < el->el_line.buffer) 119 el->el_line.cursor = el->el_line.buffer; /* bounds check */ 120 return CC_REFRESH; 121 } 122 123 124 /* ed_delete_next_char(): 125 * Delete character under cursor 126 * [^D] [x] 127 */ 128 protected el_action_t 129 /*ARGSUSED*/ 130 ed_delete_next_char(el, c) 131 EditLine *el; 132 int c; 133 { 134 #ifdef notdef /* XXX */ 135 #define EL el->el_line 136 fprintf(stderr, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", 137 EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, EL.lastchar, EL.limit, EL.limit); 138 #endif 139 if (el->el_line.cursor == el->el_line.lastchar) {/* if I'm at the end */ 140 if (el->el_map.type == MAP_VI) { 141 if (el->el_line.cursor == el->el_line.buffer) { 142 /* if I'm also at the beginning */ 143 #ifdef KSHVI 144 return CC_ERROR; 145 #else 146 term_overwrite(el, STReof, 4);/* then do a EOF */ 147 term__flush(); 148 return CC_EOF; 149 #endif 150 } 151 else { 152 #ifdef KSHVI 153 el->el_line.cursor--; 154 #else 155 return CC_ERROR; 156 #endif 157 } 158 } 159 else { 160 if (el->el_line.cursor != el->el_line.buffer) 161 el->el_line.cursor--; 162 else 163 return CC_ERROR; 164 } 165 } 166 c_delafter(el, el->el_state.argument); /* delete after dot */ 167 if (el->el_line.cursor >= el->el_line.lastchar && el->el_line.cursor > el->el_line.buffer) 168 el->el_line.cursor = el->el_line.lastchar - 1; /* bounds check */ 169 return CC_REFRESH; 170 } 171 172 173 /* ed_kill_line(): 174 * Cut to the end of line 175 * [^K] [^K] 176 */ 177 protected el_action_t 178 /*ARGSUSED*/ 179 ed_kill_line(el, c) 180 EditLine *el; 181 int c; 182 { 183 char *kp, *cp; 184 185 cp = el->el_line.cursor; 186 kp = el->el_chared.c_kill.buf; 187 while (cp < el->el_line.lastchar) 188 *kp++ = *cp++; /* copy it */ 189 el->el_chared.c_kill.last = kp; 190 el->el_line.lastchar = el->el_line.cursor; /* zap! -- delete to end */ 191 return CC_REFRESH; 192 } 193 194 195 /* ed_move_to_end(): 196 * Move cursor to the end of line 197 * [^E] [^E] 198 */ 199 protected el_action_t 200 /*ARGSUSED*/ 201 ed_move_to_end(el, c) 202 EditLine *el; 203 int c; 204 { 205 el->el_line.cursor = el->el_line.lastchar; 206 if (el->el_map.type == MAP_VI) { 207 #ifdef VI_MOVE 208 el->el_line.cursor--; 209 #endif 210 if (el->el_chared.c_vcmd.action & DELETE) { 211 cv_delfini(el); 212 return CC_REFRESH; 213 } 214 } 215 return CC_CURSOR; 216 } 217 218 219 /* ed_move_to_beg(): 220 * Move cursor to the beginning of line 221 * [^A] [^A] 222 */ 223 protected el_action_t 224 /*ARGSUSED*/ 225 ed_move_to_beg(el, c) 226 EditLine *el; 227 int c; 228 { 229 el->el_line.cursor = el->el_line.buffer; 230 231 if (el->el_map.type == MAP_VI) { 232 /* We want FIRST non space character */ 233 while (isspace(*el->el_line.cursor)) 234 el->el_line.cursor++; 235 if (el->el_chared.c_vcmd.action & DELETE) { 236 cv_delfini(el); 237 return CC_REFRESH; 238 } 239 } 240 241 return CC_CURSOR; 242 } 243 244 245 /* ed_transpose_chars(): 246 * Exchange the character to the left of the cursor with the one under it 247 * [^T] [^T] 248 */ 249 protected el_action_t 250 ed_transpose_chars(el, c) 251 EditLine *el; 252 int c; 253 { 254 if (el->el_line.cursor < el->el_line.lastchar) { 255 if (el->el_line.lastchar <= &el->el_line.buffer[1]) 256 return CC_ERROR; 257 else 258 el->el_line.cursor++; 259 } 260 if (el->el_line.cursor > &el->el_line.buffer[1]) { 261 /* must have at least two chars entered */ 262 c = el->el_line.cursor[-2]; 263 el->el_line.cursor[-2] = el->el_line.cursor[-1]; 264 el->el_line.cursor[-1] = c; 265 return CC_REFRESH; 266 } 267 else 268 return CC_ERROR; 269 } 270 271 272 /* ed_next_char(): 273 * Move to the right one character 274 * [^F] [^F] 275 */ 276 protected el_action_t 277 /*ARGSUSED*/ 278 ed_next_char(el, c) 279 EditLine *el; 280 int c; 281 { 282 if (el->el_line.cursor >= el->el_line.lastchar) 283 return CC_ERROR; 284 285 el->el_line.cursor += el->el_state.argument; 286 if (el->el_line.cursor > el->el_line.lastchar) 287 el->el_line.cursor = el->el_line.lastchar; 288 289 if (el->el_map.type == MAP_VI) 290 if (el->el_chared.c_vcmd.action & DELETE) { 291 cv_delfini(el); 292 return CC_REFRESH; 293 } 294 295 return CC_CURSOR; 296 } 297 298 299 /* ed_prev_word(): 300 * Move to the beginning of the current word 301 * [M-b] [b] 302 */ 303 protected el_action_t 304 /*ARGSUSED*/ 305 ed_prev_word(el, c) 306 EditLine *el; 307 int c; 308 { 309 if (el->el_line.cursor == el->el_line.buffer) 310 return CC_ERROR; 311 312 el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer, 313 el->el_state.argument, 314 ce__isword); 315 316 if (el->el_map.type == MAP_VI) 317 if (el->el_chared.c_vcmd.action & DELETE) { 318 cv_delfini(el); 319 return CC_REFRESH; 320 } 321 322 return CC_CURSOR; 323 } 324 325 326 /* ed_prev_char(): 327 * Move to the left one character 328 * [^B] [^B] 329 */ 330 protected el_action_t 331 /*ARGSUSED*/ 332 ed_prev_char(el, c) 333 EditLine *el; 334 int c; 335 { 336 if (el->el_line.cursor > el->el_line.buffer) { 337 el->el_line.cursor -= el->el_state.argument; 338 if (el->el_line.cursor < el->el_line.buffer) 339 el->el_line.cursor = el->el_line.buffer; 340 341 if (el->el_map.type == MAP_VI) 342 if (el->el_chared.c_vcmd.action & DELETE) { 343 cv_delfini(el); 344 return CC_REFRESH; 345 } 346 347 return CC_CURSOR; 348 } 349 else 350 return CC_ERROR; 351 } 352 353 354 /* ed_quoted_insert(): 355 * Add the next character typed verbatim 356 * [^V] [^V] 357 */ 358 protected el_action_t 359 ed_quoted_insert(el, c) 360 EditLine *el; 361 int c; 362 { 363 int num; 364 char tc; 365 366 tty_quotemode(el); 367 num = el_getc(el, &tc); 368 c = (unsigned char) tc; 369 tty_noquotemode(el); 370 if (num == 1) 371 return ed_insert(el, c); 372 else 373 return ed_end_of_file(el, 0); 374 } 375 376 377 /* ed_digit(): 378 * Adds to argument or enters a digit 379 */ 380 protected el_action_t 381 ed_digit(el, c) 382 EditLine *el; 383 int c; 384 { 385 if (!isdigit(c)) 386 return CC_ERROR; 387 388 if (el->el_state.doingarg) { 389 /* if doing an arg, add this in... */ 390 if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) 391 el->el_state.argument = c - '0'; 392 else { 393 if (el->el_state.argument > 1000000) 394 return CC_ERROR; 395 el->el_state.argument = 396 (el->el_state.argument * 10) + (c - '0'); 397 } 398 return CC_ARGHACK; 399 } 400 else { 401 if (el->el_line.lastchar + 1 >= el->el_line.limit) 402 return CC_ERROR; 403 404 if (el->el_state.inputmode != MODE_INSERT) { 405 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = 406 *el->el_line.cursor; 407 el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0'; 408 c_delafter(el, 1); 409 } 410 c_insert(el, 1); 411 *el->el_line.cursor++ = c; 412 el->el_state.doingarg = 0; 413 re_fastaddc(el); 414 } 415 return CC_NORM; 416 } 417 418 419 /* ed_argument_digit(): 420 * Digit that starts argument 421 * For ESC-n 422 */ 423 protected el_action_t 424 ed_argument_digit(el, c) 425 EditLine *el; 426 register int c; 427 { 428 if (!isdigit(c)) 429 return CC_ERROR; 430 431 if (el->el_state.doingarg) { 432 if (el->el_state.argument > 1000000) 433 return CC_ERROR; 434 el->el_state.argument = (el->el_state.argument * 10) + (c - '0'); 435 } 436 else { /* else starting an argument */ 437 el->el_state.argument = c - '0'; 438 el->el_state.doingarg = 1; 439 } 440 return CC_ARGHACK; 441 } 442 443 444 /* ed_unassigned(): 445 * Indicates unbound character 446 * Bound to keys that are not assigned 447 */ 448 protected el_action_t 449 /*ARGSUSED*/ 450 ed_unassigned(el, c) 451 EditLine *el; 452 int c; 453 { 454 term_beep(el); 455 term__flush(); 456 return CC_NORM; 457 } 458 459 460 /** 461 ** TTY key handling. 462 **/ 463 464 /* ed_tty_sigint(): 465 * Tty interrupt character 466 * [^C] 467 */ 468 protected el_action_t 469 /*ARGSUSED*/ 470 ed_tty_sigint(el, c) 471 EditLine *el; 472 int c; 473 { 474 return CC_NORM; 475 } 476 477 478 /* ed_tty_dsusp(): 479 * Tty delayed suspend character 480 * [^Y] 481 */ 482 protected el_action_t 483 /*ARGSUSED*/ 484 ed_tty_dsusp(el, c) 485 EditLine *el; 486 int c; 487 { 488 return CC_NORM; 489 } 490 491 492 /* ed_tty_flush_output(): 493 * Tty flush output characters 494 * [^O] 495 */ 496 protected el_action_t 497 /*ARGSUSED*/ 498 ed_tty_flush_output(el, c) 499 EditLine *el; 500 int c; 501 { 502 return CC_NORM; 503 } 504 505 506 /* ed_tty_sigquit(): 507 * Tty quit character 508 * [^\] 509 */ 510 protected el_action_t 511 /*ARGSUSED*/ 512 ed_tty_sigquit(el, c) 513 EditLine *el; 514 int c; 515 { 516 return CC_NORM; 517 } 518 519 520 /* ed_tty_sigtstp(): 521 * Tty suspend character 522 * [^Z] 523 */ 524 protected el_action_t 525 /*ARGSUSED*/ 526 ed_tty_sigtstp(el, c) 527 EditLine *el; 528 int c; 529 { 530 return CC_NORM; 531 } 532 533 534 /* ed_tty_stop_output(): 535 * Tty disallow output characters 536 * [^S] 537 */ 538 protected el_action_t 539 /*ARGSUSED*/ 540 ed_tty_stop_output(el, c) 541 EditLine *el; 542 int c; 543 { 544 return CC_NORM; 545 } 546 547 548 /* ed_tty_start_output(): 549 * Tty allow output characters 550 * [^Q] 551 */ 552 protected el_action_t 553 /*ARGSUSED*/ 554 ed_tty_start_output(el, c) 555 EditLine *el; 556 int c; 557 { 558 return CC_NORM; 559 } 560 561 562 /* ed_newline(): 563 * Execute command 564 * [^J] 565 */ 566 protected el_action_t 567 /*ARGSUSED*/ 568 ed_newline(el, c) 569 EditLine *el; 570 int c; 571 { 572 re_goto_bottom(el); 573 *el->el_line.lastchar++ = '\n'; 574 *el->el_line.lastchar = '\0'; 575 if (el->el_map.type == MAP_VI) 576 el->el_chared.c_vcmd.ins = el->el_line.buffer; 577 return CC_NEWLINE; 578 } 579 580 581 /* ed_delete_prev_char(): 582 * Delete the character to the left of the cursor 583 * [^?] 584 */ 585 protected el_action_t 586 /*ARGSUSED*/ 587 ed_delete_prev_char(el, c) 588 EditLine *el; 589 int c; 590 { 591 if (el->el_line.cursor <= el->el_line.buffer) 592 return CC_ERROR; 593 594 c_delbefore(el, el->el_state.argument); 595 el->el_line.cursor -= el->el_state.argument; 596 if (el->el_line.cursor < el->el_line.buffer) 597 el->el_line.cursor = el->el_line.buffer; 598 return CC_REFRESH; 599 } 600 601 602 /* ed_clear_screen(): 603 * Clear screen leaving current line at the top 604 * [^L] 605 */ 606 protected el_action_t 607 /*ARGSUSED*/ 608 ed_clear_screen(el, c) 609 EditLine *el; 610 int c; 611 { 612 term_clear_screen(el); /* clear the whole real screen */ 613 re_clear_display(el); /* reset everything */ 614 return CC_REFRESH; 615 } 616 617 618 /* ed_redisplay(): 619 * Redisplay everything 620 * ^R 621 */ 622 protected el_action_t 623 /*ARGSUSED*/ 624 ed_redisplay(el, c) 625 EditLine *el; 626 int c; 627 { 628 re_clear_lines(el); 629 re_clear_display(el); 630 return CC_REFRESH; 631 } 632 633 634 /* ed_start_over(): 635 * Erase current line and start from scratch 636 * [^G] 637 */ 638 protected el_action_t 639 /*ARGSUSED*/ 640 ed_start_over(el, c) 641 EditLine *el; 642 int c; 643 { 644 ch_reset(el); 645 return CC_REFRESH; 646 } 647 648 649 /* ed_sequence_lead_in(): 650 * First character in a bound sequence 651 * Placeholder for external keys 652 */ 653 protected el_action_t 654 /*ARGSUSED*/ 655 ed_sequence_lead_in(el, c) 656 EditLine *el; 657 int c; 658 { 659 return CC_NORM; 660 } 661 662 663 /* ed_prev_history(): 664 * Move to the previous history line 665 * [^P] [k] 666 */ 667 protected el_action_t 668 /*ARGSUSED*/ 669 ed_prev_history(el, c) 670 EditLine *el; 671 int c; 672 { 673 char beep = 0; 674 675 el->el_chared.c_undo.action = NOP; 676 *el->el_line.lastchar = '\0'; /* just in case */ 677 678 if (el->el_history.eventno == 0) { /* save the current buffer away */ 679 (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); 680 el->el_history.last = el->el_history.buf + 681 (el->el_line.lastchar - el->el_line.buffer); 682 } 683 684 el->el_history.eventno += el->el_state.argument; 685 686 if (hist_get(el) == CC_ERROR) { 687 beep = 1; 688 /* el->el_history.eventno was fixed by first call */ 689 (void) hist_get(el); 690 } 691 692 re_refresh(el); 693 if (beep) 694 return CC_ERROR; 695 else 696 return CC_NORM; /* was CC_UP_HIST */ 697 } 698 699 700 /* ed_next_history(): 701 * Move to the next history line 702 * [^N] [j] 703 */ 704 protected el_action_t 705 /*ARGSUSED*/ 706 ed_next_history(el, c) 707 EditLine *el; 708 int c; 709 { 710 el->el_chared.c_undo.action = NOP; 711 *el->el_line.lastchar = '\0'; /* just in case */ 712 713 el->el_history.eventno -= el->el_state.argument; 714 715 if (el->el_history.eventno < 0) { 716 el->el_history.eventno = 0; 717 return CC_ERROR; /* make it beep */ 718 } 719 720 return hist_get(el); 721 } 722 723 724 /* ed_search_prev_history(): 725 * Search previous in history for a line matching the current 726 * next search history [M-P] [K] 727 */ 728 protected el_action_t 729 /*ARGSUSED*/ 730 ed_search_prev_history(el, c) 731 EditLine *el; 732 int c; 733 { 734 const char *hp; 735 int h; 736 bool_t found = 0; 737 738 el->el_chared.c_vcmd.action = NOP; 739 el->el_chared.c_undo.action = NOP; 740 *el->el_line.lastchar = '\0'; /* just in case */ 741 if (el->el_history.eventno < 0) { 742 #ifdef DEBUG_EDIT 743 (void) fprintf(el->el_errfile, "e_prev_search_hist(): eventno < 0;\n"); 744 #endif 745 el->el_history.eventno = 0; 746 return CC_ERROR; 747 } 748 749 if (el->el_history.eventno == 0) { 750 (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); 751 el->el_history.last = el->el_history.buf + 752 (el->el_line.lastchar - el->el_line.buffer); 753 } 754 755 756 if (el->el_history.ref == NULL) 757 return CC_ERROR; 758 759 hp = HIST_FIRST(el); 760 if (hp == NULL) 761 return CC_ERROR; 762 763 c_setpat(el); /* Set search pattern !! */ 764 765 for (h = 1; h <= el->el_history.eventno; h++) 766 hp = HIST_NEXT(el); 767 768 while (hp != NULL) { 769 #ifdef SDEBUG 770 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); 771 #endif 772 if ((strncmp(hp, el->el_line.buffer, 773 el->el_line.lastchar - el->el_line.buffer) || 774 hp[el->el_line.lastchar-el->el_line.buffer]) && 775 c_hmatch(el, hp)) { 776 found++; 777 break; 778 } 779 h++; 780 hp = HIST_NEXT(el); 781 } 782 783 if (!found) { 784 #ifdef SDEBUG 785 (void) fprintf(el->el_errfile, "not found\n"); 786 #endif 787 return CC_ERROR; 788 } 789 790 el->el_history.eventno = h; 791 792 return hist_get(el); 793 } 794 795 796 /* ed_search_next_history(): 797 * Search next in history for a line matching the current 798 * [M-N] [J] 799 */ 800 protected el_action_t 801 /*ARGSUSED*/ 802 ed_search_next_history(el, c) 803 EditLine *el; 804 int c; 805 { 806 const char *hp; 807 int h; 808 bool_t found = 0; 809 810 el->el_chared.c_vcmd.action = NOP; 811 el->el_chared.c_undo.action = NOP; 812 *el->el_line.lastchar = '\0'; /* just in case */ 813 814 if (el->el_history.eventno == 0) 815 return CC_ERROR; 816 817 if (el->el_history.ref == NULL) 818 return CC_ERROR; 819 820 hp = HIST_FIRST(el); 821 if (hp == NULL) 822 return CC_ERROR; 823 824 c_setpat(el); /* Set search pattern !! */ 825 826 for (h = 1; h < el->el_history.eventno && hp; h++) { 827 #ifdef SDEBUG 828 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); 829 #endif 830 if ((strncmp(hp, el->el_line.buffer, 831 el->el_line.lastchar - el->el_line.buffer) || 832 hp[el->el_line.lastchar-el->el_line.buffer]) && 833 c_hmatch(el, hp)) 834 found = h; 835 hp = HIST_NEXT(el); 836 } 837 838 if (!found) { /* is it the current history number? */ 839 if (!c_hmatch(el, el->el_history.buf)) { 840 #ifdef SDEBUG 841 (void) fprintf(el->el_errfile, "not found\n"); 842 #endif 843 return CC_ERROR; 844 } 845 } 846 847 el->el_history.eventno = found; 848 849 return hist_get(el); 850 } 851 852 853 /* ed_prev_line(): 854 * Move up one line 855 * Could be [k] [^p] 856 */ 857 protected el_action_t 858 /*ARGSUSED*/ 859 ed_prev_line(el, c) 860 EditLine *el; 861 int c; 862 { 863 char *ptr; 864 int nchars = c_hpos(el); 865 866 /* 867 * Move to the line requested 868 */ 869 if (*(ptr = el->el_line.cursor) == '\n') 870 ptr--; 871 872 for (; ptr >= el->el_line.buffer; ptr--) 873 if (*ptr == '\n' && --el->el_state.argument <= 0) 874 break; 875 876 if (el->el_state.argument > 0) 877 return CC_ERROR; 878 879 /* 880 * Move to the beginning of the line 881 */ 882 for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) 883 continue; 884 885 /* 886 * Move to the character requested 887 */ 888 for (ptr++; 889 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 890 ptr++) 891 continue; 892 893 el->el_line.cursor = ptr; 894 return CC_CURSOR; 895 } 896 897 898 /* ed_next_line(): 899 * Move down one line 900 * Could be [j] [^n] 901 */ 902 protected el_action_t 903 /*ARGSUSED*/ 904 ed_next_line(el, c) 905 EditLine *el; 906 int c; 907 { 908 char *ptr; 909 int nchars = c_hpos(el); 910 911 /* 912 * Move to the line requested 913 */ 914 for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) 915 if (*ptr == '\n' && --el->el_state.argument <= 0) 916 break; 917 918 if (el->el_state.argument > 0) 919 return CC_ERROR; 920 921 /* 922 * Move to the character requested 923 */ 924 for (ptr++; 925 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 926 ptr++) 927 continue; 928 929 el->el_line.cursor = ptr; 930 return CC_CURSOR; 931 } 932 933 934 /* ed_command(): 935 * Editline extended command 936 * [M-X] [:] 937 */ 938 protected el_action_t 939 /*ARGSUSED*/ 940 ed_command(el, c) 941 EditLine *el; 942 int c; 943 { 944 char tmpbuf[EL_BUFSIZ]; 945 int tmplen; 946 947 el->el_line.buffer[0] = '\0'; 948 el->el_line.lastchar = el->el_line.buffer; 949 el->el_line.cursor = el->el_line.buffer; 950 951 c_insert(el, 3); /* prompt + ": " */ 952 *el->el_line.cursor++ = '\n'; 953 *el->el_line.cursor++ = ':'; 954 *el->el_line.cursor++ = ' '; 955 re_refresh(el); 956 957 tmplen = c_gets(el, tmpbuf); 958 tmpbuf[tmplen] = '\0'; 959 960 el->el_line.buffer[0] = '\0'; 961 el->el_line.lastchar = el->el_line.buffer; 962 el->el_line.cursor = el->el_line.buffer; 963 964 if (parse_line(el, tmpbuf) == -1) 965 return CC_ERROR; 966 else 967 return CC_REFRESH; 968 } 969