1/* $NetBSD: common.c,v 1.49 2020/03/30 06:54:37 ryo 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 38static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; 39#else 40__RCSID("$NetBSD: common.c,v 1.49 2020/03/30 06:54:37 ryo 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 */ 60libedit_private el_action_t 61/*ARGSUSED*/ 62ed_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 */ 75libedit_private el_action_t 76ed_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 */ 117libedit_private el_action_t 118/*ARGSUSED*/ 119ed_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 */ 145libedit_private el_action_t 146/*ARGSUSED*/ 147ed_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 */ 192libedit_private el_action_t 193/*ARGSUSED*/ 194ed_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 */ 213libedit_private el_action_t 214/*ARGSUSED*/ 215ed_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 */ 236libedit_private el_action_t 237/*ARGSUSED*/ 238ed_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 */ 260libedit_private el_action_t 261ed_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 */ 285libedit_private el_action_t 286/*ARGSUSED*/ 287ed_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 */ 314libedit_private el_action_t 315/*ARGSUSED*/ 316ed_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 */ 340libedit_private el_action_t 341/*ARGSUSED*/ 342ed_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 */ 365libedit_private el_action_t 366/*ARGSUSED*/ 367ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__))) 368{ 369 int num; 370 wchar_t ch; 371 372 tty_quotemode(el); 373 num = el_wgetc(el, &ch); 374 tty_noquotemode(el); 375 if (num == 1) 376 return ed_insert(el, ch); 377 else 378 return ed_end_of_file(el, 0); 379} 380 381 382/* ed_digit(): 383 * Adds to argument or enters a digit 384 */ 385libedit_private el_action_t 386ed_digit(EditLine *el, wint_t c) 387{ 388 389 if (!iswdigit(c)) 390 return CC_ERROR; 391 392 if (el->el_state.doingarg) { 393 /* if doing an arg, add this in... */ 394 if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) 395 el->el_state.argument = c - '0'; 396 else { 397 if (el->el_state.argument > 1000000) 398 return CC_ERROR; 399 el->el_state.argument = 400 (el->el_state.argument * 10) + (c - '0'); 401 } 402 return CC_ARGHACK; 403 } 404 405 return ed_insert(el, c); 406} 407 408 409/* ed_argument_digit(): 410 * Digit that starts argument 411 * For ESC-n 412 */ 413libedit_private el_action_t 414ed_argument_digit(EditLine *el, wint_t c) 415{ 416 417 if (!iswdigit(c)) 418 return CC_ERROR; 419 420 if (el->el_state.doingarg) { 421 if (el->el_state.argument > 1000000) 422 return CC_ERROR; 423 el->el_state.argument = (el->el_state.argument * 10) + 424 (c - '0'); 425 } else { /* else starting an argument */ 426 el->el_state.argument = c - '0'; 427 el->el_state.doingarg = 1; 428 } 429 return CC_ARGHACK; 430} 431 432 433/* ed_unassigned(): 434 * Indicates unbound character 435 * Bound to keys that are not assigned 436 */ 437libedit_private el_action_t 438/*ARGSUSED*/ 439ed_unassigned(EditLine *el __attribute__((__unused__)), 440 wint_t c __attribute__((__unused__))) 441{ 442 443 return CC_ERROR; 444} 445 446 447/* ed_ignore(): 448 * Input characters that have no effect 449 * [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\] 450 */ 451libedit_private el_action_t 452/*ARGSUSED*/ 453ed_ignore(EditLine *el __attribute__((__unused__)), 454 wint_t c __attribute__((__unused__))) 455{ 456 457 return CC_NORM; 458} 459 460 461/* ed_newline(): 462 * Execute command 463 * [^J] 464 */ 465libedit_private el_action_t 466/*ARGSUSED*/ 467ed_newline(EditLine *el, wint_t c __attribute__((__unused__))) 468{ 469 470 re_goto_bottom(el); 471 *el->el_line.lastchar++ = '\n'; 472 *el->el_line.lastchar = '\0'; 473 return CC_NEWLINE; 474} 475 476 477/* ed_delete_prev_char(): 478 * Delete the character to the left of the cursor 479 * [^?] 480 */ 481libedit_private el_action_t 482/*ARGSUSED*/ 483ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) 484{ 485 486 if (el->el_line.cursor <= el->el_line.buffer) 487 return CC_ERROR; 488 489 c_delbefore(el, el->el_state.argument); 490 el->el_line.cursor -= el->el_state.argument; 491 if (el->el_line.cursor < el->el_line.buffer) 492 el->el_line.cursor = el->el_line.buffer; 493 return CC_REFRESH; 494} 495 496 497/* ed_clear_screen(): 498 * Clear screen leaving current line at the top 499 * [^L] 500 */ 501libedit_private el_action_t 502/*ARGSUSED*/ 503ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__))) 504{ 505 506 terminal_clear_screen(el); /* clear the whole real screen */ 507 re_clear_display(el); /* reset everything */ 508 return CC_REFRESH; 509} 510 511 512/* ed_redisplay(): 513 * Redisplay everything 514 * ^R 515 */ 516libedit_private el_action_t 517/*ARGSUSED*/ 518ed_redisplay(EditLine *el __attribute__((__unused__)), 519 wint_t c __attribute__((__unused__))) 520{ 521 522 return CC_REDISPLAY; 523} 524 525 526/* ed_start_over(): 527 * Erase current line and start from scratch 528 * [^G] 529 */ 530libedit_private el_action_t 531/*ARGSUSED*/ 532ed_start_over(EditLine *el, wint_t c __attribute__((__unused__))) 533{ 534 535 ch_reset(el); 536 return CC_REFRESH; 537} 538 539 540/* ed_sequence_lead_in(): 541 * First character in a bound sequence 542 * Placeholder for external keys 543 */ 544libedit_private el_action_t 545/*ARGSUSED*/ 546ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), 547 wint_t c __attribute__((__unused__))) 548{ 549 550 return CC_NORM; 551} 552 553 554/* ed_prev_history(): 555 * Move to the previous history line 556 * [^P] [k] 557 */ 558libedit_private el_action_t 559/*ARGSUSED*/ 560ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__))) 561{ 562 char beep = 0; 563 int sv_event = el->el_history.eventno; 564 565 el->el_chared.c_undo.len = -1; 566 *el->el_line.lastchar = '\0'; /* just in case */ 567 568 if (el->el_history.eventno == 0) { /* save the current buffer 569 * away */ 570 (void) wcsncpy(el->el_history.buf, el->el_line.buffer, 571 EL_BUFSIZ); 572 el->el_history.last = el->el_history.buf + 573 (el->el_line.lastchar - el->el_line.buffer); 574 } 575 el->el_history.eventno += el->el_state.argument; 576 577 if (hist_get(el) == CC_ERROR) { 578 if (el->el_map.type == MAP_VI) { 579 el->el_history.eventno = sv_event; 580 } 581 beep = 1; 582 /* el->el_history.eventno was fixed by first call */ 583 (void) hist_get(el); 584 } 585 if (beep) 586 return CC_REFRESH_BEEP; 587 return CC_REFRESH; 588} 589 590 591/* ed_next_history(): 592 * Move to the next history line 593 * [^N] [j] 594 */ 595libedit_private el_action_t 596/*ARGSUSED*/ 597ed_next_history(EditLine *el, wint_t c __attribute__((__unused__))) 598{ 599 el_action_t beep = CC_REFRESH, rval; 600 601 el->el_chared.c_undo.len = -1; 602 *el->el_line.lastchar = '\0'; /* just in case */ 603 604 el->el_history.eventno -= el->el_state.argument; 605 606 if (el->el_history.eventno < 0) { 607 el->el_history.eventno = 0; 608 beep = CC_REFRESH_BEEP; 609 } 610 rval = hist_get(el); 611 if (rval == CC_REFRESH) 612 return beep; 613 return rval; 614 615} 616 617 618/* ed_search_prev_history(): 619 * Search previous in history for a line matching the current 620 * next search history [M-P] [K] 621 */ 622libedit_private el_action_t 623/*ARGSUSED*/ 624ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__))) 625{ 626 const wchar_t *hp; 627 int h; 628 int found = 0; 629 630 el->el_chared.c_vcmd.action = NOP; 631 el->el_chared.c_undo.len = -1; 632 *el->el_line.lastchar = '\0'; /* just in case */ 633 if (el->el_history.eventno < 0) { 634#ifdef DEBUG_EDIT 635 (void) fprintf(el->el_errfile, 636 "e_prev_search_hist(): eventno < 0;\n"); 637#endif 638 el->el_history.eventno = 0; 639 return CC_ERROR; 640 } 641 if (el->el_history.eventno == 0) { 642 (void) wcsncpy(el->el_history.buf, el->el_line.buffer, 643 EL_BUFSIZ); 644 el->el_history.last = el->el_history.buf + 645 (el->el_line.lastchar - el->el_line.buffer); 646 } 647 if (el->el_history.ref == NULL) 648 return CC_ERROR; 649 650 hp = HIST_FIRST(el); 651 if (hp == NULL) 652 return CC_ERROR; 653 654 c_setpat(el); /* Set search pattern !! */ 655 656 for (h = 1; h <= el->el_history.eventno; h++) 657 hp = HIST_NEXT(el); 658 659 while (hp != NULL) { 660#ifdef SDEBUG 661 (void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp); 662#endif 663 if ((wcsncmp(hp, el->el_line.buffer, (size_t) 664 (el->el_line.lastchar - el->el_line.buffer)) || 665 hp[el->el_line.lastchar - el->el_line.buffer]) && 666 c_hmatch(el, hp)) { 667 found = 1; 668 break; 669 } 670 h++; 671 hp = HIST_NEXT(el); 672 } 673 674 if (!found) { 675#ifdef SDEBUG 676 (void) fprintf(el->el_errfile, "not found\n"); 677#endif 678 return CC_ERROR; 679 } 680 el->el_history.eventno = h; 681 682 return hist_get(el); 683} 684 685 686/* ed_search_next_history(): 687 * Search next in history for a line matching the current 688 * [M-N] [J] 689 */ 690libedit_private el_action_t 691/*ARGSUSED*/ 692ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__))) 693{ 694 const wchar_t *hp; 695 int h; 696 int found = 0; 697 698 el->el_chared.c_vcmd.action = NOP; 699 el->el_chared.c_undo.len = -1; 700 *el->el_line.lastchar = '\0'; /* just in case */ 701 702 if (el->el_history.eventno == 0) 703 return CC_ERROR; 704 705 if (el->el_history.ref == NULL) 706 return CC_ERROR; 707 708 hp = HIST_FIRST(el); 709 if (hp == NULL) 710 return CC_ERROR; 711 712 c_setpat(el); /* Set search pattern !! */ 713 714 for (h = 1; h < el->el_history.eventno && hp; h++) { 715#ifdef SDEBUG 716 (void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp); 717#endif 718 if ((wcsncmp(hp, el->el_line.buffer, (size_t) 719 (el->el_line.lastchar - el->el_line.buffer)) || 720 hp[el->el_line.lastchar - el->el_line.buffer]) && 721 c_hmatch(el, hp)) 722 found = h; 723 hp = HIST_NEXT(el); 724 } 725 726 if (!found) { /* is it the current history number? */ 727 if (!c_hmatch(el, el->el_history.buf)) { 728#ifdef SDEBUG 729 (void) fprintf(el->el_errfile, "not found\n"); 730#endif 731 return CC_ERROR; 732 } 733 } 734 el->el_history.eventno = found; 735 736 return hist_get(el); 737} 738 739 740/* ed_prev_line(): 741 * Move up one line 742 * Could be [k] [^p] 743 */ 744libedit_private el_action_t 745/*ARGSUSED*/ 746ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__))) 747{ 748 wchar_t *ptr; 749 int nchars = c_hpos(el); 750 751 /* 752 * Move to the line requested 753 */ 754 if (*(ptr = el->el_line.cursor) == '\n') 755 ptr--; 756 757 for (; ptr >= el->el_line.buffer; ptr--) 758 if (*ptr == '\n' && --el->el_state.argument <= 0) 759 break; 760 761 if (el->el_state.argument > 0) 762 return CC_ERROR; 763 764 /* 765 * Move to the beginning of the line 766 */ 767 for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) 768 continue; 769 770 /* 771 * Move to the character requested 772 */ 773 for (ptr++; 774 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 775 ptr++) 776 continue; 777 778 el->el_line.cursor = ptr; 779 return CC_CURSOR; 780} 781 782 783/* ed_next_line(): 784 * Move down one line 785 * Could be [j] [^n] 786 */ 787libedit_private el_action_t 788/*ARGSUSED*/ 789ed_next_line(EditLine *el, wint_t c __attribute__((__unused__))) 790{ 791 wchar_t *ptr; 792 int nchars = c_hpos(el); 793 794 /* 795 * Move to the line requested 796 */ 797 for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) 798 if (*ptr == '\n' && --el->el_state.argument <= 0) 799 break; 800 801 if (el->el_state.argument > 0) 802 return CC_ERROR; 803 804 /* 805 * Move to the character requested 806 */ 807 for (ptr++; 808 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 809 ptr++) 810 continue; 811 812 el->el_line.cursor = ptr; 813 return CC_CURSOR; 814} 815 816 817/* ed_command(): 818 * Editline extended command 819 * [M-X] [:] 820 */ 821libedit_private el_action_t 822/*ARGSUSED*/ 823ed_command(EditLine *el, wint_t c __attribute__((__unused__))) 824{ 825 wchar_t tmpbuf[EL_BUFSIZ]; 826 int tmplen; 827 828 tmplen = c_gets(el, tmpbuf, L"\n: "); 829 terminal__putc(el, '\n'); 830 831 if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) 832 terminal_beep(el); 833 834 el->el_map.current = el->el_map.key; 835 re_clear_display(el); 836 return CC_REFRESH; 837} 838