1/* text.c -- text handling commands for readline. */ 2 3/* Copyright (C) 1987-2005 Free Software Foundation, Inc. 4 5 This file is part of the GNU Readline Library, a library for 6 reading lines of text with interactive input and history editing. 7 8 The GNU Readline Library is free software; you can redistribute it 9 and/or modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2, or 11 (at your option) any later version. 12 13 The GNU Readline Library is distributed in the hope that it will be 14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 The GNU General Public License is often shipped with GNU software, and 19 is generally kept in a file called COPYING or LICENSE. If you do not 20 have a copy of the license, write to the Free Software Foundation, 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22#define READLINE_LIBRARY 23 24#if defined (HAVE_CONFIG_H) 25# include <config.h> 26#endif 27 28#if defined (HAVE_UNISTD_H) 29# include <unistd.h> 30#endif /* HAVE_UNISTD_H */ 31 32#if defined (HAVE_STDLIB_H) 33# include <stdlib.h> 34#else 35# include "ansi_stdlib.h" 36#endif /* HAVE_STDLIB_H */ 37 38#if defined (HAVE_LOCALE_H) 39# include <locale.h> 40#endif 41 42#include <stdio.h> 43 44/* System-specific feature definitions and include files. */ 45#include "rldefs.h" 46#include "rlmbutil.h" 47 48#if defined (__EMX__) 49# define INCL_DOSPROCESS 50# include <os2.h> 51#endif /* __EMX__ */ 52 53/* Some standard library routines. */ 54#include "readline.h" 55#include "history.h" 56 57#include "rlprivate.h" 58#include "rlshell.h" 59#include "xmalloc.h" 60 61/* Forward declarations. */ 62static int rl_change_case PARAMS((int, int)); 63static int _rl_char_search PARAMS((int, int, int)); 64 65#if defined (READLINE_CALLBACKS) 66static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *)); 67static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *)); 68#endif 69 70/* **************************************************************** */ 71/* */ 72/* Insert and Delete */ 73/* */ 74/* **************************************************************** */ 75 76/* Insert a string of text into the line at point. This is the only 77 way that you should do insertion. _rl_insert_char () calls this 78 function. Returns the number of characters inserted. */ 79int 80rl_insert_text (string) 81 const char *string; 82{ 83 register int i, l; 84 85 l = (string && *string) ? strlen (string) : 0; 86 if (l == 0) 87 return 0; 88 89 if (rl_end + l >= rl_line_buffer_len) 90 rl_extend_line_buffer (rl_end + l); 91 92 for (i = rl_end; i >= rl_point; i--) 93 rl_line_buffer[i + l] = rl_line_buffer[i]; 94 strncpy (rl_line_buffer + rl_point, string, l); 95 96 /* Remember how to undo this if we aren't undoing something. */ 97 if (_rl_doing_an_undo == 0) 98 { 99 /* If possible and desirable, concatenate the undos. */ 100 if ((l == 1) && 101 rl_undo_list && 102 (rl_undo_list->what == UNDO_INSERT) && 103 (rl_undo_list->end == rl_point) && 104 (rl_undo_list->end - rl_undo_list->start < 20)) 105 rl_undo_list->end++; 106 else 107 rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL); 108 } 109 rl_point += l; 110 rl_end += l; 111 rl_line_buffer[rl_end] = '\0'; 112 return l; 113} 114 115/* Delete the string between FROM and TO. FROM is inclusive, TO is not. 116 Returns the number of characters deleted. */ 117int 118rl_delete_text (from, to) 119 int from, to; 120{ 121 register char *text; 122 register int diff, i; 123 124 /* Fix it if the caller is confused. */ 125 if (from > to) 126 SWAP (from, to); 127 128 /* fix boundaries */ 129 if (to > rl_end) 130 { 131 to = rl_end; 132 if (from > to) 133 from = to; 134 } 135 if (from < 0) 136 from = 0; 137 138 text = rl_copy_text (from, to); 139 140 /* Some versions of strncpy() can't handle overlapping arguments. */ 141 diff = to - from; 142 for (i = from; i < rl_end - diff; i++) 143 rl_line_buffer[i] = rl_line_buffer[i + diff]; 144 145 /* Remember how to undo this delete. */ 146 if (_rl_doing_an_undo == 0) 147 rl_add_undo (UNDO_DELETE, from, to, text); 148 else 149 free (text); 150 151 rl_end -= diff; 152 rl_line_buffer[rl_end] = '\0'; 153 return (diff); 154} 155 156/* Fix up point so that it is within the line boundaries after killing 157 text. If FIX_MARK_TOO is non-zero, the mark is forced within line 158 boundaries also. */ 159 160#define _RL_FIX_POINT(x) \ 161 do { \ 162 if (x > rl_end) \ 163 x = rl_end; \ 164 else if (x < 0) \ 165 x = 0; \ 166 } while (0) 167 168void 169_rl_fix_point (fix_mark_too) 170 int fix_mark_too; 171{ 172 _RL_FIX_POINT (rl_point); 173 if (fix_mark_too) 174 _RL_FIX_POINT (rl_mark); 175} 176#undef _RL_FIX_POINT 177 178/* Replace the contents of the line buffer between START and END with 179 TEXT. The operation is undoable. To replace the entire line in an 180 undoable mode, use _rl_replace_text(text, 0, rl_end); */ 181int 182_rl_replace_text (text, start, end) 183 const char *text; 184 int start, end; 185{ 186 int n; 187 188 rl_begin_undo_group (); 189 rl_delete_text (start, end + 1); 190 rl_point = start; 191 n = rl_insert_text (text); 192 rl_end_undo_group (); 193 194 return n; 195} 196 197/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is 198 non-zero, we free the current undo list. */ 199void 200rl_replace_line (text, clear_undo) 201 const char *text; 202 int clear_undo; 203{ 204 int len; 205 206 len = strlen (text); 207 if (len >= rl_line_buffer_len) 208 rl_extend_line_buffer (len); 209 strcpy (rl_line_buffer, text); 210 rl_end = len; 211 212 if (clear_undo) 213 rl_free_undo_list (); 214 215 _rl_fix_point (1); 216} 217 218/* **************************************************************** */ 219/* */ 220/* Readline character functions */ 221/* */ 222/* **************************************************************** */ 223 224/* This is not a gap editor, just a stupid line input routine. No hair 225 is involved in writing any of the functions, and none should be. */ 226 227/* Note that: 228 229 rl_end is the place in the string that we would place '\0'; 230 i.e., it is always safe to place '\0' there. 231 232 rl_point is the place in the string where the cursor is. Sometimes 233 this is the same as rl_end. 234 235 Any command that is called interactively receives two arguments. 236 The first is a count: the numeric arg pased to this command. 237 The second is the key which invoked this command. 238*/ 239 240/* **************************************************************** */ 241/* */ 242/* Movement Commands */ 243/* */ 244/* **************************************************************** */ 245 246/* Note that if you `optimize' the display for these functions, you cannot 247 use said functions in other functions which do not do optimizing display. 248 I.e., you will have to update the data base for rl_redisplay, and you 249 might as well let rl_redisplay do that job. */ 250 251/* Move forward COUNT bytes. */ 252int 253rl_forward_byte (count, key) 254 int count, key; 255{ 256 if (count < 0) 257 return (rl_backward_byte (-count, key)); 258 259 if (count > 0) 260 { 261 int end = rl_point + count; 262#if defined (VI_MODE) 263 int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end; 264#else 265 int lend = rl_end; 266#endif 267 268 if (end > lend) 269 { 270 rl_point = lend; 271 rl_ding (); 272 } 273 else 274 rl_point = end; 275 } 276 277 if (rl_end < 0) 278 rl_end = 0; 279 280 return 0; 281} 282 283#if defined (HANDLE_MULTIBYTE) 284/* Move forward COUNT characters. */ 285int 286rl_forward_char (count, key) 287 int count, key; 288{ 289 int point; 290 291 if (MB_CUR_MAX == 1 || rl_byte_oriented) 292 return (rl_forward_byte (count, key)); 293 294 if (count < 0) 295 return (rl_backward_char (-count, key)); 296 297 if (count > 0) 298 { 299 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 300 301#if defined (VI_MODE) 302 if (rl_end <= point && rl_editing_mode == vi_mode) 303 point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO); 304#endif 305 306 if (rl_point == point) 307 rl_ding (); 308 309 rl_point = point; 310 311 if (rl_end < 0) 312 rl_end = 0; 313 } 314 315 return 0; 316} 317#else /* !HANDLE_MULTIBYTE */ 318int 319rl_forward_char (count, key) 320 int count, key; 321{ 322 return (rl_forward_byte (count, key)); 323} 324#endif /* !HANDLE_MULTIBYTE */ 325 326/* Backwards compatibility. */ 327int 328rl_forward (count, key) 329 int count, key; 330{ 331 return (rl_forward_char (count, key)); 332} 333 334/* Move backward COUNT bytes. */ 335int 336rl_backward_byte (count, key) 337 int count, key; 338{ 339 if (count < 0) 340 return (rl_forward_byte (-count, key)); 341 342 if (count > 0) 343 { 344 if (rl_point < count) 345 { 346 rl_point = 0; 347 rl_ding (); 348 } 349 else 350 rl_point -= count; 351 } 352 353 if (rl_point < 0) 354 rl_point = 0; 355 356 return 0; 357} 358 359#if defined (HANDLE_MULTIBYTE) 360/* Move backward COUNT characters. */ 361int 362rl_backward_char (count, key) 363 int count, key; 364{ 365 int point; 366 367 if (MB_CUR_MAX == 1 || rl_byte_oriented) 368 return (rl_backward_byte (count, key)); 369 370 if (count < 0) 371 return (rl_forward_char (-count, key)); 372 373 if (count > 0) 374 { 375 point = rl_point; 376 377 while (count > 0 && point > 0) 378 { 379 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); 380 count--; 381 } 382 if (count > 0) 383 { 384 rl_point = 0; 385 rl_ding (); 386 } 387 else 388 rl_point = point; 389 } 390 391 return 0; 392} 393#else 394int 395rl_backward_char (count, key) 396 int count, key; 397{ 398 return (rl_backward_byte (count, key)); 399} 400#endif 401 402/* Backwards compatibility. */ 403int 404rl_backward (count, key) 405 int count, key; 406{ 407 return (rl_backward_char (count, key)); 408} 409 410/* Move to the beginning of the line. */ 411int 412rl_beg_of_line (count, key) 413 int count, key; 414{ 415 rl_point = 0; 416 return 0; 417} 418 419/* Move to the end of the line. */ 420int 421rl_end_of_line (count, key) 422 int count, key; 423{ 424 rl_point = rl_end; 425 return 0; 426} 427 428/* Move forward a word. We do what Emacs does. Handles multibyte chars. */ 429int 430rl_forward_word (count, key) 431 int count, key; 432{ 433 int c; 434 435 if (count < 0) 436 return (rl_backward_word (-count, key)); 437 438 while (count) 439 { 440 if (rl_point == rl_end) 441 return 0; 442 443 /* If we are not in a word, move forward until we are in one. 444 Then, move forward until we hit a non-alphabetic character. */ 445 c = _rl_char_value (rl_line_buffer, rl_point); 446 447 if (_rl_walphabetic (c) == 0) 448 { 449 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 450 while (rl_point < rl_end) 451 { 452 c = _rl_char_value (rl_line_buffer, rl_point); 453 if (_rl_walphabetic (c)) 454 break; 455 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 456 } 457 } 458 459 if (rl_point == rl_end) 460 return 0; 461 462 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 463 while (rl_point < rl_end) 464 { 465 c = _rl_char_value (rl_line_buffer, rl_point); 466 if (_rl_walphabetic (c) == 0) 467 break; 468 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 469 } 470 471 --count; 472 } 473 474 return 0; 475} 476 477/* Move backward a word. We do what Emacs does. Handles multibyte chars. */ 478int 479rl_backward_word (count, key) 480 int count, key; 481{ 482 int c, p; 483 484 if (count < 0) 485 return (rl_forward_word (-count, key)); 486 487 while (count) 488 { 489 if (rl_point == 0) 490 return 0; 491 492 /* Like rl_forward_word (), except that we look at the characters 493 just before point. */ 494 495 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 496 c = _rl_char_value (rl_line_buffer, p); 497 498 if (_rl_walphabetic (c) == 0) 499 { 500 rl_point = p; 501 while (rl_point > 0) 502 { 503 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 504 c = _rl_char_value (rl_line_buffer, p); 505 if (_rl_walphabetic (c)) 506 break; 507 rl_point = p; 508 } 509 } 510 511 while (rl_point) 512 { 513 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 514 c = _rl_char_value (rl_line_buffer, p); 515 if (_rl_walphabetic (c) == 0) 516 break; 517 else 518 rl_point = p; 519 } 520 521 --count; 522 } 523 524 return 0; 525} 526 527/* Clear the current line. Numeric argument to C-l does this. */ 528int 529rl_refresh_line (ignore1, ignore2) 530 int ignore1, ignore2; 531{ 532 int curr_line; 533 534 curr_line = _rl_current_display_line (); 535 536 _rl_move_vert (curr_line); 537 _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */ 538 539 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */ 540 541 rl_forced_update_display (); 542 rl_display_fixed = 1; 543 544 return 0; 545} 546 547/* C-l typed to a line without quoting clears the screen, and then reprints 548 the prompt and the current input line. Given a numeric arg, redraw only 549 the current line. */ 550int 551rl_clear_screen (count, key) 552 int count, key; 553{ 554 if (rl_explicit_arg) 555 { 556 rl_refresh_line (count, key); 557 return 0; 558 } 559 560 _rl_clear_screen (); /* calls termcap function to clear screen */ 561 rl_forced_update_display (); 562 rl_display_fixed = 1; 563 564 return 0; 565} 566 567int 568rl_arrow_keys (count, c) 569 int count, c; 570{ 571 int ch; 572 573 RL_SETSTATE(RL_STATE_MOREINPUT); 574 ch = rl_read_key (); 575 RL_UNSETSTATE(RL_STATE_MOREINPUT); 576 577 switch (_rl_to_upper (ch)) 578 { 579 case 'A': 580 rl_get_previous_history (count, ch); 581 break; 582 583 case 'B': 584 rl_get_next_history (count, ch); 585 break; 586 587 case 'C': 588 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 589 rl_forward_char (count, ch); 590 else 591 rl_forward_byte (count, ch); 592 break; 593 594 case 'D': 595 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 596 rl_backward_char (count, ch); 597 else 598 rl_backward_byte (count, ch); 599 break; 600 601 default: 602 rl_ding (); 603 } 604 605 return 0; 606} 607 608/* **************************************************************** */ 609/* */ 610/* Text commands */ 611/* */ 612/* **************************************************************** */ 613 614#ifdef HANDLE_MULTIBYTE 615static char pending_bytes[MB_LEN_MAX]; 616static int pending_bytes_length = 0; 617static mbstate_t ps = {0}; 618#endif 619 620/* Insert the character C at the current location, moving point forward. 621 If C introduces a multibyte sequence, we read the whole sequence and 622 then insert the multibyte char into the line buffer. */ 623int 624_rl_insert_char (count, c) 625 int count, c; 626{ 627 register int i; 628 char *string; 629#ifdef HANDLE_MULTIBYTE 630 int string_size; 631 char incoming[MB_LEN_MAX + 1]; 632 int incoming_length = 0; 633 mbstate_t ps_back; 634 static int stored_count = 0; 635#endif 636 637 if (count <= 0) 638 return 0; 639 640#if defined (HANDLE_MULTIBYTE) 641 if (MB_CUR_MAX == 1 || rl_byte_oriented) 642 { 643 incoming[0] = c; 644 incoming[1] = '\0'; 645 incoming_length = 1; 646 } 647 else 648 { 649 wchar_t wc; 650 size_t ret; 651 652 if (stored_count <= 0) 653 stored_count = count; 654 else 655 count = stored_count; 656 657 ps_back = ps; 658 pending_bytes[pending_bytes_length++] = c; 659 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps); 660 661 if (ret == (size_t)-2) 662 { 663 /* Bytes too short to compose character, try to wait for next byte. 664 Restore the state of the byte sequence, because in this case the 665 effect of mbstate is undefined. */ 666 ps = ps_back; 667 return 1; 668 } 669 else if (ret == (size_t)-1) 670 { 671 /* Invalid byte sequence for the current locale. Treat first byte 672 as a single character. */ 673 incoming[0] = pending_bytes[0]; 674 incoming[1] = '\0'; 675 incoming_length = 1; 676 pending_bytes_length--; 677 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length); 678 /* Clear the state of the byte sequence, because in this case the 679 effect of mbstate is undefined. */ 680 memset (&ps, 0, sizeof (mbstate_t)); 681 } 682 else if (ret == (size_t)0) 683 { 684 incoming[0] = '\0'; 685 incoming_length = 0; 686 pending_bytes_length--; 687 /* Clear the state of the byte sequence, because in this case the 688 effect of mbstate is undefined. */ 689 memset (&ps, 0, sizeof (mbstate_t)); 690 } 691 else 692 { 693 /* We successfully read a single multibyte character. */ 694 memcpy (incoming, pending_bytes, pending_bytes_length); 695 incoming[pending_bytes_length] = '\0'; 696 incoming_length = pending_bytes_length; 697 pending_bytes_length = 0; 698 } 699 } 700#endif /* HANDLE_MULTIBYTE */ 701 702 /* If we can optimize, then do it. But don't let people crash 703 readline because of extra large arguments. */ 704 if (count > 1 && count <= 1024) 705 { 706#if defined (HANDLE_MULTIBYTE) 707 string_size = count * incoming_length; 708 string = (char *)xmalloc (1 + string_size); 709 710 i = 0; 711 while (i < string_size) 712 { 713 strncpy (string + i, incoming, incoming_length); 714 i += incoming_length; 715 } 716 incoming_length = 0; 717 stored_count = 0; 718#else /* !HANDLE_MULTIBYTE */ 719 string = (char *)xmalloc (1 + count); 720 721 for (i = 0; i < count; i++) 722 string[i] = c; 723#endif /* !HANDLE_MULTIBYTE */ 724 725 string[i] = '\0'; 726 rl_insert_text (string); 727 free (string); 728 729 return 0; 730 } 731 732 if (count > 1024) 733 { 734 int decreaser; 735#if defined (HANDLE_MULTIBYTE) 736 string_size = incoming_length * 1024; 737 string = (char *)xmalloc (1 + string_size); 738 739 i = 0; 740 while (i < string_size) 741 { 742 strncpy (string + i, incoming, incoming_length); 743 i += incoming_length; 744 } 745 746 while (count) 747 { 748 decreaser = (count > 1024) ? 1024 : count; 749 string[decreaser*incoming_length] = '\0'; 750 rl_insert_text (string); 751 count -= decreaser; 752 } 753 754 free (string); 755 incoming_length = 0; 756 stored_count = 0; 757#else /* !HANDLE_MULTIBYTE */ 758 char str[1024+1]; 759 760 for (i = 0; i < 1024; i++) 761 str[i] = c; 762 763 while (count) 764 { 765 decreaser = (count > 1024 ? 1024 : count); 766 str[decreaser] = '\0'; 767 rl_insert_text (str); 768 count -= decreaser; 769 } 770#endif /* !HANDLE_MULTIBYTE */ 771 772 return 0; 773 } 774 775 if (MB_CUR_MAX == 1 || rl_byte_oriented) 776 { 777 /* We are inserting a single character. 778 If there is pending input, then make a string of all of the 779 pending characters that are bound to rl_insert, and insert 780 them all. */ 781 if (_rl_any_typein ()) 782 _rl_insert_typein (c); 783 else 784 { 785 /* Inserting a single character. */ 786 char str[2]; 787 788 str[1] = '\0'; 789 str[0] = c; 790 rl_insert_text (str); 791 } 792 } 793#if defined (HANDLE_MULTIBYTE) 794 else 795 { 796 rl_insert_text (incoming); 797 stored_count = 0; 798 } 799#endif 800 801 return 0; 802} 803 804/* Overwrite the character at point (or next COUNT characters) with C. 805 If C introduces a multibyte character sequence, read the entire sequence 806 before starting the overwrite loop. */ 807int 808_rl_overwrite_char (count, c) 809 int count, c; 810{ 811 int i; 812#if defined (HANDLE_MULTIBYTE) 813 char mbkey[MB_LEN_MAX]; 814 int k; 815 816 /* Read an entire multibyte character sequence to insert COUNT times. */ 817 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) 818 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); 819#endif 820 821 rl_begin_undo_group (); 822 823 for (i = 0; i < count; i++) 824 { 825#if defined (HANDLE_MULTIBYTE) 826 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 827 rl_insert_text (mbkey); 828 else 829#endif 830 _rl_insert_char (1, c); 831 832 if (rl_point < rl_end) 833 rl_delete (1, c); 834 } 835 836 rl_end_undo_group (); 837 838 return 0; 839} 840 841int 842rl_insert (count, c) 843 int count, c; 844{ 845 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c) 846 : _rl_overwrite_char (count, c)); 847} 848 849/* Insert the next typed character verbatim. */ 850static int 851_rl_insert_next (count) 852 int count; 853{ 854 int c; 855 856 RL_SETSTATE(RL_STATE_MOREINPUT); 857 c = rl_read_key (); 858 RL_UNSETSTATE(RL_STATE_MOREINPUT); 859 860 if (c < 0) 861 return -1; 862 863#if defined (HANDLE_SIGNALS) 864 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 865 _rl_restore_tty_signals (); 866#endif 867 868 return (_rl_insert_char (count, c)); 869} 870 871#if defined (READLINE_CALLBACKS) 872static int 873_rl_insert_next_callback (data) 874 _rl_callback_generic_arg *data; 875{ 876 int count; 877 878 count = data->count; 879 880 /* Deregister function, let rl_callback_read_char deallocate data */ 881 _rl_callback_func = 0; 882 _rl_want_redisplay = 1; 883 884 return _rl_insert_next (count); 885} 886#endif 887 888int 889rl_quoted_insert (count, key) 890 int count, key; 891{ 892 /* Let's see...should the callback interface futz with signal handling? */ 893#if defined (HANDLE_SIGNALS) 894 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 895 _rl_disable_tty_signals (); 896#endif 897 898#if defined (READLINE_CALLBACKS) 899 if (RL_ISSTATE (RL_STATE_CALLBACK)) 900 { 901 _rl_callback_data = _rl_callback_data_alloc (count); 902 _rl_callback_func = _rl_insert_next_callback; 903 return (0); 904 } 905#endif 906 907 return _rl_insert_next (count); 908} 909 910/* Insert a tab character. */ 911int 912rl_tab_insert (count, key) 913 int count, key; 914{ 915 return (_rl_insert_char (count, '\t')); 916} 917 918/* What to do when a NEWLINE is pressed. We accept the whole line. 919 KEY is the key that invoked this command. I guess it could have 920 meaning in the future. */ 921int 922rl_newline (count, key) 923 int count, key; 924{ 925 rl_done = 1; 926 927 if (_rl_history_preserve_point) 928 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; 929 930 RL_SETSTATE(RL_STATE_DONE); 931 932#if defined (VI_MODE) 933 if (rl_editing_mode == vi_mode) 934 { 935 _rl_vi_done_inserting (); 936 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */ 937 _rl_vi_reset_last (); 938 } 939#endif /* VI_MODE */ 940 941 /* If we've been asked to erase empty lines, suppress the final update, 942 since _rl_update_final calls rl_crlf(). */ 943 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) 944 return 0; 945 946 if (readline_echoing_p) 947 _rl_update_final (); 948 return 0; 949} 950 951/* What to do for some uppercase characters, like meta characters, 952 and some characters appearing in emacs_ctlx_keymap. This function 953 is just a stub, you bind keys to it and the code in _rl_dispatch () 954 is special cased. */ 955int 956rl_do_lowercase_version (ignore1, ignore2) 957 int ignore1, ignore2; 958{ 959 return 0; 960} 961 962/* This is different from what vi does, so the code's not shared. Emacs 963 rubout in overwrite mode has one oddity: it replaces a control 964 character that's displayed as two characters (^X) with two spaces. */ 965int 966_rl_overwrite_rubout (count, key) 967 int count, key; 968{ 969 int opoint; 970 int i, l; 971 972 if (rl_point == 0) 973 { 974 rl_ding (); 975 return 1; 976 } 977 978 opoint = rl_point; 979 980 /* L == number of spaces to insert */ 981 for (i = l = 0; i < count; i++) 982 { 983 rl_backward_char (1, key); 984 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ 985 } 986 987 rl_begin_undo_group (); 988 989 if (count > 1 || rl_explicit_arg) 990 rl_kill_text (opoint, rl_point); 991 else 992 rl_delete_text (opoint, rl_point); 993 994 /* Emacs puts point at the beginning of the sequence of spaces. */ 995 if (rl_point < rl_end) 996 { 997 opoint = rl_point; 998 _rl_insert_char (l, ' '); 999 rl_point = opoint; 1000 } 1001 1002 rl_end_undo_group (); 1003 1004 return 0; 1005} 1006 1007/* Rubout the character behind point. */ 1008int 1009rl_rubout (count, key) 1010 int count, key; 1011{ 1012 if (count < 0) 1013 return (rl_delete (-count, key)); 1014 1015 if (!rl_point) 1016 { 1017 rl_ding (); 1018 return -1; 1019 } 1020 1021 if (rl_insert_mode == RL_IM_OVERWRITE) 1022 return (_rl_overwrite_rubout (count, key)); 1023 1024 return (_rl_rubout_char (count, key)); 1025} 1026 1027int 1028_rl_rubout_char (count, key) 1029 int count, key; 1030{ 1031 int orig_point; 1032 unsigned char c; 1033 1034 /* Duplicated code because this is called from other parts of the library. */ 1035 if (count < 0) 1036 return (rl_delete (-count, key)); 1037 1038 if (rl_point == 0) 1039 { 1040 rl_ding (); 1041 return -1; 1042 } 1043 1044 orig_point = rl_point; 1045 if (count > 1 || rl_explicit_arg) 1046 { 1047 rl_backward_char (count, key); 1048 rl_kill_text (orig_point, rl_point); 1049 } 1050 else if (MB_CUR_MAX == 1 || rl_byte_oriented) 1051 { 1052 c = rl_line_buffer[--rl_point]; 1053 rl_delete_text (rl_point, orig_point); 1054 /* The erase-at-end-of-line hack is of questionable merit now. */ 1055 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) 1056 { 1057 int l; 1058 l = rl_character_len (c, rl_point); 1059 _rl_erase_at_end_of_line (l); 1060 } 1061 } 1062 else 1063 { 1064 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1065 rl_delete_text (rl_point, orig_point); 1066 } 1067 1068 return 0; 1069} 1070 1071/* Delete the character under the cursor. Given a numeric argument, 1072 kill that many characters instead. */ 1073int 1074rl_delete (count, key) 1075 int count, key; 1076{ 1077 int xpoint; 1078 1079 if (count < 0) 1080 return (_rl_rubout_char (-count, key)); 1081 1082 if (rl_point == rl_end) 1083 { 1084 rl_ding (); 1085 return -1; 1086 } 1087 1088 if (count > 1 || rl_explicit_arg) 1089 { 1090 xpoint = rl_point; 1091 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1092 rl_forward_char (count, key); 1093 else 1094 rl_forward_byte (count, key); 1095 1096 rl_kill_text (xpoint, rl_point); 1097 rl_point = xpoint; 1098 } 1099 else 1100 { 1101 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 1102 rl_delete_text (rl_point, xpoint); 1103 } 1104 return 0; 1105} 1106 1107/* Delete the character under the cursor, unless the insertion 1108 point is at the end of the line, in which case the character 1109 behind the cursor is deleted. COUNT is obeyed and may be used 1110 to delete forward or backward that many characters. */ 1111int 1112rl_rubout_or_delete (count, key) 1113 int count, key; 1114{ 1115 if (rl_end != 0 && rl_point == rl_end) 1116 return (_rl_rubout_char (count, key)); 1117 else 1118 return (rl_delete (count, key)); 1119} 1120 1121/* Delete all spaces and tabs around point. */ 1122int 1123rl_delete_horizontal_space (count, ignore) 1124 int count, ignore; 1125{ 1126 int start = rl_point; 1127 1128 while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) 1129 rl_point--; 1130 1131 start = rl_point; 1132 1133 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) 1134 rl_point++; 1135 1136 if (start != rl_point) 1137 { 1138 rl_delete_text (start, rl_point); 1139 rl_point = start; 1140 } 1141 1142 if (rl_point < 0) 1143 rl_point = 0; 1144 1145 return 0; 1146} 1147 1148/* Like the tcsh editing function delete-char-or-list. The eof character 1149 is caught before this is invoked, so this really does the same thing as 1150 delete-char-or-list-or-eof, as long as it's bound to the eof character. */ 1151int 1152rl_delete_or_show_completions (count, key) 1153 int count, key; 1154{ 1155 if (rl_end != 0 && rl_point == rl_end) 1156 return (rl_possible_completions (count, key)); 1157 else 1158 return (rl_delete (count, key)); 1159} 1160 1161#ifndef RL_COMMENT_BEGIN_DEFAULT 1162#define RL_COMMENT_BEGIN_DEFAULT "#" 1163#endif 1164 1165/* Turn the current line into a comment in shell history. 1166 A K*rn shell style function. */ 1167int 1168rl_insert_comment (count, key) 1169 int count, key; 1170{ 1171 char *rl_comment_text; 1172 int rl_comment_len; 1173 1174 rl_beg_of_line (1, key); 1175 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT; 1176 1177 if (rl_explicit_arg == 0) 1178 rl_insert_text (rl_comment_text); 1179 else 1180 { 1181 rl_comment_len = strlen (rl_comment_text); 1182 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) 1183 rl_delete_text (rl_point, rl_point + rl_comment_len); 1184 else 1185 rl_insert_text (rl_comment_text); 1186 } 1187 1188 (*rl_redisplay_function) (); 1189 rl_newline (1, '\n'); 1190 1191 return (0); 1192} 1193 1194/* **************************************************************** */ 1195/* */ 1196/* Changing Case */ 1197/* */ 1198/* **************************************************************** */ 1199 1200/* The three kinds of things that we know how to do. */ 1201#define UpCase 1 1202#define DownCase 2 1203#define CapCase 3 1204 1205/* Uppercase the word at point. */ 1206int 1207rl_upcase_word (count, key) 1208 int count, key; 1209{ 1210 return (rl_change_case (count, UpCase)); 1211} 1212 1213/* Lowercase the word at point. */ 1214int 1215rl_downcase_word (count, key) 1216 int count, key; 1217{ 1218 return (rl_change_case (count, DownCase)); 1219} 1220 1221/* Upcase the first letter, downcase the rest. */ 1222int 1223rl_capitalize_word (count, key) 1224 int count, key; 1225{ 1226 return (rl_change_case (count, CapCase)); 1227} 1228 1229/* The meaty function. 1230 Change the case of COUNT words, performing OP on them. 1231 OP is one of UpCase, DownCase, or CapCase. 1232 If a negative argument is given, leave point where it started, 1233 otherwise, leave it where it moves to. */ 1234static int 1235rl_change_case (count, op) 1236 int count, op; 1237{ 1238 int start, next, end; 1239 int inword, c, nc, nop; 1240#if defined (HANDLE_MULTIBYTE) 1241 wchar_t wc, nwc; 1242 char mb[MB_LEN_MAX+1]; 1243 int mlen; 1244 mbstate_t mps; 1245#endif 1246 1247 start = rl_point; 1248 rl_forward_word (count, 0); 1249 end = rl_point; 1250 1251 if (op != UpCase && op != DownCase && op != CapCase) 1252 { 1253 rl_ding (); 1254 return -1; 1255 } 1256 1257 if (count < 0) 1258 SWAP (start, end); 1259 1260#if defined (HANDLE_MULTIBYTE) 1261 memset (&mps, 0, sizeof (mbstate_t)); 1262#endif 1263 1264 /* We are going to modify some text, so let's prepare to undo it. */ 1265 rl_modifying (start, end); 1266 1267 inword = 0; 1268 while (start < end) 1269 { 1270 c = _rl_char_value (rl_line_buffer, start); 1271 /* This assumes that the upper and lower case versions are the same width. */ 1272 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO); 1273 1274 if (_rl_walphabetic (c) == 0) 1275 { 1276 inword = 0; 1277 start = next; 1278 continue; 1279 } 1280 1281 if (op == CapCase) 1282 { 1283 nop = inword ? DownCase : UpCase; 1284 inword = 1; 1285 } 1286 else 1287 nop = op; 1288 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c)) 1289 { 1290 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); 1291 rl_line_buffer[start] = nc; 1292 } 1293#if defined (HANDLE_MULTIBYTE) 1294 else 1295 { 1296 mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); 1297 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); 1298 if (nwc != wc) /* just skip unchanged characters */ 1299 { 1300 mlen = wcrtomb (mb, nwc, &mps); 1301 if (mlen > 0) 1302 mb[mlen] = '\0'; 1303 /* Assume the same width */ 1304 strncpy (rl_line_buffer + start, mb, mlen); 1305 } 1306 } 1307#endif 1308 1309 start = next; 1310 } 1311 1312 rl_point = end; 1313 return 0; 1314} 1315 1316/* **************************************************************** */ 1317/* */ 1318/* Transposition */ 1319/* */ 1320/* **************************************************************** */ 1321 1322/* Transpose the words at point. If point is at the end of the line, 1323 transpose the two words before point. */ 1324int 1325rl_transpose_words (count, key) 1326 int count, key; 1327{ 1328 char *word1, *word2; 1329 int w1_beg, w1_end, w2_beg, w2_end; 1330 int orig_point = rl_point; 1331 1332 if (!count) 1333 return 0; 1334 1335 /* Find the two words. */ 1336 rl_forward_word (count, key); 1337 w2_end = rl_point; 1338 rl_backward_word (1, key); 1339 w2_beg = rl_point; 1340 rl_backward_word (count, key); 1341 w1_beg = rl_point; 1342 rl_forward_word (1, key); 1343 w1_end = rl_point; 1344 1345 /* Do some check to make sure that there really are two words. */ 1346 if ((w1_beg == w2_beg) || (w2_beg < w1_end)) 1347 { 1348 rl_ding (); 1349 rl_point = orig_point; 1350 return -1; 1351 } 1352 1353 /* Get the text of the words. */ 1354 word1 = rl_copy_text (w1_beg, w1_end); 1355 word2 = rl_copy_text (w2_beg, w2_end); 1356 1357 /* We are about to do many insertions and deletions. Remember them 1358 as one operation. */ 1359 rl_begin_undo_group (); 1360 1361 /* Do the stuff at word2 first, so that we don't have to worry 1362 about word1 moving. */ 1363 rl_point = w2_beg; 1364 rl_delete_text (w2_beg, w2_end); 1365 rl_insert_text (word1); 1366 1367 rl_point = w1_beg; 1368 rl_delete_text (w1_beg, w1_end); 1369 rl_insert_text (word2); 1370 1371 /* This is exactly correct since the text before this point has not 1372 changed in length. */ 1373 rl_point = w2_end; 1374 1375 /* I think that does it. */ 1376 rl_end_undo_group (); 1377 free (word1); 1378 free (word2); 1379 1380 return 0; 1381} 1382 1383/* Transpose the characters at point. If point is at the end of the line, 1384 then transpose the characters before point. */ 1385int 1386rl_transpose_chars (count, key) 1387 int count, key; 1388{ 1389#if defined (HANDLE_MULTIBYTE) 1390 char *dummy; 1391 int i; 1392#else 1393 char dummy[2]; 1394#endif 1395 int char_length, prev_point; 1396 1397 if (count == 0) 1398 return 0; 1399 1400 if (!rl_point || rl_end < 2) 1401 { 1402 rl_ding (); 1403 return -1; 1404 } 1405 1406 rl_begin_undo_group (); 1407 1408 if (rl_point == rl_end) 1409 { 1410 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1411 count = 1; 1412 } 1413 1414 prev_point = rl_point; 1415 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1416 1417#if defined (HANDLE_MULTIBYTE) 1418 char_length = prev_point - rl_point; 1419 dummy = (char *)xmalloc (char_length + 1); 1420 for (i = 0; i < char_length; i++) 1421 dummy[i] = rl_line_buffer[rl_point + i]; 1422 dummy[i] = '\0'; 1423#else 1424 dummy[0] = rl_line_buffer[rl_point]; 1425 dummy[char_length = 1] = '\0'; 1426#endif 1427 1428 rl_delete_text (rl_point, rl_point + char_length); 1429 1430 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 1431 1432 _rl_fix_point (0); 1433 rl_insert_text (dummy); 1434 rl_end_undo_group (); 1435 1436#if defined (HANDLE_MULTIBYTE) 1437 free (dummy); 1438#endif 1439 1440 return 0; 1441} 1442 1443/* **************************************************************** */ 1444/* */ 1445/* Character Searching */ 1446/* */ 1447/* **************************************************************** */ 1448 1449int 1450#if defined (HANDLE_MULTIBYTE) 1451_rl_char_search_internal (count, dir, smbchar, len) 1452 int count, dir; 1453 char *smbchar; 1454 int len; 1455#else 1456_rl_char_search_internal (count, dir, schar) 1457 int count, dir, schar; 1458#endif 1459{ 1460 int pos, inc; 1461#if defined (HANDLE_MULTIBYTE) 1462 int prepos; 1463#endif 1464 1465 pos = rl_point; 1466 inc = (dir < 0) ? -1 : 1; 1467 while (count) 1468 { 1469 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) 1470 { 1471 rl_ding (); 1472 return -1; 1473 } 1474 1475#if defined (HANDLE_MULTIBYTE) 1476 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1477 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); 1478#else 1479 pos += inc; 1480#endif 1481 do 1482 { 1483#if defined (HANDLE_MULTIBYTE) 1484 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) 1485#else 1486 if (rl_line_buffer[pos] == schar) 1487#endif 1488 { 1489 count--; 1490 if (dir < 0) 1491 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1492 : pos; 1493 else 1494 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) 1495 : pos; 1496 break; 1497 } 1498#if defined (HANDLE_MULTIBYTE) 1499 prepos = pos; 1500#endif 1501 } 1502#if defined (HANDLE_MULTIBYTE) 1503 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos 1504 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); 1505#else 1506 while ((dir < 0) ? pos-- : ++pos < rl_end); 1507#endif 1508 } 1509 return (0); 1510} 1511 1512/* Search COUNT times for a character read from the current input stream. 1513 FDIR is the direction to search if COUNT is non-negative; otherwise 1514 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE 1515 that there are two separate versions of this function. */ 1516#if defined (HANDLE_MULTIBYTE) 1517static int 1518_rl_char_search (count, fdir, bdir) 1519 int count, fdir, bdir; 1520{ 1521 char mbchar[MB_LEN_MAX]; 1522 int mb_len; 1523 1524 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); 1525 1526 if (mb_len <= 0) 1527 return -1; 1528 1529 if (count < 0) 1530 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); 1531 else 1532 return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); 1533} 1534#else /* !HANDLE_MULTIBYTE */ 1535static int 1536_rl_char_search (count, fdir, bdir) 1537 int count, fdir, bdir; 1538{ 1539 int c; 1540 1541 RL_SETSTATE(RL_STATE_MOREINPUT); 1542 c = rl_read_key (); 1543 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1544 1545 if (c < 0) 1546 return -1; 1547 1548 if (count < 0) 1549 return (_rl_char_search_internal (-count, bdir, c)); 1550 else 1551 return (_rl_char_search_internal (count, fdir, c)); 1552} 1553#endif /* !HANDLE_MULTIBYTE */ 1554 1555#if defined (READLINE_CALLBACKS) 1556static int 1557_rl_char_search_callback (data) 1558 _rl_callback_generic_arg *data; 1559{ 1560 _rl_callback_func = 0; 1561 _rl_want_redisplay = 1; 1562 1563 return (_rl_char_search (data->count, data->i1, data->i2)); 1564} 1565#endif 1566 1567int 1568rl_char_search (count, key) 1569 int count, key; 1570{ 1571#if defined (READLINE_CALLBACKS) 1572 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1573 { 1574 _rl_callback_data = _rl_callback_data_alloc (count); 1575 _rl_callback_data->i1 = FFIND; 1576 _rl_callback_data->i2 = BFIND; 1577 _rl_callback_func = _rl_char_search_callback; 1578 return (0); 1579 } 1580#endif 1581 1582 return (_rl_char_search (count, FFIND, BFIND)); 1583} 1584 1585int 1586rl_backward_char_search (count, key) 1587 int count, key; 1588{ 1589#if defined (READLINE_CALLBACKS) 1590 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1591 { 1592 _rl_callback_data = _rl_callback_data_alloc (count); 1593 _rl_callback_data->i1 = BFIND; 1594 _rl_callback_data->i2 = FFIND; 1595 _rl_callback_func = _rl_char_search_callback; 1596 return (0); 1597 } 1598#endif 1599 1600 return (_rl_char_search (count, BFIND, FFIND)); 1601} 1602 1603/* **************************************************************** */ 1604/* */ 1605/* The Mark and the Region. */ 1606/* */ 1607/* **************************************************************** */ 1608 1609/* Set the mark at POSITION. */ 1610int 1611_rl_set_mark_at_pos (position) 1612 int position; 1613{ 1614 if (position > rl_end) 1615 return -1; 1616 1617 rl_mark = position; 1618 return 0; 1619} 1620 1621/* A bindable command to set the mark. */ 1622int 1623rl_set_mark (count, key) 1624 int count, key; 1625{ 1626 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); 1627} 1628 1629/* Exchange the position of mark and point. */ 1630int 1631rl_exchange_point_and_mark (count, key) 1632 int count, key; 1633{ 1634 if (rl_mark > rl_end) 1635 rl_mark = -1; 1636 1637 if (rl_mark == -1) 1638 { 1639 rl_ding (); 1640 return -1; 1641 } 1642 else 1643 SWAP (rl_point, rl_mark); 1644 1645 return 0; 1646} 1647