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