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 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA. */ 22 #define READLINE_LIBRARY 23 24 #if defined (HAVE_CONFIG_H) 25 # include "config_readline.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. */ 62 static int rl_change_case PARAMS((int, int)); 63 static int _rl_char_search PARAMS((int, int, int)); 64 65 #if defined (READLINE_CALLBACKS) 66 static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *)); 67 static 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. */ 79 int 80 rl_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. */ 117 int 118 rl_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 168 void 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); */ 181 int 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. */ 199 void 200 rl_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. */ 252 int 253 rl_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. */ 285 int 286 rl_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 */ 318 int 319 rl_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. */ 327 int 328 rl_forward (count, key) 329 int count, key; 330 { 331 return (rl_forward_char (count, key)); 332 } 333 334 /* Move backward COUNT bytes. */ 335 int 336 rl_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. */ 361 int 362 rl_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 394 int 395 rl_backward_char (count, key) 396 int count, key; 397 { 398 return (rl_backward_byte (count, key)); 399 } 400 #endif 401 402 /* Backwards compatibility. */ 403 int 404 rl_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. */ 411 int 412 rl_beg_of_line (count, key) 413 int count __attribute__((unused)), key __attribute__((unused)); 414 { 415 rl_point = 0; 416 return 0; 417 } 418 419 /* Move to the end of the line. */ 420 int 421 rl_end_of_line (count, key) 422 int count __attribute__((unused)), key __attribute__((unused)); 423 { 424 rl_point = rl_end; 425 return 0; 426 } 427 428 /* Move forward a word. We do what Emacs does. Handles multibyte chars. */ 429 int 430 rl_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. */ 478 int 479 rl_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. */ 528 int 529 rl_refresh_line (ignore1, ignore2) 530 int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); 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. */ 550 int 551 rl_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 567 int 568 rl_arrow_keys (count, c) 569 int count, c __attribute__((unused)); 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 615 static char pending_bytes[MB_LEN_MAX]; 616 static int pending_bytes_length = 0; 617 static mbstate_t ps; 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. */ 623 int 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. */ 807 int 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 815 /* Read an entire multibyte character sequence to insert COUNT times. */ 816 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) 817 _rl_read_mbstring (c, mbkey, MB_LEN_MAX); 818 #endif 819 820 rl_begin_undo_group (); 821 822 for (i = 0; i < count; i++) 823 { 824 #if defined (HANDLE_MULTIBYTE) 825 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 826 rl_insert_text (mbkey); 827 else 828 #endif 829 _rl_insert_char (1, c); 830 831 if (rl_point < rl_end) 832 rl_delete (1, c); 833 } 834 835 rl_end_undo_group (); 836 837 return 0; 838 } 839 840 int 841 rl_insert (count, c) 842 int count, c; 843 { 844 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c) 845 : _rl_overwrite_char (count, c)); 846 } 847 848 /* Insert the next typed character verbatim. */ 849 static int 850 _rl_insert_next (count) 851 int count; 852 { 853 int c; 854 855 RL_SETSTATE(RL_STATE_MOREINPUT); 856 c = rl_read_key (); 857 RL_UNSETSTATE(RL_STATE_MOREINPUT); 858 859 #if defined (HANDLE_SIGNALS) 860 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 861 _rl_restore_tty_signals (); 862 #endif 863 864 return (_rl_insert_char (count, c)); 865 } 866 867 #if defined (READLINE_CALLBACKS) 868 static int 869 _rl_insert_next_callback (data) 870 _rl_callback_generic_arg *data; 871 { 872 int count; 873 874 count = data->count; 875 876 /* Deregister function, let rl_callback_read_char deallocate data */ 877 _rl_callback_func = 0; 878 _rl_want_redisplay = 1; 879 880 return _rl_insert_next (count); 881 } 882 #endif 883 884 int 885 rl_quoted_insert (count, key) 886 int count, key __attribute__((unused)); 887 { 888 /* Let's see...should the callback interface futz with signal handling? */ 889 #if defined (HANDLE_SIGNALS) 890 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 891 _rl_disable_tty_signals (); 892 #endif 893 894 #if defined (READLINE_CALLBACKS) 895 if (RL_ISSTATE (RL_STATE_CALLBACK)) 896 { 897 _rl_callback_data = _rl_callback_data_alloc (count); 898 _rl_callback_func = _rl_insert_next_callback; 899 return (0); 900 } 901 #endif 902 903 return _rl_insert_next (count); 904 } 905 906 /* Insert a tab character. */ 907 int 908 rl_tab_insert (count, key) 909 int count, key __attribute__((unused)); 910 { 911 return (_rl_insert_char (count, '\t')); 912 } 913 914 /* What to do when a NEWLINE is pressed. We accept the whole line. 915 KEY is the key that invoked this command. I guess it could have 916 meaning in the future. */ 917 int 918 rl_newline (count, key) 919 int count __attribute__((unused)), key __attribute__((unused)); 920 { 921 rl_done = 1; 922 923 if (_rl_history_preserve_point) 924 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; 925 926 RL_SETSTATE(RL_STATE_DONE); 927 928 #if defined (VI_MODE) 929 if (rl_editing_mode == vi_mode) 930 { 931 _rl_vi_done_inserting (); 932 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */ 933 _rl_vi_reset_last (); 934 } 935 #endif /* VI_MODE */ 936 937 /* If we've been asked to erase empty lines, suppress the final update, 938 since _rl_update_final calls rl_crlf(). */ 939 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) 940 return 0; 941 942 if (readline_echoing_p) 943 _rl_update_final (); 944 return 0; 945 } 946 947 /* What to do for some uppercase characters, like meta characters, 948 and some characters appearing in emacs_ctlx_keymap. This function 949 is just a stub, you bind keys to it and the code in _rl_dispatch () 950 is special cased. */ 951 int 952 rl_do_lowercase_version (ignore1, ignore2) 953 int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); 954 { 955 return 0; 956 } 957 958 /* This is different from what vi does, so the code's not shared. Emacs 959 rubout in overwrite mode has one oddity: it replaces a control 960 character that's displayed as two characters (^X) with two spaces. */ 961 int 962 _rl_overwrite_rubout (count, key) 963 int count, key; 964 { 965 int opoint; 966 int i, l; 967 968 if (rl_point == 0) 969 { 970 rl_ding (); 971 return 1; 972 } 973 974 opoint = rl_point; 975 976 /* L == number of spaces to insert */ 977 for (i = l = 0; i < count; i++) 978 { 979 rl_backward_char (1, key); 980 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ 981 } 982 983 rl_begin_undo_group (); 984 985 if (count > 1 || rl_explicit_arg) 986 rl_kill_text (opoint, rl_point); 987 else 988 rl_delete_text (opoint, rl_point); 989 990 /* Emacs puts point at the beginning of the sequence of spaces. */ 991 if (rl_point < rl_end) 992 { 993 opoint = rl_point; 994 _rl_insert_char (l, ' '); 995 rl_point = opoint; 996 } 997 998 rl_end_undo_group (); 999 1000 return 0; 1001 } 1002 1003 /* Rubout the character behind point. */ 1004 int 1005 rl_rubout (count, key) 1006 int count, key; 1007 { 1008 if (count < 0) 1009 return (rl_delete (-count, key)); 1010 1011 if (!rl_point) 1012 { 1013 rl_ding (); 1014 return -1; 1015 } 1016 1017 if (rl_insert_mode == RL_IM_OVERWRITE) 1018 return (_rl_overwrite_rubout (count, key)); 1019 1020 return (_rl_rubout_char (count, key)); 1021 } 1022 1023 int 1024 _rl_rubout_char (count, key) 1025 int count, key; 1026 { 1027 int orig_point; 1028 unsigned char c; 1029 1030 /* Duplicated code because this is called from other parts of the library. */ 1031 if (count < 0) 1032 return (rl_delete (-count, key)); 1033 1034 if (rl_point == 0) 1035 { 1036 rl_ding (); 1037 return -1; 1038 } 1039 1040 orig_point = rl_point; 1041 if (count > 1 || rl_explicit_arg) 1042 { 1043 rl_backward_char (count, key); 1044 rl_kill_text (orig_point, rl_point); 1045 } 1046 else if (MB_CUR_MAX == 1 || rl_byte_oriented) 1047 { 1048 c = rl_line_buffer[--rl_point]; 1049 rl_delete_text (rl_point, orig_point); 1050 /* The erase-at-end-of-line hack is of questionable merit now. */ 1051 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) 1052 { 1053 int l; 1054 l = rl_character_len (c, rl_point); 1055 _rl_erase_at_end_of_line (l); 1056 } 1057 } 1058 else 1059 { 1060 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1061 rl_delete_text (rl_point, orig_point); 1062 } 1063 1064 return 0; 1065 } 1066 1067 /* Delete the character under the cursor. Given a numeric argument, 1068 kill that many characters instead. */ 1069 int 1070 rl_delete (count, key) 1071 int count, key; 1072 { 1073 int xpoint; 1074 1075 if (count < 0) 1076 return (_rl_rubout_char (-count, key)); 1077 1078 if (rl_point == rl_end) 1079 { 1080 rl_ding (); 1081 return -1; 1082 } 1083 1084 if (count > 1 || rl_explicit_arg) 1085 { 1086 xpoint = rl_point; 1087 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1088 rl_forward_char (count, key); 1089 else 1090 rl_forward_byte (count, key); 1091 1092 rl_kill_text (xpoint, rl_point); 1093 rl_point = xpoint; 1094 } 1095 else 1096 { 1097 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 1098 rl_delete_text (rl_point, xpoint); 1099 } 1100 return 0; 1101 } 1102 1103 /* Delete the character under the cursor, unless the insertion 1104 point is at the end of the line, in which case the character 1105 behind the cursor is deleted. COUNT is obeyed and may be used 1106 to delete forward or backward that many characters. */ 1107 int 1108 rl_rubout_or_delete (count, key) 1109 int count, key; 1110 { 1111 if (rl_end != 0 && rl_point == rl_end) 1112 return (_rl_rubout_char (count, key)); 1113 else 1114 return (rl_delete (count, key)); 1115 } 1116 1117 /* Delete all spaces and tabs around point. */ 1118 int 1119 rl_delete_horizontal_space (count, ignore) 1120 int count __attribute__((unused)), ignore __attribute__((unused)); 1121 { 1122 int start = rl_point; 1123 1124 while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) 1125 rl_point--; 1126 1127 start = rl_point; 1128 1129 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) 1130 rl_point++; 1131 1132 if (start != rl_point) 1133 { 1134 rl_delete_text (start, rl_point); 1135 rl_point = start; 1136 } 1137 1138 if (rl_point < 0) 1139 rl_point = 0; 1140 1141 return 0; 1142 } 1143 1144 /* Like the tcsh editing function delete-char-or-list. The eof character 1145 is caught before this is invoked, so this really does the same thing as 1146 delete-char-or-list-or-eof, as long as it's bound to the eof character. */ 1147 int 1148 rl_delete_or_show_completions (count, key) 1149 int count, key; 1150 { 1151 if (rl_end != 0 && rl_point == rl_end) 1152 return (rl_possible_completions (count, key)); 1153 else 1154 return (rl_delete (count, key)); 1155 } 1156 1157 #ifndef RL_COMMENT_BEGIN_DEFAULT 1158 #define RL_COMMENT_BEGIN_DEFAULT "#" 1159 #endif 1160 1161 /* Turn the current line into a comment in shell history. 1162 A K*rn shell style function. */ 1163 int 1164 rl_insert_comment (count, key) 1165 int count __attribute__((unused)), key; 1166 { 1167 const char *rl_comment_text; 1168 int rl_comment_len; 1169 1170 rl_beg_of_line (1, key); 1171 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : (char*) RL_COMMENT_BEGIN_DEFAULT; 1172 1173 if (rl_explicit_arg == 0) 1174 rl_insert_text (rl_comment_text); 1175 else 1176 { 1177 rl_comment_len = strlen (rl_comment_text); 1178 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) 1179 rl_delete_text (rl_point, rl_point + rl_comment_len); 1180 else 1181 rl_insert_text (rl_comment_text); 1182 } 1183 1184 (*rl_redisplay_function) (); 1185 rl_newline (1, '\n'); 1186 1187 return (0); 1188 } 1189 1190 /* **************************************************************** */ 1191 /* */ 1192 /* Changing Case */ 1193 /* */ 1194 /* **************************************************************** */ 1195 1196 /* The three kinds of things that we know how to do. */ 1197 #define UpCase 1 1198 #define DownCase 2 1199 #define CapCase 3 1200 1201 /* Uppercase the word at point. */ 1202 int 1203 rl_upcase_word (count, key) 1204 int count, key __attribute__((unused)); 1205 { 1206 return (rl_change_case (count, UpCase)); 1207 } 1208 1209 /* Lowercase the word at point. */ 1210 int 1211 rl_downcase_word (count, key) 1212 int count, key __attribute__((unused)); 1213 { 1214 return (rl_change_case (count, DownCase)); 1215 } 1216 1217 /* Upcase the first letter, downcase the rest. */ 1218 int 1219 rl_capitalize_word (count, key) 1220 int count, key __attribute__((unused)); 1221 { 1222 return (rl_change_case (count, CapCase)); 1223 } 1224 1225 /* The meaty function. 1226 Change the case of COUNT words, performing OP on them. 1227 OP is one of UpCase, DownCase, or CapCase. 1228 If a negative argument is given, leave point where it started, 1229 otherwise, leave it where it moves to. */ 1230 static int 1231 rl_change_case (count, op) 1232 int count, op; 1233 { 1234 int start, next, end; 1235 int inword, c, nc, nop; 1236 #if defined (HANDLE_MULTIBYTE) 1237 wchar_t wc, nwc; 1238 char mb[MB_LEN_MAX+1]; 1239 int mlen; 1240 mbstate_t mps; 1241 #endif 1242 1243 start = rl_point; 1244 rl_forward_word (count, 0); 1245 end = rl_point; 1246 1247 if (op != UpCase && op != DownCase && op != CapCase) 1248 { 1249 rl_ding (); 1250 return -1; 1251 } 1252 1253 if (count < 0) 1254 SWAP (start, end); 1255 1256 #if defined (HANDLE_MULTIBYTE) 1257 memset (&mps, 0, sizeof (mbstate_t)); 1258 #endif 1259 1260 /* We are going to modify some text, so let's prepare to undo it. */ 1261 rl_modifying (start, end); 1262 1263 inword = 0; 1264 while (start < end) 1265 { 1266 c = _rl_char_value (rl_line_buffer, start); 1267 /* This assumes that the upper and lower case versions are the same width. */ 1268 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO); 1269 1270 if (_rl_walphabetic (c) == 0) 1271 { 1272 inword = 0; 1273 start = next; 1274 continue; 1275 } 1276 1277 if (op == CapCase) 1278 { 1279 nop = inword ? DownCase : UpCase; 1280 inword = 1; 1281 } 1282 else 1283 nop = op; 1284 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c)) 1285 { 1286 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); 1287 rl_line_buffer[start] = nc; 1288 } 1289 #if defined (HANDLE_MULTIBYTE) 1290 else 1291 { 1292 mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); 1293 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); 1294 if (nwc != wc) /* just skip unchanged characters */ 1295 { 1296 mlen = wcrtomb (mb, nwc, &mps); 1297 if (mlen > 0) 1298 mb[mlen] = '\0'; 1299 /* Assume the same width */ 1300 strncpy (rl_line_buffer + start, mb, mlen); 1301 } 1302 } 1303 #endif 1304 1305 start = next; 1306 } 1307 1308 rl_point = end; 1309 return 0; 1310 } 1311 1312 /* **************************************************************** */ 1313 /* */ 1314 /* Transposition */ 1315 /* */ 1316 /* **************************************************************** */ 1317 1318 /* Transpose the words at point. If point is at the end of the line, 1319 transpose the two words before point. */ 1320 int 1321 rl_transpose_words (count, key) 1322 int count, key; 1323 { 1324 char *word1, *word2; 1325 int w1_beg, w1_end, w2_beg, w2_end; 1326 int orig_point = rl_point; 1327 1328 if (!count) 1329 return 0; 1330 1331 /* Find the two words. */ 1332 rl_forward_word (count, key); 1333 w2_end = rl_point; 1334 rl_backward_word (1, key); 1335 w2_beg = rl_point; 1336 rl_backward_word (count, key); 1337 w1_beg = rl_point; 1338 rl_forward_word (1, key); 1339 w1_end = rl_point; 1340 1341 /* Do some check to make sure that there really are two words. */ 1342 if ((w1_beg == w2_beg) || (w2_beg < w1_end)) 1343 { 1344 rl_ding (); 1345 rl_point = orig_point; 1346 return -1; 1347 } 1348 1349 /* Get the text of the words. */ 1350 word1 = rl_copy_text (w1_beg, w1_end); 1351 word2 = rl_copy_text (w2_beg, w2_end); 1352 1353 /* We are about to do many insertions and deletions. Remember them 1354 as one operation. */ 1355 rl_begin_undo_group (); 1356 1357 /* Do the stuff at word2 first, so that we don't have to worry 1358 about word1 moving. */ 1359 rl_point = w2_beg; 1360 rl_delete_text (w2_beg, w2_end); 1361 rl_insert_text (word1); 1362 1363 rl_point = w1_beg; 1364 rl_delete_text (w1_beg, w1_end); 1365 rl_insert_text (word2); 1366 1367 /* This is exactly correct since the text before this point has not 1368 changed in length. */ 1369 rl_point = w2_end; 1370 1371 /* I think that does it. */ 1372 rl_end_undo_group (); 1373 free (word1); 1374 free (word2); 1375 1376 return 0; 1377 } 1378 1379 /* Transpose the characters at point. If point is at the end of the line, 1380 then transpose the characters before point. */ 1381 int 1382 rl_transpose_chars (count, key) 1383 int count, key __attribute__((unused)); 1384 { 1385 #if defined (HANDLE_MULTIBYTE) 1386 char *dummy; 1387 int i; 1388 int prev_point; 1389 #else 1390 char dummy[2]; 1391 #endif 1392 int char_length; 1393 1394 if (count == 0) 1395 return 0; 1396 1397 if (!rl_point || rl_end < 2) 1398 { 1399 rl_ding (); 1400 return -1; 1401 } 1402 1403 rl_begin_undo_group (); 1404 1405 if (rl_point == rl_end) 1406 { 1407 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1408 count = 1; 1409 } 1410 1411 #if defined (HANDLE_MULTIBYTE) 1412 prev_point = rl_point; 1413 #endif 1414 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1415 1416 #if defined (HANDLE_MULTIBYTE) 1417 char_length = prev_point - rl_point; 1418 dummy = (char *)xmalloc (char_length + 1); 1419 for (i = 0; i < char_length; i++) 1420 dummy[i] = rl_line_buffer[rl_point + i]; 1421 dummy[i] = '\0'; 1422 #else 1423 dummy[0] = rl_line_buffer[rl_point]; 1424 dummy[char_length = 1] = '\0'; 1425 #endif 1426 1427 rl_delete_text (rl_point, rl_point + char_length); 1428 1429 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 1430 1431 _rl_fix_point (0); 1432 rl_insert_text (dummy); 1433 rl_end_undo_group (); 1434 1435 #if defined (HANDLE_MULTIBYTE) 1436 free (dummy); 1437 #endif 1438 1439 return 0; 1440 } 1441 1442 /* **************************************************************** */ 1443 /* */ 1444 /* Character Searching */ 1445 /* */ 1446 /* **************************************************************** */ 1447 1448 int 1449 #if defined (HANDLE_MULTIBYTE) 1450 _rl_char_search_internal (count, dir, smbchar, len) 1451 int count, dir; 1452 char *smbchar; 1453 int len; 1454 #else 1455 _rl_char_search_internal (count, dir, schar) 1456 int count, dir, schar; 1457 #endif 1458 { 1459 int pos, inc; 1460 #if defined (HANDLE_MULTIBYTE) 1461 int prepos; 1462 #endif 1463 1464 pos = rl_point; 1465 inc = (dir < 0) ? -1 : 1; 1466 while (count) 1467 { 1468 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) 1469 { 1470 rl_ding (); 1471 return -1; 1472 } 1473 1474 #if defined (HANDLE_MULTIBYTE) 1475 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1476 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); 1477 #else 1478 pos += inc; 1479 #endif 1480 do 1481 { 1482 #if defined (HANDLE_MULTIBYTE) 1483 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) 1484 #else 1485 if (rl_line_buffer[pos] == schar) 1486 #endif 1487 { 1488 count--; 1489 if (dir < 0) 1490 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1491 : pos; 1492 else 1493 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) 1494 : pos; 1495 break; 1496 } 1497 #if defined (HANDLE_MULTIBYTE) 1498 prepos = pos; 1499 #endif 1500 } 1501 #if defined (HANDLE_MULTIBYTE) 1502 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos 1503 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); 1504 #else 1505 while ((dir < 0) ? pos-- : ++pos < rl_end); 1506 #endif 1507 } 1508 return (0); 1509 } 1510 1511 /* Search COUNT times for a character read from the current input stream. 1512 FDIR is the direction to search if COUNT is non-negative; otherwise 1513 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE 1514 that there are two separate versions of this function. */ 1515 #if defined (HANDLE_MULTIBYTE) 1516 static int 1517 _rl_char_search (count, fdir, bdir) 1518 int count, fdir, bdir; 1519 { 1520 char mbchar[MB_LEN_MAX]; 1521 int mb_len; 1522 1523 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); 1524 1525 if (count < 0) 1526 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); 1527 else 1528 return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); 1529 } 1530 #else /* !HANDLE_MULTIBYTE */ 1531 static int 1532 _rl_char_search (count, fdir, bdir) 1533 int count, fdir, bdir; 1534 { 1535 int c; 1536 1537 RL_SETSTATE(RL_STATE_MOREINPUT); 1538 c = rl_read_key (); 1539 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1540 1541 if (count < 0) 1542 return (_rl_char_search_internal (-count, bdir, c)); 1543 else 1544 return (_rl_char_search_internal (count, fdir, c)); 1545 } 1546 #endif /* !HANDLE_MULTIBYTE */ 1547 1548 #if defined (READLINE_CALLBACKS) 1549 static int 1550 _rl_char_search_callback (data) 1551 _rl_callback_generic_arg *data; 1552 { 1553 _rl_callback_func = 0; 1554 _rl_want_redisplay = 1; 1555 1556 return (_rl_char_search (data->count, data->i1, data->i2)); 1557 } 1558 #endif 1559 1560 int 1561 rl_char_search (count, key) 1562 int count, key __attribute__((unused)); 1563 { 1564 #if defined (READLINE_CALLBACKS) 1565 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1566 { 1567 _rl_callback_data = _rl_callback_data_alloc (count); 1568 _rl_callback_data->i1 = FFIND; 1569 _rl_callback_data->i2 = BFIND; 1570 _rl_callback_func = _rl_char_search_callback; 1571 return (0); 1572 } 1573 #endif 1574 1575 return (_rl_char_search (count, FFIND, BFIND)); 1576 } 1577 1578 int 1579 rl_backward_char_search (count, key) 1580 int count, key __attribute__((unused)); 1581 { 1582 #if defined (READLINE_CALLBACKS) 1583 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1584 { 1585 _rl_callback_data = _rl_callback_data_alloc (count); 1586 _rl_callback_data->i1 = BFIND; 1587 _rl_callback_data->i2 = FFIND; 1588 _rl_callback_func = _rl_char_search_callback; 1589 return (0); 1590 } 1591 #endif 1592 1593 return (_rl_char_search (count, BFIND, FFIND)); 1594 } 1595 1596 /* **************************************************************** */ 1597 /* */ 1598 /* The Mark and the Region. */ 1599 /* */ 1600 /* **************************************************************** */ 1601 1602 /* Set the mark at POSITION. */ 1603 int 1604 _rl_set_mark_at_pos (position) 1605 int position; 1606 { 1607 if (position > rl_end) 1608 return -1; 1609 1610 rl_mark = position; 1611 return 0; 1612 } 1613 1614 /* A bindable command to set the mark. */ 1615 int 1616 rl_set_mark (count, key) 1617 int count, key __attribute__((unused)); 1618 { 1619 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); 1620 } 1621 1622 /* Exchange the position of mark and point. */ 1623 int 1624 rl_exchange_point_and_mark (count, key) 1625 int count __attribute__((unused)), key __attribute__((unused)); 1626 { 1627 if (rl_mark > rl_end) 1628 rl_mark = -1; 1629 1630 if (rl_mark == -1) 1631 { 1632 rl_ding (); 1633 return -1; 1634 } 1635 else 1636 SWAP (rl_point, rl_mark); 1637 1638 return 0; 1639 } 1640