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