1 /* text.c -- text handling commands for readline. */
3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
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.
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.
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
24 #if defined (HAVE_CONFIG_H)
28 #if defined (HAVE_UNISTD_H)
30 #endif /* HAVE_UNISTD_H */
32 #if defined (HAVE_STDLIB_H)
35 # include "ansi_stdlib.h"
36 #endif /* HAVE_STDLIB_H */
38 #if defined (HAVE_LOCALE_H)
44 /* System-specific feature definitions and include files. */
49 # define INCL_DOSPROCESS
53 /* Some standard library routines. */
57 #include "rlprivate.h"
61 /* Forward declarations. */
62 static int rl_change_case PARAMS((int, int));
63 static int _rl_char_search PARAMS((int, int, int));
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 *));
70 /* **************************************************************** */
72 /* Insert and Delete */
74 /* **************************************************************** */
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. */
80 rl_insert_text (string)
85 l = (string && *string) ? strlen (string) : 0;
89 if (rl_end + l >= rl_line_buffer_len)
90 rl_extend_line_buffer (rl_end + l);
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);
96 /* Remember how to undo this if we aren't undoing something. */
97 if (_rl_doing_an_undo == 0)
99 /* If possible and desirable, concatenate the undos. */
102 (rl_undo_list->what == UNDO_INSERT) &&
103 (rl_undo_list->end == rl_point) &&
104 (rl_undo_list->end - rl_undo_list->start < 20))
107 rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
111 rl_line_buffer[rl_end] = '\0';
115 /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
116 Returns the number of characters deleted. */
118 rl_delete_text (from, to)
122 register int diff, i;
124 /* Fix it if the caller is confused. */
138 text = rl_copy_text (from, to);
140 /* Some versions of strncpy() can't handle overlapping arguments. */
142 for (i = from; i < rl_end - diff; i++)
143 rl_line_buffer[i] = rl_line_buffer[i + diff];
145 /* Remember how to undo this delete. */
146 if (_rl_doing_an_undo == 0)
147 rl_add_undo (UNDO_DELETE, from, to, text);
152 rl_line_buffer[rl_end] = '\0';
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
160 #define _RL_FIX_POINT(x) \
169 _rl_fix_point (fix_mark_too)
172 _RL_FIX_POINT (rl_point);
174 _RL_FIX_POINT (rl_mark);
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); */
182 _rl_replace_text (text, start, end)
188 rl_begin_undo_group ();
189 rl_delete_text (start, end + 1);
191 n = rl_insert_text (text);
192 rl_end_undo_group ();
197 /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
198 non-zero, we free the current undo list. */
200 rl_replace_line (text, clear_undo)
207 if (len >= rl_line_buffer_len)
208 rl_extend_line_buffer (len);
209 strcpy (rl_line_buffer, text);
213 rl_free_undo_list ();
218 /* **************************************************************** */
220 /* Readline character functions */
222 /* **************************************************************** */
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. */
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.
232 rl_point is the place in the string where the cursor is. Sometimes
233 this is the same as rl_end.
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.
240 /* **************************************************************** */
242 /* Movement Commands */
244 /* **************************************************************** */
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. */
251 /* Move forward COUNT bytes. */
253 rl_forward_byte (count, key)
257 return (rl_backward_byte (-count, key));
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;
283 #if defined (HANDLE_MULTIBYTE)
284 /* Move forward COUNT characters. */
286 rl_forward_char (count, key)
291 if (MB_CUR_MAX == 1 || rl_byte_oriented)
292 return (rl_forward_byte (count, key));
295 return (rl_backward_char (-count, key));
299 point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
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);
306 if (rl_point == point)
317 #else /* !HANDLE_MULTIBYTE */
319 rl_forward_char (count, key)
322 return (rl_forward_byte (count, key));
324 #endif /* !HANDLE_MULTIBYTE */
326 /* Backwards compatibility. */
328 rl_forward (count, key)
331 return (rl_forward_char (count, key));
334 /* Move backward COUNT bytes. */
336 rl_backward_byte (count, key)
340 return (rl_forward_byte (-count, key));
344 if (rl_point < count)
359 #if defined (HANDLE_MULTIBYTE)
360 /* Move backward COUNT characters. */
362 rl_backward_char (count, key)
367 if (MB_CUR_MAX == 1 || rl_byte_oriented)
368 return (rl_backward_byte (count, key));
371 return (rl_forward_char (-count, key));
377 while (count > 0 && point > 0)
379 point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
395 rl_backward_char (count, key)
398 return (rl_backward_byte (count, key));
402 /* Backwards compatibility. */
404 rl_backward (count, key)
407 return (rl_backward_char (count, key));
410 /* Move to the beginning of the line. */
412 rl_beg_of_line (count, key)
419 /* Move to the end of the line. */
421 rl_end_of_line (count, key)
428 /* Move forward a word. We do what Emacs does. Handles multibyte chars. */
430 rl_forward_word (count, key)
436 return (rl_backward_word (-count, key));
440 if (rl_point == rl_end)
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);
447 if (_rl_walphabetic (c) == 0)
449 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
450 while (rl_point < rl_end)
452 c = _rl_char_value (rl_line_buffer, rl_point);
453 if (_rl_walphabetic (c))
455 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
459 if (rl_point == rl_end)
462 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
463 while (rl_point < rl_end)
465 c = _rl_char_value (rl_line_buffer, rl_point);
466 if (_rl_walphabetic (c) == 0)
468 rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
477 /* Move backward a word. We do what Emacs does. Handles multibyte chars. */
479 rl_backward_word (count, key)
485 return (rl_forward_word (-count, key));
492 /* Like rl_forward_word (), except that we look at the characters
493 just before point. */
495 p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
496 c = _rl_char_value (rl_line_buffer, p);
498 if (_rl_walphabetic (c) == 0)
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))
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)
527 /* Clear the current line. Numeric argument to C-l does this. */
529 rl_refresh_line (ignore1, ignore2)
530 int ignore1, ignore2;
534 curr_line = _rl_current_display_line ();
536 _rl_move_vert (curr_line);
537 _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
539 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
541 rl_forced_update_display ();
542 rl_display_fixed = 1;
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
551 rl_clear_screen (count, key)
556 rl_refresh_line (count, key);
560 _rl_clear_screen (); /* calls termcap function to clear screen */
561 rl_forced_update_display ();
562 rl_display_fixed = 1;
568 rl_arrow_keys (count, c)
573 RL_SETSTATE(RL_STATE_MOREINPUT);
575 RL_UNSETSTATE(RL_STATE_MOREINPUT);
577 switch (_rl_to_upper (ch))
580 rl_get_previous_history (count, ch);
584 rl_get_next_history (count, ch);
588 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
589 rl_forward_char (count, ch);
591 rl_forward_byte (count, ch);
595 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
596 rl_backward_char (count, ch);
598 rl_backward_byte (count, ch);
608 /* **************************************************************** */
612 /* **************************************************************** */
614 #ifdef HANDLE_MULTIBYTE
615 static char pending_bytes[MB_LEN_MAX];
616 static int pending_bytes_length = 0;
617 static mbstate_t ps = {0};
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. */
624 _rl_insert_char (count, c)
629 #ifdef HANDLE_MULTIBYTE
631 char incoming[MB_LEN_MAX + 1];
632 int incoming_length = 0;
634 static int stored_count = 0;
640 #if defined (HANDLE_MULTIBYTE)
641 if (MB_CUR_MAX == 1 || rl_byte_oriented)
652 if (stored_count <= 0)
653 stored_count = count;
655 count = stored_count;
658 pending_bytes[pending_bytes_length++] = c;
659 ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
661 if (ret == (size_t)-2)
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. */
669 else if (ret == (size_t)-1)
671 /* Invalid byte sequence for the current locale. Treat first byte
672 as a single character. */
673 incoming[0] = pending_bytes[0];
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));
682 else if (ret == (size_t)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));
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;
700 #endif /* HANDLE_MULTIBYTE */
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)
706 #if defined (HANDLE_MULTIBYTE)
707 string_size = count * incoming_length;
708 string = (char *)xmalloc (1 + string_size);
711 while (i < string_size)
713 strncpy (string + i, incoming, incoming_length);
714 i += incoming_length;
718 #else /* !HANDLE_MULTIBYTE */
719 string = (char *)xmalloc (1 + count);
721 for (i = 0; i < count; i++)
723 #endif /* !HANDLE_MULTIBYTE */
726 rl_insert_text (string);
735 #if defined (HANDLE_MULTIBYTE)
736 string_size = incoming_length * 1024;
737 string = (char *)xmalloc (1 + string_size);
740 while (i < string_size)
742 strncpy (string + i, incoming, incoming_length);
743 i += incoming_length;
748 decreaser = (count > 1024) ? 1024 : count;
749 string[decreaser*incoming_length] = '\0';
750 rl_insert_text (string);
757 #else /* !HANDLE_MULTIBYTE */
760 for (i = 0; i < 1024; i++)
765 decreaser = (count > 1024 ? 1024 : count);
766 str[decreaser] = '\0';
767 rl_insert_text (str);
770 #endif /* !HANDLE_MULTIBYTE */
775 if (MB_CUR_MAX == 1 || rl_byte_oriented)
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
781 if (_rl_any_typein ())
782 _rl_insert_typein (c);
785 /* Inserting a single character. */
790 rl_insert_text (str);
793 #if defined (HANDLE_MULTIBYTE)
796 rl_insert_text (incoming);
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. */
808 _rl_overwrite_char (count, c)
812 #if defined (HANDLE_MULTIBYTE)
813 char mbkey[MB_LEN_MAX];
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);
821 rl_begin_undo_group ();
823 for (i = 0; i < count; i++)
825 #if defined (HANDLE_MULTIBYTE)
826 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
827 rl_insert_text (mbkey);
830 _rl_insert_char (1, c);
832 if (rl_point < rl_end)
836 rl_end_undo_group ();
845 return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
846 : _rl_overwrite_char (count, c));
849 /* Insert the next typed character verbatim. */
851 _rl_insert_next (count)
856 RL_SETSTATE(RL_STATE_MOREINPUT);
858 RL_UNSETSTATE(RL_STATE_MOREINPUT);
860 #if defined (HANDLE_SIGNALS)
861 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
862 _rl_restore_tty_signals ();
865 return (_rl_insert_char (count, c));
868 #if defined (READLINE_CALLBACKS)
870 _rl_insert_next_callback (data)
871 _rl_callback_generic_arg *data;
877 /* Deregister function, let rl_callback_read_char deallocate data */
878 _rl_callback_func = 0;
879 _rl_want_redisplay = 1;
881 return _rl_insert_next (count);
886 rl_quoted_insert (count, key)
889 /* Let's see...should the callback interface futz with signal handling? */
890 #if defined (HANDLE_SIGNALS)
891 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
892 _rl_disable_tty_signals ();
895 #if defined (READLINE_CALLBACKS)
896 if (RL_ISSTATE (RL_STATE_CALLBACK))
898 _rl_callback_data = _rl_callback_data_alloc (count);
899 _rl_callback_func = _rl_insert_next_callback;
904 return _rl_insert_next (count);
907 /* Insert a tab character. */
909 rl_tab_insert (count, key)
912 return (_rl_insert_char (count, '\t'));
915 /* What to do when a NEWLINE is pressed. We accept the whole line.
916 KEY is the key that invoked this command. I guess it could have
917 meaning in the future. */
919 rl_newline (count, key)
924 if (_rl_history_preserve_point)
925 _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
927 RL_SETSTATE(RL_STATE_DONE);
929 #if defined (VI_MODE)
930 if (rl_editing_mode == vi_mode)
932 _rl_vi_done_inserting ();
933 if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
934 _rl_vi_reset_last ();
938 /* If we've been asked to erase empty lines, suppress the final update,
939 since _rl_update_final calls rl_crlf(). */
940 if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
943 if (readline_echoing_p)
948 /* What to do for some uppercase characters, like meta characters,
949 and some characters appearing in emacs_ctlx_keymap. This function
950 is just a stub, you bind keys to it and the code in _rl_dispatch ()
953 rl_do_lowercase_version (ignore1, ignore2)
954 int ignore1, ignore2;
959 /* This is different from what vi does, so the code's not shared. Emacs
960 rubout in overwrite mode has one oddity: it replaces a control
961 character that's displayed as two characters (^X) with two spaces. */
963 _rl_overwrite_rubout (count, key)
977 /* L == number of spaces to insert */
978 for (i = l = 0; i < count; i++)
980 rl_backward_char (1, key);
981 l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
984 rl_begin_undo_group ();
986 if (count > 1 || rl_explicit_arg)
987 rl_kill_text (opoint, rl_point);
989 rl_delete_text (opoint, rl_point);
991 /* Emacs puts point at the beginning of the sequence of spaces. */
992 if (rl_point < rl_end)
995 _rl_insert_char (l, ' ');
999 rl_end_undo_group ();
1004 /* Rubout the character behind point. */
1006 rl_rubout (count, key)
1010 return (rl_delete (-count, key));
1018 if (rl_insert_mode == RL_IM_OVERWRITE)
1019 return (_rl_overwrite_rubout (count, key));
1021 return (_rl_rubout_char (count, key));
1025 _rl_rubout_char (count, key)
1031 /* Duplicated code because this is called from other parts of the library. */
1033 return (rl_delete (-count, key));
1041 orig_point = rl_point;
1042 if (count > 1 || rl_explicit_arg)
1044 rl_backward_char (count, key);
1045 rl_kill_text (orig_point, rl_point);
1047 else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1049 c = rl_line_buffer[--rl_point];
1050 rl_delete_text (rl_point, orig_point);
1051 /* The erase-at-end-of-line hack is of questionable merit now. */
1052 if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
1055 l = rl_character_len (c, rl_point);
1056 _rl_erase_at_end_of_line (l);
1061 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1062 rl_delete_text (rl_point, orig_point);
1068 /* Delete the character under the cursor. Given a numeric argument,
1069 kill that many characters instead. */
1071 rl_delete (count, key)
1077 return (_rl_rubout_char (-count, key));
1079 if (rl_point == rl_end)
1085 if (count > 1 || rl_explicit_arg)
1087 int orig_point = rl_point;
1088 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1089 rl_forward_char (count, key);
1091 rl_forward_byte (count, key);
1093 r = rl_kill_text (orig_point, rl_point);
1094 rl_point = orig_point;
1101 new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1102 return (rl_delete_text (rl_point, new_point));
1106 /* Delete the character under the cursor, unless the insertion
1107 point is at the end of the line, in which case the character
1108 behind the cursor is deleted. COUNT is obeyed and may be used
1109 to delete forward or backward that many characters. */
1111 rl_rubout_or_delete (count, key)
1114 if (rl_end != 0 && rl_point == rl_end)
1115 return (_rl_rubout_char (count, key));
1117 return (rl_delete (count, key));
1120 /* Delete all spaces and tabs around point. */
1122 rl_delete_horizontal_space (count, ignore)
1125 int start = rl_point;
1127 while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1132 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1135 if (start != rl_point)
1137 rl_delete_text (start, rl_point);
1147 /* Like the tcsh editing function delete-char-or-list. The eof character
1148 is caught before this is invoked, so this really does the same thing as
1149 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1151 rl_delete_or_show_completions (count, key)
1154 if (rl_end != 0 && rl_point == rl_end)
1155 return (rl_possible_completions (count, key));
1157 return (rl_delete (count, key));
1160 #ifndef RL_COMMENT_BEGIN_DEFAULT
1161 #define RL_COMMENT_BEGIN_DEFAULT "#"
1164 /* Turn the current line into a comment in shell history.
1165 A K*rn shell style function. */
1167 rl_insert_comment (count, key)
1170 char *rl_comment_text;
1173 rl_beg_of_line (1, key);
1174 rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1176 if (rl_explicit_arg == 0)
1177 rl_insert_text (rl_comment_text);
1180 rl_comment_len = strlen (rl_comment_text);
1181 if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1182 rl_delete_text (rl_point, rl_point + rl_comment_len);
1184 rl_insert_text (rl_comment_text);
1187 (*rl_redisplay_function) ();
1188 rl_newline (1, '\n');
1193 /* **************************************************************** */
1197 /* **************************************************************** */
1199 /* The three kinds of things that we know how to do. */
1204 /* Uppercase the word at point. */
1206 rl_upcase_word (count, key)
1209 return (rl_change_case (count, UpCase));
1212 /* Lowercase the word at point. */
1214 rl_downcase_word (count, key)
1217 return (rl_change_case (count, DownCase));
1220 /* Upcase the first letter, downcase the rest. */
1222 rl_capitalize_word (count, key)
1225 return (rl_change_case (count, CapCase));
1228 /* The meaty function.
1229 Change the case of COUNT words, performing OP on them.
1230 OP is one of UpCase, DownCase, or CapCase.
1231 If a negative argument is given, leave point where it started,
1232 otherwise, leave it where it moves to. */
1234 rl_change_case (count, op)
1237 int start, next, end;
1238 int inword, c, nc, nop;
1239 #if defined (HANDLE_MULTIBYTE)
1241 char mb[MB_LEN_MAX+1];
1247 rl_forward_word (count, 0);
1250 if (op != UpCase && op != DownCase && op != CapCase)
1259 #if defined (HANDLE_MULTIBYTE)
1260 memset (&ps, 0, sizeof (mbstate_t));
1263 /* We are going to modify some text, so let's prepare to undo it. */
1264 rl_modifying (start, end);
1269 c = _rl_char_value (rl_line_buffer, start);
1270 /* This assumes that the upper and lower case versions are the same width. */
1271 next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1273 if (_rl_walphabetic (c) == 0)
1282 nop = inword ? DownCase : UpCase;
1287 if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
1289 nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
1290 rl_line_buffer[start] = nc;
1292 #if defined (HANDLE_MULTIBYTE)
1295 mbrtowc (&wc, rl_line_buffer + start, end - start, &ps);
1296 nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1297 if (nwc != wc) /* just skip unchanged characters */
1299 mblen = wcrtomb (mb, nwc, &ps);
1302 /* Assume the same width */
1303 strncpy (rl_line_buffer + start, mb, mblen);
1315 /* **************************************************************** */
1319 /* **************************************************************** */
1321 /* Transpose the words at point. If point is at the end of the line,
1322 transpose the two words before point. */
1324 rl_transpose_words (count, key)
1327 char *word1, *word2;
1328 int w1_beg, w1_end, w2_beg, w2_end;
1329 int orig_point = rl_point;
1334 /* Find the two words. */
1335 rl_forward_word (count, key);
1337 rl_backward_word (1, key);
1339 rl_backward_word (count, key);
1341 rl_forward_word (1, key);
1344 /* Do some check to make sure that there really are two words. */
1345 if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1348 rl_point = orig_point;
1352 /* Get the text of the words. */
1353 word1 = rl_copy_text (w1_beg, w1_end);
1354 word2 = rl_copy_text (w2_beg, w2_end);
1356 /* We are about to do many insertions and deletions. Remember them
1357 as one operation. */
1358 rl_begin_undo_group ();
1360 /* Do the stuff at word2 first, so that we don't have to worry
1361 about word1 moving. */
1363 rl_delete_text (w2_beg, w2_end);
1364 rl_insert_text (word1);
1367 rl_delete_text (w1_beg, w1_end);
1368 rl_insert_text (word2);
1370 /* This is exactly correct since the text before this point has not
1371 changed in length. */
1374 /* I think that does it. */
1375 rl_end_undo_group ();
1382 /* Transpose the characters at point. If point is at the end of the line,
1383 then transpose the characters before point. */
1385 rl_transpose_chars (count, key)
1388 #if defined (HANDLE_MULTIBYTE)
1394 int char_length, prev_point;
1399 if (!rl_point || rl_end < 2)
1405 rl_begin_undo_group ();
1407 if (rl_point == rl_end)
1409 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1413 prev_point = rl_point;
1414 rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
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];
1423 dummy[0] = rl_line_buffer[rl_point];
1424 dummy[char_length = 1] = '\0';
1427 rl_delete_text (rl_point, rl_point + char_length);
1429 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1432 rl_insert_text (dummy);
1433 rl_end_undo_group ();
1435 #if defined (HANDLE_MULTIBYTE)
1442 /* **************************************************************** */
1444 /* Character Searching */
1446 /* **************************************************************** */
1449 #if defined (HANDLE_MULTIBYTE)
1450 _rl_char_search_internal (count, dir, smbchar, len)
1455 _rl_char_search_internal (count, dir, schar)
1456 int count, dir, schar;
1460 #if defined (HANDLE_MULTIBYTE)
1465 inc = (dir < 0) ? -1 : 1;
1468 if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
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);
1482 #if defined (HANDLE_MULTIBYTE)
1483 if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1485 if (rl_line_buffer[pos] == schar)
1490 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1493 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1497 #if defined (HANDLE_MULTIBYTE)
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);
1505 while ((dir < 0) ? pos-- : ++pos < rl_end);
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)
1517 _rl_char_search (count, fdir, bdir)
1518 int count, fdir, bdir;
1520 char mbchar[MB_LEN_MAX];
1523 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1526 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1528 return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1530 #else /* !HANDLE_MULTIBYTE */
1532 _rl_char_search (count, fdir, bdir)
1533 int count, fdir, bdir;
1537 RL_SETSTATE(RL_STATE_MOREINPUT);
1539 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1542 return (_rl_char_search_internal (-count, bdir, c));
1544 return (_rl_char_search_internal (count, fdir, c));
1546 #endif /* !HANDLE_MULTIBYTE */
1548 #if defined (READLINE_CALLBACKS)
1550 _rl_char_search_callback (data)
1551 _rl_callback_generic_arg *data;
1553 _rl_callback_func = 0;
1554 _rl_want_redisplay = 1;
1556 return (_rl_char_search (data->count, data->i1, data->i2));
1561 rl_char_search (count, key)
1564 #if defined (READLINE_CALLBACKS)
1565 if (RL_ISSTATE (RL_STATE_CALLBACK))
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;
1575 return (_rl_char_search (count, FFIND, BFIND));
1579 rl_backward_char_search (count, key)
1582 #if defined (READLINE_CALLBACKS)
1583 if (RL_ISSTATE (RL_STATE_CALLBACK))
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;
1593 return (_rl_char_search (count, BFIND, FFIND));
1596 /* **************************************************************** */
1598 /* The Mark and the Region. */
1600 /* **************************************************************** */
1602 /* Set the mark at POSITION. */
1604 _rl_set_mark_at_pos (position)
1607 if (position > rl_end)
1614 /* A bindable command to set the mark. */
1616 rl_set_mark (count, key)
1619 return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1622 /* Exchange the position of mark and point. */
1624 rl_exchange_point_and_mark (count, key)
1627 if (rl_mark > rl_end)
1636 SWAP (rl_point, rl_mark);