1 /* $NetBSD: chared.c,v 1.65 2025/12/14 18:07:40 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[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; 39 #else 40 __RCSID("$NetBSD: chared.c,v 1.65 2025/12/14 18:07:40 christos Exp $"); 41 #endif 42 #endif /* not lint && not SCCSID */ 43 44 /* 45 * chared.c: Character editor utilities 46 */ 47 #include <ctype.h> 48 #include <stdlib.h> 49 #include <string.h> 50 51 #include "el.h" 52 #include "common.h" 53 #include "fcns.h" 54 55 /* value to leave unused in line buffer */ 56 #define EL_LEAVE 2 57 58 /* cv_undo(): 59 * Handle state for the vi undo command 60 */ 61 libedit_private void 62 cv_undo(EditLine *el) 63 { 64 c_undo_t *vu = &el->el_chared.c_undo; 65 c_redo_t *r = &el->el_chared.c_redo; 66 size_t size; 67 68 /* Save entire line for undo */ 69 size = (size_t)(el->el_line.lastchar - el->el_line.buffer); 70 vu->len = (ssize_t)size; 71 vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer); 72 (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf)); 73 74 /* save command info for redo */ 75 r->count = el->el_state.doingarg ? el->el_state.argument : 0; 76 r->action = el->el_chared.c_vcmd.action; 77 r->pos = r->buf; 78 r->cmd = el->el_state.thiscmd; 79 r->ch = el->el_state.thisch; 80 } 81 82 /* cv_yank(): 83 * Save yank/delete data for paste 84 */ 85 libedit_private void 86 cv_yank(EditLine *el, const wchar_t *ptr, int size) 87 { 88 c_kill_t *k = &el->el_chared.c_kill; 89 90 (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf)); 91 k->last = k->buf + size; 92 } 93 94 95 /* c_insert(): 96 * Insert num characters 97 */ 98 libedit_private void 99 c_insert(EditLine *el, int num) 100 { 101 wchar_t *cp; 102 103 if (el->el_line.lastchar + num >= el->el_line.limit) { 104 if (!ch_enlargebufs(el, (size_t)num)) 105 return; /* can't go past end of buffer */ 106 } 107 108 if (el->el_line.cursor < el->el_line.lastchar) { 109 /* if I must move chars */ 110 for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) 111 cp[num] = *cp; 112 } 113 el->el_line.lastchar += num; 114 } 115 116 117 /* c_delafter(): 118 * Delete num characters after the cursor 119 */ 120 libedit_private void 121 c_delafter(EditLine *el, int num) 122 { 123 124 if (el->el_line.cursor + num > el->el_line.lastchar) 125 num = (int)(el->el_line.lastchar - el->el_line.cursor); 126 127 if (el->el_map.current != el->el_map.emacs) { 128 cv_undo(el); 129 cv_yank(el, el->el_line.cursor, num); 130 } 131 132 if (num > 0) { 133 wchar_t *cp; 134 135 for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) 136 *cp = cp[num]; 137 138 el->el_line.lastchar -= num; 139 } 140 } 141 142 143 /* c_delafter1(): 144 * Delete the character after the cursor, do not yank 145 */ 146 libedit_private void 147 c_delafter1(EditLine *el) 148 { 149 wchar_t *cp; 150 151 for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) 152 *cp = cp[1]; 153 154 el->el_line.lastchar--; 155 } 156 157 158 /* c_delbefore(): 159 * Delete num characters before the cursor 160 */ 161 libedit_private void 162 c_delbefore(EditLine *el, int num) 163 { 164 165 if (el->el_line.cursor - num < el->el_line.buffer) 166 num = (int)(el->el_line.cursor - el->el_line.buffer); 167 168 if (el->el_map.current != el->el_map.emacs) { 169 cv_undo(el); 170 cv_yank(el, el->el_line.cursor - num, num); 171 } 172 173 if (num > 0) { 174 wchar_t *cp; 175 176 for (cp = el->el_line.cursor - num; 177 &cp[num] <= el->el_line.lastchar; 178 cp++) 179 *cp = cp[num]; 180 181 el->el_line.lastchar -= num; 182 } 183 } 184 185 186 /* c_delbefore1(): 187 * Delete the character before the cursor, do not yank 188 */ 189 libedit_private void 190 c_delbefore1(EditLine *el) 191 { 192 wchar_t *cp; 193 194 for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) 195 *cp = cp[1]; 196 197 el->el_line.lastchar--; 198 } 199 200 201 /* ce__isword(): 202 * Return if p is part of a word according to emacs 203 */ 204 libedit_private int 205 ce__isword(EditLine *el, wint_t p) 206 { 207 return iswalnum(p) || wcschr(el->el_map.wordchars, p) != NULL; 208 } 209 210 211 /* cv__isword(): 212 * Return if p is part of a word according to vi 213 */ 214 libedit_private int 215 cv__isword(EditLine *el, wint_t p) 216 { 217 if (iswalnum(p) || wcschr(el->el_map.wordchars, p) != NULL) 218 return 1; 219 if (iswgraph(p)) 220 return 2; 221 return 0; 222 } 223 224 225 /* cv__isWord(): 226 * Return if p is part of a big word according to vi 227 */ 228 libedit_private int 229 cv__isWord(EditLine *el __attribute__((__unused__)), wint_t p) 230 { 231 return !iswspace(p); 232 } 233 234 235 /* c__prev_word(): 236 * Find the previous word 237 */ 238 libedit_private wchar_t * 239 c__prev_word(EditLine *el, wchar_t *p, wchar_t *low, int n, 240 int (*wtest)(EditLine *, wint_t)) 241 { 242 p--; 243 244 while (n--) { 245 while ((p >= low) && !(*wtest)(el, *p)) 246 p--; 247 while ((p >= low) && (*wtest)(el, *p)) 248 p--; 249 } 250 251 /* cp now points to one character before the word */ 252 p++; 253 if (p < low) 254 p = low; 255 /* cp now points where we want it */ 256 return p; 257 } 258 259 260 /* c__next_word(): 261 * Find the next word 262 */ 263 libedit_private wchar_t * 264 c__next_word(EditLine *el, wchar_t *p, wchar_t *high, int n, 265 int (*wtest)(EditLine *, wint_t)) 266 { 267 while (n--) { 268 while ((p < high) && !(*wtest)(el, *p)) 269 p++; 270 while ((p < high) && (*wtest)(el, *p)) 271 p++; 272 } 273 if (p > high) 274 p = high; 275 /* p now points where we want it */ 276 return p; 277 } 278 279 /* cv_next_word(): 280 * Find the next word vi style 281 */ 282 libedit_private wchar_t * 283 cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n, 284 int (*wtest)(EditLine *el, wint_t)) 285 { 286 int test; 287 288 while (n--) { 289 test = (*wtest)(el, *p); 290 while ((p < high) && (*wtest)(el, *p) == test) 291 p++; 292 /* 293 * vi historically deletes with cw only the word preserving the 294 * trailing whitespace! This is not what 'w' does.. 295 */ 296 if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) 297 while ((p < high) && iswspace(*p)) 298 p++; 299 } 300 301 /* p now points where we want it */ 302 if (p > high) 303 return high; 304 else 305 return p; 306 } 307 308 309 /* cv_prev_word(): 310 * Find the previous word vi style 311 */ 312 libedit_private wchar_t * 313 cv_prev_word(EditLine *el, wchar_t *p, wchar_t *low, int n, 314 int (*wtest)(EditLine *el, wint_t)) 315 { 316 int test; 317 318 p--; 319 while (n--) { 320 while ((p > low) && iswspace(*p)) 321 p--; 322 test = (*wtest)(el, *p); 323 while ((p >= low) && (*wtest)(el, *p) == test) 324 p--; 325 if (p < low) 326 return low; 327 } 328 p++; 329 330 /* p now points where we want it */ 331 if (p < low) 332 return low; 333 else 334 return p; 335 } 336 337 338 /* cv_delfini(): 339 * Finish vi delete action 340 */ 341 libedit_private void 342 cv_delfini(EditLine *el) 343 { 344 int size; 345 int action = el->el_chared.c_vcmd.action; 346 347 if (action & INSERT) 348 el->el_map.current = el->el_map.key; 349 350 if (el->el_chared.c_vcmd.pos == 0) 351 /* sanity */ 352 return; 353 354 size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos); 355 if (size == 0) 356 size = 1; 357 el->el_line.cursor = el->el_chared.c_vcmd.pos; 358 if (action & YANK) { 359 if (size > 0) 360 cv_yank(el, el->el_line.cursor, size); 361 else 362 cv_yank(el, el->el_line.cursor + size, -size); 363 } else { 364 if (size > 0) { 365 c_delafter(el, size); 366 re_refresh_cursor(el); 367 } else { 368 c_delbefore(el, -size); 369 el->el_line.cursor += size; 370 } 371 } 372 el->el_chared.c_vcmd.action = NOP; 373 } 374 375 376 /* cv__endword(): 377 * Go to the end of this word according to vi 378 */ 379 libedit_private wchar_t * 380 cv__endword(EditLine *el, wchar_t *p, wchar_t *high, int n, 381 int (*wtest)(EditLine *, wint_t)) 382 { 383 int test; 384 385 p++; 386 387 while (n--) { 388 while ((p < high) && iswspace(*p)) 389 p++; 390 391 test = (*wtest)(el, *p); 392 while ((p < high) && (*wtest)(el, *p) == test) 393 p++; 394 } 395 p--; 396 return p; 397 } 398 399 /* ch_init(): 400 * Initialize the character editor 401 */ 402 libedit_private int 403 ch_init(EditLine *el) 404 { 405 el->el_line.buffer = el_calloc(EL_BUFSIZ, 406 sizeof(*el->el_line.buffer)); 407 if (el->el_line.buffer == NULL) 408 return -1; 409 410 el->el_line.cursor = el->el_line.buffer; 411 el->el_line.lastchar = el->el_line.buffer; 412 el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; 413 414 el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ, 415 sizeof(*el->el_chared.c_undo.buf)); 416 if (el->el_chared.c_undo.buf == NULL) 417 return -1; 418 el->el_chared.c_undo.len = -1; 419 el->el_chared.c_undo.cursor = 0; 420 el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ, 421 sizeof(*el->el_chared.c_redo.buf)); 422 if (el->el_chared.c_redo.buf == NULL) 423 goto out; 424 el->el_chared.c_redo.pos = el->el_chared.c_redo.buf; 425 el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ; 426 el->el_chared.c_redo.cmd = ED_UNASSIGNED; 427 428 el->el_chared.c_vcmd.action = NOP; 429 el->el_chared.c_vcmd.pos = el->el_line.buffer; 430 431 el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ, 432 sizeof(*el->el_chared.c_kill.buf)); 433 if (el->el_chared.c_kill.buf == NULL) 434 goto out; 435 el->el_chared.c_kill.mark = el->el_line.buffer; 436 el->el_chared.c_kill.last = el->el_chared.c_kill.buf; 437 el->el_chared.c_resizefun = NULL; 438 el->el_chared.c_resizearg = NULL; 439 el->el_chared.c_aliasfun = NULL; 440 el->el_chared.c_aliasarg = NULL; 441 442 el->el_map.current = el->el_map.key; 443 444 el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 445 el->el_state.doingarg = 0; 446 el->el_state.metanext = 0; 447 el->el_state.argument = 1; 448 el->el_state.lastcmd = ED_UNASSIGNED; 449 450 return 0; 451 out: 452 ch_end(el); 453 return -1; 454 } 455 456 /* ch_reset(): 457 * Reset the character editor 458 */ 459 libedit_private void 460 ch_reset(EditLine *el) 461 { 462 el->el_line.cursor = el->el_line.buffer; 463 el->el_line.lastchar = el->el_line.buffer; 464 465 el->el_chared.c_undo.len = -1; 466 el->el_chared.c_undo.cursor = 0; 467 468 el->el_chared.c_vcmd.action = NOP; 469 el->el_chared.c_vcmd.pos = el->el_line.buffer; 470 471 el->el_chared.c_kill.mark = el->el_line.buffer; 472 473 el->el_map.current = el->el_map.key; 474 475 el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 476 el->el_state.doingarg = 0; 477 el->el_state.metanext = 0; 478 el->el_state.argument = 1; 479 el->el_state.lastcmd = ED_UNASSIGNED; 480 481 el->el_history.eventno = 0; 482 } 483 484 /* ch_enlargebufs(): 485 * Enlarge line buffer to be able to hold twice as much characters. 486 * Returns 1 if successful, 0 if not. 487 */ 488 libedit_private int 489 ch_enlargebufs(EditLine *el, size_t addlen) 490 { 491 size_t sz, newsz; 492 wchar_t *newbuffer, *oldbuf, *oldkbuf; 493 494 sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE); 495 newsz = sz * 2; 496 /* 497 * If newly required length is longer than current buffer, we need 498 * to make the buffer big enough to hold both old and new stuff. 499 */ 500 if (addlen > sz) { 501 while(newsz - sz < addlen) 502 newsz *= 2; 503 } 504 505 /* 506 * Reallocate line buffer. 507 */ 508 newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer)); 509 if (!newbuffer) 510 return 0; 511 512 /* zero the newly added memory, leave old data in */ 513 (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 514 515 oldbuf = el->el_line.buffer; 516 517 el->el_line.buffer = newbuffer; 518 el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); 519 el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); 520 /* don't set new size until all buffers are enlarged */ 521 el->el_line.limit = &newbuffer[sz - EL_LEAVE]; 522 523 /* 524 * Reallocate kill buffer. 525 */ 526 newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * 527 sizeof(*newbuffer)); 528 if (!newbuffer) 529 return 0; 530 531 /* zero the newly added memory, leave old data in */ 532 (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 533 534 oldkbuf = el->el_chared.c_kill.buf; 535 536 el->el_chared.c_kill.buf = newbuffer; 537 el->el_chared.c_kill.last = newbuffer + 538 (el->el_chared.c_kill.last - oldkbuf); 539 el->el_chared.c_kill.mark = el->el_line.buffer + 540 (el->el_chared.c_kill.mark - oldbuf); 541 542 /* 543 * Reallocate undo buffer. 544 */ 545 newbuffer = el_realloc(el->el_chared.c_undo.buf, 546 newsz * sizeof(*newbuffer)); 547 if (!newbuffer) 548 return 0; 549 550 /* zero the newly added memory, leave old data in */ 551 (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 552 el->el_chared.c_undo.buf = newbuffer; 553 554 newbuffer = el_realloc(el->el_chared.c_redo.buf, 555 newsz * sizeof(*newbuffer)); 556 if (!newbuffer) 557 return 0; 558 el->el_chared.c_redo.pos = newbuffer + 559 (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf); 560 el->el_chared.c_redo.lim = newbuffer + 561 (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf); 562 el->el_chared.c_redo.buf = newbuffer; 563 564 if (!hist_enlargebuf(el, sz, newsz)) 565 return 0; 566 567 /* Safe to set enlarged buffer size */ 568 el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE]; 569 if (el->el_chared.c_resizefun) 570 (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg); 571 return 1; 572 } 573 574 /* ch_end(): 575 * Free the data structures used by the editor 576 */ 577 libedit_private void 578 ch_end(EditLine *el) 579 { 580 el_free(el->el_line.buffer); 581 el->el_line.buffer = NULL; 582 el->el_line.limit = NULL; 583 el_free(el->el_chared.c_undo.buf); 584 el->el_chared.c_undo.buf = NULL; 585 el_free(el->el_chared.c_redo.buf); 586 el->el_chared.c_redo.buf = NULL; 587 el->el_chared.c_redo.pos = NULL; 588 el->el_chared.c_redo.lim = NULL; 589 el->el_chared.c_redo.cmd = ED_UNASSIGNED; 590 el_free(el->el_chared.c_kill.buf); 591 el->el_chared.c_kill.buf = NULL; 592 ch_reset(el); 593 } 594 595 596 /* el_insertstr(): 597 * Insert string at cursor 598 */ 599 int 600 el_winsertstr(EditLine *el, const wchar_t *s) 601 { 602 size_t len; 603 604 if (s == NULL || (len = wcslen(s)) == 0) 605 return -1; 606 if (el->el_line.lastchar + len >= el->el_line.limit) { 607 if (!ch_enlargebufs(el, len)) 608 return -1; 609 } 610 611 c_insert(el, (int)len); 612 while (*s) 613 *el->el_line.cursor++ = *s++; 614 return 0; 615 } 616 617 618 /* el_deletestr(): 619 * Delete num characters before the cursor 620 */ 621 void 622 el_deletestr(EditLine *el, int n) 623 { 624 if (n <= 0) 625 return; 626 627 if (el->el_line.cursor < &el->el_line.buffer[n]) 628 return; 629 630 c_delbefore(el, n); /* delete before dot */ 631 el->el_line.cursor -= n; 632 if (el->el_line.cursor < el->el_line.buffer) 633 el->el_line.cursor = el->el_line.buffer; 634 } 635 636 /* el_deletestr1(): 637 * Delete characters between start and end 638 */ 639 int 640 el_deletestr1(EditLine *el, int start, int end) 641 { 642 size_t line_length, len; 643 wchar_t *p1, *p2; 644 645 if (end <= start) 646 return 0; 647 648 line_length = (size_t)(el->el_line.lastchar - el->el_line.buffer); 649 650 if (start >= (int)line_length || end >= (int)line_length) 651 return 0; 652 653 len = (size_t)(end - start); 654 if (len > line_length - (size_t)end) 655 len = line_length - (size_t)end; 656 657 p1 = el->el_line.buffer + start; 658 p2 = el->el_line.buffer + end; 659 for (size_t i = 0; i < len; i++) { 660 *p1++ = *p2++; 661 el->el_line.lastchar--; 662 } 663 664 if (el->el_line.cursor < el->el_line.buffer) 665 el->el_line.cursor = el->el_line.buffer; 666 667 return end - start; 668 } 669 670 /* el_wreplacestr(): 671 * Replace the contents of the line with the provided string 672 */ 673 int 674 el_wreplacestr(EditLine *el, const wchar_t *s) 675 { 676 size_t len; 677 wchar_t * p; 678 679 if (s == NULL || (len = wcslen(s)) == 0) 680 return -1; 681 682 if (el->el_line.buffer + len >= el->el_line.limit) { 683 if (!ch_enlargebufs(el, len)) 684 return -1; 685 } 686 687 p = el->el_line.buffer; 688 for (size_t i = 0; i < len; i++) 689 *p++ = *s++; 690 691 el->el_line.buffer[len] = '\0'; 692 el->el_line.lastchar = el->el_line.buffer + len; 693 if (el->el_line.cursor > el->el_line.lastchar) 694 el->el_line.cursor = el->el_line.lastchar; 695 696 return 0; 697 } 698 699 /* el_cursor(): 700 * Move the cursor to the left or the right of the current position 701 */ 702 int 703 el_cursor(EditLine *el, int n) 704 { 705 if (n == 0) 706 goto out; 707 708 el->el_line.cursor += n; 709 710 if (el->el_line.cursor < el->el_line.buffer) 711 el->el_line.cursor = el->el_line.buffer; 712 if (el->el_line.cursor > el->el_line.lastchar) 713 el->el_line.cursor = el->el_line.lastchar; 714 out: 715 return (int)(el->el_line.cursor - el->el_line.buffer); 716 } 717 718 /* c_gets(): 719 * Get a string 720 */ 721 libedit_private int 722 c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt) 723 { 724 ssize_t len; 725 wchar_t *cp = el->el_line.buffer, ch; 726 727 if (prompt) { 728 len = (ssize_t)wcslen(prompt); 729 (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp)); 730 cp += len; 731 } 732 len = 0; 733 734 for (;;) { 735 el->el_line.cursor = cp; 736 *cp = ' '; 737 el->el_line.lastchar = cp + 1; 738 re_refresh(el); 739 740 if (el_wgetc(el, &ch) != 1) { 741 ed_end_of_file(el, 0); 742 len = -1; 743 break; 744 } 745 746 switch (ch) { 747 748 case L'\b': /* Delete and backspace */ 749 case 0177: 750 if (len == 0) { 751 len = -1; 752 break; 753 } 754 len--; 755 cp--; 756 continue; 757 758 case 0033: /* ESC */ 759 case L'\r': /* Newline */ 760 case L'\n': 761 buf[len] = ch; 762 break; 763 764 default: 765 if (len >= (ssize_t)(EL_BUFSIZ - 16)) 766 terminal_beep(el); 767 else { 768 buf[len++] = ch; 769 *cp++ = ch; 770 } 771 continue; 772 } 773 break; 774 } 775 776 el->el_line.buffer[0] = '\0'; 777 el->el_line.lastchar = el->el_line.buffer; 778 el->el_line.cursor = el->el_line.buffer; 779 return (int)len; 780 } 781 782 783 /* c_hpos(): 784 * Return the current horizontal position of the cursor 785 */ 786 libedit_private int 787 c_hpos(EditLine *el) 788 { 789 wchar_t *ptr; 790 791 /* 792 * Find how many characters till the beginning of this line. 793 */ 794 if (el->el_line.cursor == el->el_line.buffer) 795 return 0; 796 else { 797 for (ptr = el->el_line.cursor - 1; 798 ptr >= el->el_line.buffer && *ptr != '\n'; 799 ptr--) 800 continue; 801 return (int)(el->el_line.cursor - ptr - 1); 802 } 803 } 804 805 libedit_private int 806 ch_resizefun(EditLine *el, el_zfunc_t f, void *a) 807 { 808 el->el_chared.c_resizefun = f; 809 el->el_chared.c_resizearg = a; 810 return 0; 811 } 812 813 libedit_private int 814 ch_aliasfun(EditLine *el, el_afunc_t f, void *a) 815 { 816 el->el_chared.c_aliasfun = f; 817 el->el_chared.c_aliasarg = a; 818 return 0; 819 } 820