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 if (rl_point == rl_end) { 300 rl_ding(); 301 return 0; 302 } 303 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 304 305#if defined (VI_MODE) 306 if (rl_end <= point && rl_editing_mode == vi_mode) 307 point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO); 308#endif 309 310 if (rl_point == point) 311 rl_ding (); 312 313 rl_point = point; 314 315 if (rl_end < 0) 316 rl_end = 0; 317 } 318 319 return 0; 320} 321#else /* !HANDLE_MULTIBYTE */ 322int 323rl_forward_char (count, key) 324 int count, key; 325{ 326 return (rl_forward_byte (count, key)); 327} 328#endif /* !HANDLE_MULTIBYTE */ 329 330/* Backwards compatibility. */ 331int 332rl_forward (count, key) 333 int count, key; 334{ 335 return (rl_forward_char (count, key)); 336} 337 338/* Move backward COUNT bytes. */ 339int 340rl_backward_byte (count, key) 341 int count, key; 342{ 343 if (count < 0) 344 return (rl_forward_byte (-count, key)); 345 346 if (count > 0) 347 { 348 if (rl_point < count) 349 { 350 rl_point = 0; 351 rl_ding (); 352 } 353 else 354 rl_point -= count; 355 } 356 357 if (rl_point < 0) 358 rl_point = 0; 359 360 return 0; 361} 362 363#if defined (HANDLE_MULTIBYTE) 364/* Move backward COUNT characters. */ 365int 366rl_backward_char (count, key) 367 int count, key; 368{ 369 int point; 370 371 if (MB_CUR_MAX == 1 || rl_byte_oriented) 372 return (rl_backward_byte (count, key)); 373 374 if (count < 0) 375 return (rl_forward_char (-count, key)); 376 377 if (count > 0) 378 { 379 point = rl_point; 380 381 while (count > 0 && point > 0) 382 { 383 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); 384 count--; 385 } 386 if (count > 0) 387 { 388 rl_point = 0; 389 rl_ding (); 390 } 391 else 392 rl_point = point; 393 } 394 395 return 0; 396} 397#else 398int 399rl_backward_char (count, key) 400 int count, key; 401{ 402 return (rl_backward_byte (count, key)); 403} 404#endif 405 406/* Backwards compatibility. */ 407int 408rl_backward (count, key) 409 int count, key; 410{ 411 return (rl_backward_char (count, key)); 412} 413 414/* Move to the beginning of the line. */ 415int 416rl_beg_of_line (count, key) 417 int count, key; 418{ 419 rl_point = 0; 420 return 0; 421} 422 423/* Move to the end of the line. */ 424int 425rl_end_of_line (count, key) 426 int count, key; 427{ 428 rl_point = rl_end; 429 return 0; 430} 431 432/* Move forward a word. We do what Emacs does. Handles multibyte chars. */ 433int 434rl_forward_word (count, key) 435 int count, key; 436{ 437 int c; 438 439 if (count < 0) 440 return (rl_backward_word (-count, key)); 441 442 while (count) 443 { 444 if (rl_point == rl_end) 445 return 0; 446 447 /* If we are not in a word, move forward until we are in one. 448 Then, move forward until we hit a non-alphabetic character. */ 449 c = _rl_char_value (rl_line_buffer, rl_point); 450 451 if (_rl_walphabetic (c) == 0) 452 { 453 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 454 while (rl_point < rl_end) 455 { 456 c = _rl_char_value (rl_line_buffer, rl_point); 457 if (_rl_walphabetic (c)) 458 break; 459 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 460 } 461 } 462 463 if (rl_point == rl_end) 464 return 0; 465 466 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 467 while (rl_point < rl_end) 468 { 469 c = _rl_char_value (rl_line_buffer, rl_point); 470 if (_rl_walphabetic (c) == 0) 471 break; 472 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 473 } 474 475 --count; 476 } 477 478 return 0; 479} 480 481/* Move backward a word. We do what Emacs does. Handles multibyte chars. */ 482int 483rl_backward_word (count, key) 484 int count, key; 485{ 486 int c, p; 487 488 if (count < 0) 489 return (rl_forward_word (-count, key)); 490 491 while (count) 492 { 493 if (rl_point == 0) 494 return 0; 495 496 /* Like rl_forward_word (), except that we look at the characters 497 just before point. */ 498 499 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 500 c = _rl_char_value (rl_line_buffer, p); 501 502 if (_rl_walphabetic (c) == 0) 503 { 504 rl_point = p; 505 while (rl_point > 0) 506 { 507 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 508 c = _rl_char_value (rl_line_buffer, p); 509 if (_rl_walphabetic (c)) 510 break; 511 rl_point = p; 512 } 513 } 514 515 while (rl_point) 516 { 517 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 518 c = _rl_char_value (rl_line_buffer, p); 519 if (_rl_walphabetic (c) == 0) 520 break; 521 else 522 rl_point = p; 523 } 524 525 --count; 526 } 527 528 return 0; 529} 530 531/* Clear the current line. Numeric argument to C-l does this. */ 532int 533rl_refresh_line (ignore1, ignore2) 534 int ignore1, ignore2; 535{ 536 int curr_line; 537 538 curr_line = _rl_current_display_line (); 539 540 _rl_move_vert (curr_line); 541 _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */ 542 543 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */ 544 545 rl_forced_update_display (); 546 rl_display_fixed = 1; 547 548 return 0; 549} 550 551/* C-l typed to a line without quoting clears the screen, and then reprints 552 the prompt and the current input line. Given a numeric arg, redraw only 553 the current line. */ 554int 555rl_clear_screen (count, key) 556 int count, key; 557{ 558 if (rl_explicit_arg) 559 { 560 rl_refresh_line (count, key); 561 return 0; 562 } 563 564 _rl_clear_screen (); /* calls termcap function to clear screen */ 565 rl_forced_update_display (); 566 rl_display_fixed = 1; 567 568 return 0; 569} 570 571int 572rl_arrow_keys (count, c) 573 int count, c; 574{ 575 int ch; 576 577 RL_SETSTATE(RL_STATE_MOREINPUT); 578 ch = rl_read_key (); 579 RL_UNSETSTATE(RL_STATE_MOREINPUT); 580 581 switch (_rl_to_upper (ch)) 582 { 583 case 'A': 584 rl_get_previous_history (count, ch); 585 break; 586 587 case 'B': 588 rl_get_next_history (count, ch); 589 break; 590 591 case 'C': 592 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 593 rl_forward_char (count, ch); 594 else 595 rl_forward_byte (count, ch); 596 break; 597 598 case 'D': 599 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 600 rl_backward_char (count, ch); 601 else 602 rl_backward_byte (count, ch); 603 break; 604 605 default: 606 rl_ding (); 607 } 608 609 return 0; 610} 611 612/* **************************************************************** */ 613/* */ 614/* Text commands */ 615/* */ 616/* **************************************************************** */ 617 618#ifdef HANDLE_MULTIBYTE 619static char pending_bytes[MB_LEN_MAX]; 620static int pending_bytes_length = 0; 621static mbstate_t ps = {0}; 622#endif 623 624/* Insert the character C at the current location, moving point forward. 625 If C introduces a multibyte sequence, we read the whole sequence and 626 then insert the multibyte char into the line buffer. */ 627int 628_rl_insert_char (count, c) 629 int count, c; 630{ 631 register int i; 632 char *string; 633#ifdef HANDLE_MULTIBYTE 634 int string_size; 635 char incoming[MB_LEN_MAX + 1]; 636 int incoming_length = 0; 637 mbstate_t ps_back; 638 static int stored_count = 0; 639#endif 640 641 if (count <= 0) 642 return 0; 643 644#if defined (HANDLE_MULTIBYTE) 645 if (MB_CUR_MAX == 1 || rl_byte_oriented) 646 { 647 incoming[0] = c; 648 incoming[1] = '\0'; 649 incoming_length = 1; 650 } 651 else 652 { 653 wchar_t wc; 654 size_t ret; 655 656 if (stored_count <= 0) 657 stored_count = count; 658 else 659 count = stored_count; 660 661 ps_back = ps; 662 pending_bytes[pending_bytes_length++] = c; 663 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps); 664 665 if (ret == (size_t)-2) 666 { 667 /* Bytes too short to compose character, try to wait for next byte. 668 Restore the state of the byte sequence, because in this case the 669 effect of mbstate is undefined. */ 670 ps = ps_back; 671 return 1; 672 } 673 else if (ret == (size_t)-1) 674 { 675 /* Invalid byte sequence for the current locale. Treat first byte 676 as a single character. */ 677 incoming[0] = pending_bytes[0]; 678 incoming[1] = '\0'; 679 incoming_length = 1; 680 pending_bytes_length--; 681 memmove (pending_bytes, pending_bytes + 1, pending_bytes_length); 682 /* Clear the state of the byte sequence, because in this case the 683 effect of mbstate is undefined. */ 684 memset (&ps, 0, sizeof (mbstate_t)); 685 } 686 else if (ret == (size_t)0) 687 { 688 incoming[0] = '\0'; 689 incoming_length = 0; 690 pending_bytes_length--; 691 /* Clear the state of the byte sequence, because in this case the 692 effect of mbstate is undefined. */ 693 memset (&ps, 0, sizeof (mbstate_t)); 694 } 695 else 696 { 697 /* We successfully read a single multibyte character. */ 698 memcpy (incoming, pending_bytes, pending_bytes_length); 699 incoming[pending_bytes_length] = '\0'; 700 incoming_length = pending_bytes_length; 701 pending_bytes_length = 0; 702 } 703 } 704#endif /* HANDLE_MULTIBYTE */ 705 706 /* If we can optimize, then do it. But don't let people crash 707 readline because of extra large arguments. */ 708 if (count > 1 && count <= 1024) 709 { 710#if defined (HANDLE_MULTIBYTE) 711 string_size = count * incoming_length; 712 string = (char *)xmalloc (1 + string_size); 713 714 i = 0; 715 while (i < string_size) 716 { 717 strncpy (string + i, incoming, incoming_length); 718 i += incoming_length; 719 } 720 incoming_length = 0; 721 stored_count = 0; 722#else /* !HANDLE_MULTIBYTE */ 723 string = (char *)xmalloc (1 + count); 724 725 for (i = 0; i < count; i++) 726 string[i] = c; 727#endif /* !HANDLE_MULTIBYTE */ 728 729 string[i] = '\0'; 730 rl_insert_text (string); 731 free (string); 732 733 return 0; 734 } 735 736 if (count > 1024) 737 { 738 int decreaser; 739#if defined (HANDLE_MULTIBYTE) 740 string_size = incoming_length * 1024; 741 string = (char *)xmalloc (1 + string_size); 742 743 i = 0; 744 while (i < string_size) 745 { 746 strncpy (string + i, incoming, incoming_length); 747 i += incoming_length; 748 } 749 750 while (count) 751 { 752 decreaser = (count > 1024) ? 1024 : count; 753 string[decreaser*incoming_length] = '\0'; 754 rl_insert_text (string); 755 count -= decreaser; 756 } 757 758 free (string); 759 incoming_length = 0; 760 stored_count = 0; 761#else /* !HANDLE_MULTIBYTE */ 762 char str[1024+1]; 763 764 for (i = 0; i < 1024; i++) 765 str[i] = c; 766 767 while (count) 768 { 769 decreaser = (count > 1024 ? 1024 : count); 770 str[decreaser] = '\0'; 771 rl_insert_text (str); 772 count -= decreaser; 773 } 774#endif /* !HANDLE_MULTIBYTE */ 775 776 return 0; 777 } 778 779 if (MB_CUR_MAX == 1 || rl_byte_oriented) 780 { 781 /* We are inserting a single character. 782 If there is pending input, then make a string of all of the 783 pending characters that are bound to rl_insert, and insert 784 them all. */ 785 if (_rl_any_typein ()) 786 _rl_insert_typein (c); 787 else 788 { 789 /* Inserting a single character. */ 790 char str[2]; 791 792 str[1] = '\0'; 793 str[0] = c; 794 rl_insert_text (str); 795 } 796 } 797#if defined (HANDLE_MULTIBYTE) 798 else 799 { 800 rl_insert_text (incoming); 801 stored_count = 0; 802 } 803#endif 804 805 return 0; 806} 807 808/* Overwrite the character at point (or next COUNT characters) with C. 809 If C introduces a multibyte character sequence, read the entire sequence 810 before starting the overwrite loop. */ 811int 812_rl_overwrite_char (count, c) 813 int count, c; 814{ 815 int i; 816#if defined (HANDLE_MULTIBYTE) 817 char mbkey[MB_LEN_MAX]; 818 int k; 819 820 /* Read an entire multibyte character sequence to insert COUNT times. */ 821 if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) 822 k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); 823#endif 824 825 rl_begin_undo_group (); 826 827 for (i = 0; i < count; i++) 828 { 829#if defined (HANDLE_MULTIBYTE) 830 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 831 rl_insert_text (mbkey); 832 else 833#endif 834 _rl_insert_char (1, c); 835 836 if (rl_point < rl_end) 837 rl_delete (1, c); 838 } 839 840 rl_end_undo_group (); 841 842 return 0; 843} 844 845int 846rl_insert (count, c) 847 int count, c; 848{ 849 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c) 850 : _rl_overwrite_char (count, c)); 851} 852 853/* Insert the next typed character verbatim. */ 854static int 855_rl_insert_next (count) 856 int count; 857{ 858 int c; 859 860 RL_SETSTATE(RL_STATE_MOREINPUT); 861 c = rl_read_key (); 862 RL_UNSETSTATE(RL_STATE_MOREINPUT); 863 864 if (c < 0) 865 return -1; 866 867#if defined (HANDLE_SIGNALS) 868 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 869 _rl_restore_tty_signals (); 870#endif 871 872 return (_rl_insert_char (count, c)); 873} 874 875#if defined (READLINE_CALLBACKS) 876static int 877_rl_insert_next_callback (data) 878 _rl_callback_generic_arg *data; 879{ 880 int count; 881 882 count = data->count; 883 884 /* Deregister function, let rl_callback_read_char deallocate data */ 885 _rl_callback_func = 0; 886 _rl_want_redisplay = 1; 887 888 return _rl_insert_next (count); 889} 890#endif 891 892int 893rl_quoted_insert (count, key) 894 int count, key; 895{ 896 /* Let's see...should the callback interface futz with signal handling? */ 897#if defined (HANDLE_SIGNALS) 898 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 899 _rl_disable_tty_signals (); 900#endif 901 902#if defined (READLINE_CALLBACKS) 903 if (RL_ISSTATE (RL_STATE_CALLBACK)) 904 { 905 _rl_callback_data = _rl_callback_data_alloc (count); 906 _rl_callback_func = _rl_insert_next_callback; 907 return (0); 908 } 909#endif 910 911 return _rl_insert_next (count); 912} 913 914/* Insert a tab character. */ 915int 916rl_tab_insert (count, key) 917 int count, key; 918{ 919 return (_rl_insert_char (count, '\t')); 920} 921 922/* What to do when a NEWLINE is pressed. We accept the whole line. 923 KEY is the key that invoked this command. I guess it could have 924 meaning in the future. */ 925int 926rl_newline (count, key) 927 int count, key; 928{ 929 rl_done = 1; 930 931 if (_rl_history_preserve_point) 932 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; 933 934 RL_SETSTATE(RL_STATE_DONE); 935 936#if defined (VI_MODE) 937 if (rl_editing_mode == vi_mode) 938 { 939 _rl_vi_done_inserting (); 940 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */ 941 _rl_vi_reset_last (); 942 } 943#endif /* VI_MODE */ 944 945 /* If we've been asked to erase empty lines, suppress the final update, 946 since _rl_update_final calls rl_crlf(). */ 947 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) 948 return 0; 949 950 if (readline_echoing_p) 951 _rl_update_final (); 952 return 0; 953} 954 955/* What to do for some uppercase characters, like meta characters, 956 and some characters appearing in emacs_ctlx_keymap. This function 957 is just a stub, you bind keys to it and the code in _rl_dispatch () 958 is special cased. */ 959int 960rl_do_lowercase_version (ignore1, ignore2) 961 int ignore1, ignore2; 962{ 963 return 0; 964} 965 966/* This is different from what vi does, so the code's not shared. Emacs 967 rubout in overwrite mode has one oddity: it replaces a control 968 character that's displayed as two characters (^X) with two spaces. */ 969int 970_rl_overwrite_rubout (count, key) 971 int count, key; 972{ 973 int opoint; 974 int i, l; 975 976 if (rl_point == 0) 977 { 978 rl_ding (); 979 return 1; 980 } 981 982 opoint = rl_point; 983 984 /* L == number of spaces to insert */ 985 for (i = l = 0; i < count; i++) 986 { 987 rl_backward_char (1, key); 988 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ 989 } 990 991 rl_begin_undo_group (); 992 993 if (count > 1 || rl_explicit_arg) 994 rl_kill_text (opoint, rl_point); 995 else 996 rl_delete_text (opoint, rl_point); 997 998 /* Emacs puts point at the beginning of the sequence of spaces. */ 999 if (rl_point < rl_end) 1000 { 1001 opoint = rl_point; 1002 _rl_insert_char (l, ' '); 1003 rl_point = opoint; 1004 } 1005 1006 rl_end_undo_group (); 1007 1008 return 0; 1009} 1010 1011/* Rubout the character behind point. */ 1012int 1013rl_rubout (count, key) 1014 int count, key; 1015{ 1016 if (count < 0) 1017 return (rl_delete (-count, key)); 1018 1019 if (!rl_point) 1020 { 1021 rl_ding (); 1022 return -1; 1023 } 1024 1025 if (rl_insert_mode == RL_IM_OVERWRITE) 1026 return (_rl_overwrite_rubout (count, key)); 1027 1028 return (_rl_rubout_char (count, key)); 1029} 1030 1031int 1032_rl_rubout_char (count, key) 1033 int count, key; 1034{ 1035 int orig_point; 1036 unsigned char c; 1037 1038 /* Duplicated code because this is called from other parts of the library. */ 1039 if (count < 0) 1040 return (rl_delete (-count, key)); 1041 1042 if (rl_point == 0) 1043 { 1044 rl_ding (); 1045 return -1; 1046 } 1047 1048 orig_point = rl_point; 1049 if (count > 1 || rl_explicit_arg) 1050 { 1051 rl_backward_char (count, key); 1052 rl_kill_text (orig_point, rl_point); 1053 } 1054 else if (MB_CUR_MAX == 1 || rl_byte_oriented) 1055 { 1056 c = rl_line_buffer[--rl_point]; 1057 rl_delete_text (rl_point, orig_point); 1058 /* The erase-at-end-of-line hack is of questionable merit now. */ 1059 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) 1060 { 1061 int l; 1062 l = rl_character_len (c, rl_point); 1063 _rl_erase_at_end_of_line (l); 1064 } 1065 } 1066 else 1067 { 1068 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1069 rl_delete_text (rl_point, orig_point); 1070 } 1071 1072 return 0; 1073} 1074 1075/* Delete the character under the cursor. Given a numeric argument, 1076 kill that many characters instead. */ 1077int 1078rl_delete (count, key) 1079 int count, key; 1080{ 1081 int xpoint; 1082 1083 if (count < 0) 1084 return (_rl_rubout_char (-count, key)); 1085 1086 if (rl_point == rl_end) 1087 { 1088 rl_ding (); 1089 return -1; 1090 } 1091 1092 if (count > 1 || rl_explicit_arg) 1093 { 1094 xpoint = rl_point; 1095 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1096 rl_forward_char (count, key); 1097 else 1098 rl_forward_byte (count, key); 1099 1100 rl_kill_text (xpoint, rl_point); 1101 rl_point = xpoint; 1102 } 1103 else 1104 { 1105 xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); 1106 rl_delete_text (rl_point, xpoint); 1107 } 1108 return 0; 1109} 1110 1111/* Delete the character under the cursor, unless the insertion 1112 point is at the end of the line, in which case the character 1113 behind the cursor is deleted. COUNT is obeyed and may be used 1114 to delete forward or backward that many characters. */ 1115int 1116rl_rubout_or_delete (count, key) 1117 int count, key; 1118{ 1119 if (rl_end != 0 && rl_point == rl_end) 1120 return (_rl_rubout_char (count, key)); 1121 else 1122 return (rl_delete (count, key)); 1123} 1124 1125/* Delete all spaces and tabs around point. */ 1126int 1127rl_delete_horizontal_space (count, ignore) 1128 int count, ignore; 1129{ 1130 int start = rl_point; 1131 1132 while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) 1133 rl_point--; 1134 1135 start = rl_point; 1136 1137 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) 1138 rl_point++; 1139 1140 if (start != rl_point) 1141 { 1142 rl_delete_text (start, rl_point); 1143 rl_point = start; 1144 } 1145 1146 if (rl_point < 0) 1147 rl_point = 0; 1148 1149 return 0; 1150} 1151 1152/* Like the tcsh editing function delete-char-or-list. The eof character 1153 is caught before this is invoked, so this really does the same thing as 1154 delete-char-or-list-or-eof, as long as it's bound to the eof character. */ 1155int 1156rl_delete_or_show_completions (count, key) 1157 int count, key; 1158{ 1159 if (rl_end != 0 && rl_point == rl_end) 1160 return (rl_possible_completions (count, key)); 1161 else 1162 return (rl_delete (count, key)); 1163} 1164 1165#ifndef RL_COMMENT_BEGIN_DEFAULT 1166#define RL_COMMENT_BEGIN_DEFAULT "#" 1167#endif 1168 1169/* Turn the current line into a comment in shell history. 1170 A K*rn shell style function. */ 1171int 1172rl_insert_comment (count, key) 1173 int count, key; 1174{ 1175 char *rl_comment_text; 1176 int rl_comment_len; 1177 1178 rl_beg_of_line (1, key); 1179 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT; 1180 1181 if (rl_explicit_arg == 0) 1182 rl_insert_text (rl_comment_text); 1183 else 1184 { 1185 rl_comment_len = strlen (rl_comment_text); 1186 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) 1187 rl_delete_text (rl_point, rl_point + rl_comment_len); 1188 else 1189 rl_insert_text (rl_comment_text); 1190 } 1191 1192 (*rl_redisplay_function) (); 1193 rl_newline (1, '\n'); 1194 1195 return (0); 1196} 1197 1198/* **************************************************************** */ 1199/* */ 1200/* Changing Case */ 1201/* */ 1202/* **************************************************************** */ 1203 1204/* The three kinds of things that we know how to do. */ 1205#define UpCase 1 1206#define DownCase 2 1207#define CapCase 3 1208 1209/* Uppercase the word at point. */ 1210int 1211rl_upcase_word (count, key) 1212 int count, key; 1213{ 1214 return (rl_change_case (count, UpCase)); 1215} 1216 1217/* Lowercase the word at point. */ 1218int 1219rl_downcase_word (count, key) 1220 int count, key; 1221{ 1222 return (rl_change_case (count, DownCase)); 1223} 1224 1225/* Upcase the first letter, downcase the rest. */ 1226int 1227rl_capitalize_word (count, key) 1228 int count, key; 1229{ 1230 return (rl_change_case (count, CapCase)); 1231} 1232 1233/* The meaty function. 1234 Change the case of COUNT words, performing OP on them. 1235 OP is one of UpCase, DownCase, or CapCase. 1236 If a negative argument is given, leave point where it started, 1237 otherwise, leave it where it moves to. */ 1238static int 1239rl_change_case (count, op) 1240 int count, op; 1241{ 1242 int start, next, end; 1243 int inword, c, nc, nop; 1244#if defined (HANDLE_MULTIBYTE) 1245 wchar_t wc, nwc; 1246 char mb[MB_LEN_MAX+1]; 1247 int mlen; 1248 mbstate_t mps; 1249#endif 1250 1251 start = rl_point; 1252 rl_forward_word (count, 0); 1253 end = rl_point; 1254 1255 if (op != UpCase && op != DownCase && op != CapCase) 1256 { 1257 rl_ding (); 1258 return -1; 1259 } 1260 1261 if (count < 0) 1262 SWAP (start, end); 1263 1264#if defined (HANDLE_MULTIBYTE) 1265 memset (&mps, 0, sizeof (mbstate_t)); 1266#endif 1267 1268 /* We are going to modify some text, so let's prepare to undo it. */ 1269 rl_modifying (start, end); 1270 1271 inword = 0; 1272 while (start < end) 1273 { 1274 c = _rl_char_value (rl_line_buffer, start); 1275 /* This assumes that the upper and lower case versions are the same width. */ 1276 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO); 1277 1278 if (_rl_walphabetic (c) == 0) 1279 { 1280 inword = 0; 1281 start = next; 1282 continue; 1283 } 1284 1285 if (op == CapCase) 1286 { 1287 nop = inword ? DownCase : UpCase; 1288 inword = 1; 1289 } 1290 else 1291 nop = op; 1292 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c)) 1293 { 1294 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); 1295 rl_line_buffer[start] = nc; 1296 } 1297#if defined (HANDLE_MULTIBYTE) 1298 else 1299 { 1300 mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); 1301 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); 1302 if (nwc != wc) /* just skip unchanged characters */ 1303 { 1304 mlen = wcrtomb (mb, nwc, &mps); 1305 if (mlen > 0) 1306 mb[mlen] = '\0'; 1307 /* Assume the same width */ 1308 strncpy (rl_line_buffer + start, mb, mlen); 1309 } 1310 } 1311#endif 1312 1313 start = next; 1314 } 1315 1316 rl_point = end; 1317 return 0; 1318} 1319 1320/* **************************************************************** */ 1321/* */ 1322/* Transposition */ 1323/* */ 1324/* **************************************************************** */ 1325 1326/* Transpose the words at point. If point is at the end of the line, 1327 transpose the two words before point. */ 1328int 1329rl_transpose_words (count, key) 1330 int count, key; 1331{ 1332 char *word1, *word2; 1333 int w1_beg, w1_end, w2_beg, w2_end; 1334 int orig_point = rl_point; 1335 1336 if (!count) 1337 return 0; 1338 1339 /* Find the two words. */ 1340 rl_forward_word (count, key); 1341 w2_end = rl_point; 1342 rl_backward_word (1, key); 1343 w2_beg = rl_point; 1344 rl_backward_word (count, key); 1345 w1_beg = rl_point; 1346 rl_forward_word (1, key); 1347 w1_end = rl_point; 1348 1349 /* Do some check to make sure that there really are two words. */ 1350 if ((w1_beg == w2_beg) || (w2_beg < w1_end)) 1351 { 1352 rl_ding (); 1353 rl_point = orig_point; 1354 return -1; 1355 } 1356 1357 /* Get the text of the words. */ 1358 word1 = rl_copy_text (w1_beg, w1_end); 1359 word2 = rl_copy_text (w2_beg, w2_end); 1360 1361 /* We are about to do many insertions and deletions. Remember them 1362 as one operation. */ 1363 rl_begin_undo_group (); 1364 1365 /* Do the stuff at word2 first, so that we don't have to worry 1366 about word1 moving. */ 1367 rl_point = w2_beg; 1368 rl_delete_text (w2_beg, w2_end); 1369 rl_insert_text (word1); 1370 1371 rl_point = w1_beg; 1372 rl_delete_text (w1_beg, w1_end); 1373 rl_insert_text (word2); 1374 1375 /* This is exactly correct since the text before this point has not 1376 changed in length. */ 1377 rl_point = w2_end; 1378 1379 /* I think that does it. */ 1380 rl_end_undo_group (); 1381 free (word1); 1382 free (word2); 1383 1384 return 0; 1385} 1386 1387/* Transpose the characters at point. If point is at the end of the line, 1388 then transpose the characters before point. */ 1389int 1390rl_transpose_chars (count, key) 1391 int count, key; 1392{ 1393#if defined (HANDLE_MULTIBYTE) 1394 char *dummy; 1395 int i; 1396#else 1397 char dummy[2]; 1398#endif 1399 int char_length, prev_point; 1400 1401 if (count == 0) 1402 return 0; 1403 1404 if (!rl_point || rl_end < 2) 1405 { 1406 rl_ding (); 1407 return -1; 1408 } 1409 1410 rl_begin_undo_group (); 1411 1412 if (rl_point == rl_end) 1413 { 1414 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1415 count = 1; 1416 } 1417 1418 prev_point = rl_point; 1419 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1420 1421#if defined (HANDLE_MULTIBYTE) 1422 char_length = prev_point - rl_point; 1423 dummy = (char *)xmalloc (char_length + 1); 1424 for (i = 0; i < char_length; i++) 1425 dummy[i] = rl_line_buffer[rl_point + i]; 1426 dummy[i] = '\0'; 1427#else 1428 dummy[0] = rl_line_buffer[rl_point]; 1429 dummy[char_length = 1] = '\0'; 1430#endif 1431 1432 rl_delete_text (rl_point, rl_point + char_length); 1433 1434 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 1435 1436 _rl_fix_point (0); 1437 rl_insert_text (dummy); 1438 rl_end_undo_group (); 1439 1440#if defined (HANDLE_MULTIBYTE) 1441 free (dummy); 1442#endif 1443 1444 return 0; 1445} 1446 1447/* **************************************************************** */ 1448/* */ 1449/* Character Searching */ 1450/* */ 1451/* **************************************************************** */ 1452 1453int 1454#if defined (HANDLE_MULTIBYTE) 1455_rl_char_search_internal (count, dir, smbchar, len) 1456 int count, dir; 1457 char *smbchar; 1458 int len; 1459#else 1460_rl_char_search_internal (count, dir, schar) 1461 int count, dir, schar; 1462#endif 1463{ 1464 int pos, inc; 1465#if defined (HANDLE_MULTIBYTE) 1466 int prepos; 1467#endif 1468 1469 pos = rl_point; 1470 inc = (dir < 0) ? -1 : 1; 1471 while (count) 1472 { 1473 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) 1474 { 1475 rl_ding (); 1476 return -1; 1477 } 1478 1479#if defined (HANDLE_MULTIBYTE) 1480 pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1481 : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); 1482#else 1483 pos += inc; 1484#endif 1485 do 1486 { 1487#if defined (HANDLE_MULTIBYTE) 1488 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) 1489#else 1490 if (rl_line_buffer[pos] == schar) 1491#endif 1492 { 1493 count--; 1494 if (dir < 0) 1495 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) 1496 : pos; 1497 else 1498 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) 1499 : pos; 1500 break; 1501 } 1502#if defined (HANDLE_MULTIBYTE) 1503 prepos = pos; 1504#endif 1505 } 1506#if defined (HANDLE_MULTIBYTE) 1507 while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos 1508 : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); 1509#else 1510 while ((dir < 0) ? pos-- : ++pos < rl_end); 1511#endif 1512 } 1513 return (0); 1514} 1515 1516/* Search COUNT times for a character read from the current input stream. 1517 FDIR is the direction to search if COUNT is non-negative; otherwise 1518 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE 1519 that there are two separate versions of this function. */ 1520#if defined (HANDLE_MULTIBYTE) 1521static int 1522_rl_char_search (count, fdir, bdir) 1523 int count, fdir, bdir; 1524{ 1525 char mbchar[MB_LEN_MAX]; 1526 int mb_len; 1527 1528 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); 1529 1530 if (mb_len <= 0) 1531 return -1; 1532 1533 if (count < 0) 1534 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); 1535 else 1536 return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); 1537} 1538#else /* !HANDLE_MULTIBYTE */ 1539static int 1540_rl_char_search (count, fdir, bdir) 1541 int count, fdir, bdir; 1542{ 1543 int c; 1544 1545 RL_SETSTATE(RL_STATE_MOREINPUT); 1546 c = rl_read_key (); 1547 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1548 1549 if (c < 0) 1550 return -1; 1551 1552 if (count < 0) 1553 return (_rl_char_search_internal (-count, bdir, c)); 1554 else 1555 return (_rl_char_search_internal (count, fdir, c)); 1556} 1557#endif /* !HANDLE_MULTIBYTE */ 1558 1559#if defined (READLINE_CALLBACKS) 1560static int 1561_rl_char_search_callback (data) 1562 _rl_callback_generic_arg *data; 1563{ 1564 _rl_callback_func = 0; 1565 _rl_want_redisplay = 1; 1566 1567 return (_rl_char_search (data->count, data->i1, data->i2)); 1568} 1569#endif 1570 1571int 1572rl_char_search (count, key) 1573 int count, key; 1574{ 1575#if defined (READLINE_CALLBACKS) 1576 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1577 { 1578 _rl_callback_data = _rl_callback_data_alloc (count); 1579 _rl_callback_data->i1 = FFIND; 1580 _rl_callback_data->i2 = BFIND; 1581 _rl_callback_func = _rl_char_search_callback; 1582 return (0); 1583 } 1584#endif 1585 1586 return (_rl_char_search (count, FFIND, BFIND)); 1587} 1588 1589int 1590rl_backward_char_search (count, key) 1591 int count, key; 1592{ 1593#if defined (READLINE_CALLBACKS) 1594 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1595 { 1596 _rl_callback_data = _rl_callback_data_alloc (count); 1597 _rl_callback_data->i1 = BFIND; 1598 _rl_callback_data->i2 = FFIND; 1599 _rl_callback_func = _rl_char_search_callback; 1600 return (0); 1601 } 1602#endif 1603 1604 return (_rl_char_search (count, BFIND, FFIND)); 1605} 1606 1607/* **************************************************************** */ 1608/* */ 1609/* The Mark and the Region. */ 1610/* */ 1611/* **************************************************************** */ 1612 1613/* Set the mark at POSITION. */ 1614int 1615_rl_set_mark_at_pos (position) 1616 int position; 1617{ 1618 if (position > rl_end) 1619 return -1; 1620 1621 rl_mark = position; 1622 return 0; 1623} 1624 1625/* A bindable command to set the mark. */ 1626int 1627rl_set_mark (count, key) 1628 int count, key; 1629{ 1630 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); 1631} 1632 1633/* Exchange the position of mark and point. */ 1634int 1635rl_exchange_point_and_mark (count, key) 1636 int count, key; 1637{ 1638 if (rl_mark > rl_end) 1639 rl_mark = -1; 1640 1641 if (rl_mark == -1) 1642 { 1643 rl_ding (); 1644 return -1; 1645 } 1646 else 1647 SWAP (rl_point, rl_mark); 1648 1649 return 0; 1650} 1651