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