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