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