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