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