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