1 /* text.c -- text handling commands for readline. */
3 /* Copyright (C) 1987-2002 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 /* **************************************************************** */
67 /* Insert and Delete */
69 /* **************************************************************** */
71 /* Insert a string of text into the line at point. This is the only
72 way that you should do insertion. _rl_insert_char () calls this
73 function. Returns the number of characters inserted. */
75 rl_insert_text (string
)
80 l
= (string
&& *string
) ? strlen (string
) : 0;
84 if (rl_end
+ l
>= rl_line_buffer_len
)
85 rl_extend_line_buffer (rl_end
+ l
);
87 for (i
= rl_end
; i
>= rl_point
; i
--)
88 rl_line_buffer
[i
+ l
] = rl_line_buffer
[i
];
89 strncpy (rl_line_buffer
+ rl_point
, string
, l
);
91 /* Remember how to undo this if we aren't undoing something. */
92 if (_rl_doing_an_undo
== 0)
94 /* If possible and desirable, concatenate the undos. */
97 (rl_undo_list
->what
== UNDO_INSERT
) &&
98 (rl_undo_list
->end
== rl_point
) &&
99 (rl_undo_list
->end
- rl_undo_list
->start
< 20))
102 rl_add_undo (UNDO_INSERT
, rl_point
, rl_point
+ l
, (char *)NULL
);
106 rl_line_buffer
[rl_end
] = '\0';
110 /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
111 Returns the number of characters deleted. */
113 rl_delete_text (from
, to
)
117 register int diff
, i
;
119 /* Fix it if the caller is confused. */
133 text
= rl_copy_text (from
, to
);
135 /* Some versions of strncpy() can't handle overlapping arguments. */
137 for (i
= from
; i
< rl_end
- diff
; i
++)
138 rl_line_buffer
[i
] = rl_line_buffer
[i
+ diff
];
140 /* Remember how to undo this delete. */
141 if (_rl_doing_an_undo
== 0)
142 rl_add_undo (UNDO_DELETE
, from
, to
, text
);
147 rl_line_buffer
[rl_end
] = '\0';
151 /* Fix up point so that it is within the line boundaries after killing
152 text. If FIX_MARK_TOO is non-zero, the mark is forced within line
155 #define _RL_FIX_POINT(x) \
164 _rl_fix_point (fix_mark_too
)
167 _RL_FIX_POINT (rl_point
);
169 _RL_FIX_POINT (rl_mark
);
174 _rl_replace_text (text
, start
, end
)
180 rl_begin_undo_group ();
181 rl_delete_text (start
, end
+ 1);
183 n
= rl_insert_text (text
);
184 rl_end_undo_group ();
189 /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
190 non-zero, we free the current undo list. */
192 rl_replace_line (text
, clear_undo
)
199 if (len
>= rl_line_buffer_len
)
200 rl_extend_line_buffer (len
);
201 strcpy (rl_line_buffer
, text
);
205 rl_free_undo_list ();
210 /* **************************************************************** */
212 /* Readline character functions */
214 /* **************************************************************** */
216 /* This is not a gap editor, just a stupid line input routine. No hair
217 is involved in writing any of the functions, and none should be. */
221 rl_end is the place in the string that we would place '\0';
222 i.e., it is always safe to place '\0' there.
224 rl_point is the place in the string where the cursor is. Sometimes
225 this is the same as rl_end.
227 Any command that is called interactively receives two arguments.
228 The first is a count: the numeric arg pased to this command.
229 The second is the key which invoked this command.
232 /* **************************************************************** */
234 /* Movement Commands */
236 /* **************************************************************** */
238 /* Note that if you `optimize' the display for these functions, you cannot
239 use said functions in other functions which do not do optimizing display.
240 I.e., you will have to update the data base for rl_redisplay, and you
241 might as well let rl_redisplay do that job. */
243 /* Move forward COUNT bytes. */
245 rl_forward_byte (count
, key
)
249 return (rl_backward_byte (-count
, key
));
253 int end
= rl_point
+ count
;
254 #if defined (VI_MODE)
255 int lend
= rl_end
> 0 ? rl_end
- (rl_editing_mode
== vi_mode
) : rl_end
;
275 #if defined (HANDLE_MULTIBYTE)
276 /* Move forward COUNT characters. */
278 rl_forward_char (count
, key
)
283 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
284 return (rl_forward_byte (count
, key
));
287 return (rl_backward_char (-count
, key
));
291 point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
293 #if defined (VI_MODE)
294 if (rl_end
<= point
&& rl_editing_mode
== vi_mode
)
295 point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_end
, MB_FIND_NONZERO
);
298 if (rl_point
== point
)
309 #else /* !HANDLE_MULTIBYTE */
311 rl_forward_char (count
, key
)
314 return (rl_forward_byte (count
, key
));
316 #endif /* !HANDLE_MULTIBYTE */
318 /* Backwards compatibility. */
320 rl_forward (count
, key
)
323 return (rl_forward_char (count
, key
));
326 /* Move backward COUNT bytes. */
328 rl_backward_byte (count
, key
)
332 return (rl_forward_byte (-count
, key
));
336 if (rl_point
< count
)
351 #if defined (HANDLE_MULTIBYTE)
352 /* Move backward COUNT characters. */
354 rl_backward_char (count
, key
)
359 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
360 return (rl_backward_byte (count
, key
));
363 return (rl_forward_char (-count
, key
));
369 while (count
> 0 && point
> 0)
371 point
= _rl_find_prev_mbchar (rl_line_buffer
, point
, MB_FIND_NONZERO
);
387 rl_backward_char (count
, key
)
390 return (rl_backward_byte (count
, key
));
394 /* Backwards compatibility. */
396 rl_backward (count
, key
)
399 return (rl_backward_char (count
, key
));
402 /* Move to the beginning of the line. */
404 rl_beg_of_line (count
, key
)
411 /* Move to the end of the line. */
413 rl_end_of_line (count
, key
)
420 /* XXX - these might need changes for multibyte characters */
421 /* Move forward a word. We do what Emacs does. */
423 rl_forward_word (count
, key
)
429 return (rl_backward_word (-count
, key
));
433 if (rl_point
== rl_end
)
436 /* If we are not in a word, move forward until we are in one.
437 Then, move forward until we hit a non-alphabetic character. */
438 c
= rl_line_buffer
[rl_point
];
439 if (rl_alphabetic (c
) == 0)
441 while (++rl_point
< rl_end
)
443 c
= rl_line_buffer
[rl_point
];
444 if (rl_alphabetic (c
))
449 if (rl_point
== rl_end
)
452 while (++rl_point
< rl_end
)
454 c
= rl_line_buffer
[rl_point
];
455 if (rl_alphabetic (c
) == 0)
464 /* Move backward a word. We do what Emacs does. */
466 rl_backward_word (count
, key
)
472 return (rl_forward_word (-count
, key
));
479 /* Like rl_forward_word (), except that we look at the characters
480 just before point. */
482 c
= rl_line_buffer
[rl_point
- 1];
483 if (rl_alphabetic (c
) == 0)
487 c
= rl_line_buffer
[rl_point
- 1];
488 if (rl_alphabetic (c
))
495 c
= rl_line_buffer
[rl_point
- 1];
496 if (rl_alphabetic (c
) == 0)
508 /* Clear the current line. Numeric argument to C-l does this. */
510 rl_refresh_line (ignore1
, ignore2
)
511 int ignore1
, ignore2
;
515 curr_line
= _rl_current_display_line ();
517 _rl_move_vert (curr_line
);
518 _rl_move_cursor_relative (0, rl_line_buffer
); /* XXX is this right */
520 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
522 rl_forced_update_display ();
523 rl_display_fixed
= 1;
528 /* C-l typed to a line without quoting clears the screen, and then reprints
529 the prompt and the current input line. Given a numeric arg, redraw only
532 rl_clear_screen (count
, key
)
537 rl_refresh_line (count
, key
);
541 _rl_clear_screen (); /* calls termcap function to clear screen */
542 rl_forced_update_display ();
543 rl_display_fixed
= 1;
549 rl_arrow_keys (count
, c
)
554 RL_SETSTATE(RL_STATE_MOREINPUT
);
556 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
558 switch (_rl_to_upper (ch
))
561 rl_get_previous_history (count
, ch
);
565 rl_get_next_history (count
, ch
);
569 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
570 rl_forward_char (count
, ch
);
572 rl_forward_byte (count
, ch
);
576 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
577 rl_backward_char (count
, ch
);
579 rl_backward_byte (count
, ch
);
589 /* **************************************************************** */
593 /* **************************************************************** */
595 #ifdef HANDLE_MULTIBYTE
596 static char pending_bytes
[MB_LEN_MAX
];
597 static int pending_bytes_length
= 0;
598 static mbstate_t ps
= {0};
601 /* Insert the character C at the current location, moving point forward.
602 If C introduces a multibyte sequence, we read the whole sequence and
603 then insert the multibyte char into the line buffer. */
605 _rl_insert_char (count
, c
)
610 #ifdef HANDLE_MULTIBYTE
612 char incoming
[MB_LEN_MAX
+ 1];
613 int incoming_length
= 0;
615 static int stored_count
= 0;
621 #if defined (HANDLE_MULTIBYTE)
622 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
633 if (stored_count
<= 0)
634 stored_count
= count
;
636 count
= stored_count
;
639 pending_bytes
[pending_bytes_length
++] = c
;
640 ret
= mbrtowc (&wc
, pending_bytes
, pending_bytes_length
, &ps
);
642 if (ret
== (size_t)-2)
644 /* Bytes too short to compose character, try to wait for next byte.
645 Restore the state of the byte sequence, because in this case the
646 effect of mbstate is undefined. */
650 else if (ret
== (size_t)-1)
652 /* Invalid byte sequence for the current locale. Treat first byte
653 as a single character. */
654 incoming
[0] = pending_bytes
[0];
657 pending_bytes_length
--;
658 memmove (pending_bytes
, pending_bytes
+ 1, pending_bytes_length
);
659 /* Clear the state of the byte sequence, because in this case the
660 effect of mbstate is undefined. */
661 memset (&ps
, 0, sizeof (mbstate_t));
663 else if (ret
== (size_t)0)
667 pending_bytes_length
--;
668 /* Clear the state of the byte sequence, because in this case the
669 effect of mbstate is undefined. */
670 memset (&ps
, 0, sizeof (mbstate_t));
674 /* We successfully read a single multibyte character. */
675 memcpy (incoming
, pending_bytes
, pending_bytes_length
);
676 incoming
[pending_bytes_length
] = '\0';
677 incoming_length
= pending_bytes_length
;
678 pending_bytes_length
= 0;
681 #endif /* HANDLE_MULTIBYTE */
683 /* If we can optimize, then do it. But don't let people crash
684 readline because of extra large arguments. */
685 if (count
> 1 && count
<= 1024)
687 #if defined (HANDLE_MULTIBYTE)
688 string_size
= count
* incoming_length
;
689 string
= (char *)xmalloc (1 + string_size
);
692 while (i
< string_size
)
694 strncpy (string
+ i
, incoming
, incoming_length
);
695 i
+= incoming_length
;
699 #else /* !HANDLE_MULTIBYTE */
700 string
= (char *)xmalloc (1 + count
);
702 for (i
= 0; i
< count
; i
++)
704 #endif /* !HANDLE_MULTIBYTE */
707 rl_insert_text (string
);
716 #if defined (HANDLE_MULTIBYTE)
717 string_size
= incoming_length
* 1024;
718 string
= (char *)xmalloc (1 + string_size
);
721 while (i
< string_size
)
723 strncpy (string
+ i
, incoming
, incoming_length
);
724 i
+= incoming_length
;
729 decreaser
= (count
> 1024) ? 1024 : count
;
730 string
[decreaser
*incoming_length
] = '\0';
731 rl_insert_text (string
);
738 #else /* !HANDLE_MULTIBYTE */
741 for (i
= 0; i
< 1024; i
++)
746 decreaser
= (count
> 1024 ? 1024 : count
);
747 str
[decreaser
] = '\0';
748 rl_insert_text (str
);
751 #endif /* !HANDLE_MULTIBYTE */
756 #if defined (HANDLE_MULTIBYTE)
757 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
760 /* We are inserting a single character.
761 If there is pending input, then make a string of all of the
762 pending characters that are bound to rl_insert, and insert
764 if (_rl_any_typein ())
765 _rl_insert_typein (c
);
768 /* Inserting a single character. */
773 rl_insert_text (str
);
775 #if defined (HANDLE_MULTIBYTE)
779 rl_insert_text (incoming
);
787 /* Overwrite the character at point (or next COUNT characters) with C.
788 If C introduces a multibyte character sequence, read the entire sequence
789 before starting the overwrite loop. */
791 _rl_overwrite_char (count
, c
)
795 #if defined (HANDLE_MULTIBYTE)
796 char mbkey
[MB_LEN_MAX
];
799 /* Read an entire multibyte character sequence to insert COUNT times. */
800 if (count
> 0 && MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
801 k
= _rl_read_mbstring (c
, mbkey
, MB_LEN_MAX
);
804 for (i
= 0; i
< count
; i
++)
806 rl_begin_undo_group ();
808 if (rl_point
< rl_end
)
811 #if defined (HANDLE_MULTIBYTE)
812 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
813 rl_insert_text (mbkey
);
816 _rl_insert_char (1, c
);
818 rl_end_undo_group ();
828 return (rl_insert_mode
== RL_IM_INSERT
? _rl_insert_char (count
, c
)
829 : _rl_overwrite_char (count
, c
));
832 /* Insert the next typed character verbatim. */
834 rl_quoted_insert (count
, key
)
839 #if defined (HANDLE_SIGNALS)
840 _rl_disable_tty_signals ();
843 RL_SETSTATE(RL_STATE_MOREINPUT
);
845 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
847 #if defined (HANDLE_SIGNALS)
848 _rl_restore_tty_signals ();
851 return (_rl_insert_char (count
, c
));
854 /* Insert a tab character. */
856 rl_tab_insert (count
, key
)
859 return (_rl_insert_char (count
, '\t'));
862 /* What to do when a NEWLINE is pressed. We accept the whole line.
863 KEY is the key that invoked this command. I guess it could have
864 meaning in the future. */
866 rl_newline (count
, key
)
871 if (_rl_history_preserve_point
)
872 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
874 RL_SETSTATE(RL_STATE_DONE
);
876 #if defined (VI_MODE)
877 if (rl_editing_mode
== vi_mode
)
879 _rl_vi_done_inserting ();
880 _rl_vi_reset_last ();
884 /* If we've been asked to erase empty lines, suppress the final update,
885 since _rl_update_final calls rl_crlf(). */
886 if (rl_erase_empty_line
&& rl_point
== 0 && rl_end
== 0)
889 if (readline_echoing_p
)
894 /* What to do for some uppercase characters, like meta characters,
895 and some characters appearing in emacs_ctlx_keymap. This function
896 is just a stub, you bind keys to it and the code in _rl_dispatch ()
899 rl_do_lowercase_version (ignore1
, ignore2
)
900 int ignore1
, ignore2
;
905 /* This is different from what vi does, so the code's not shared. Emacs
906 rubout in overwrite mode has one oddity: it replaces a control
907 character that's displayed as two characters (^X) with two spaces. */
909 _rl_overwrite_rubout (count
, key
)
923 /* L == number of spaces to insert */
924 for (i
= l
= 0; i
< count
; i
++)
926 rl_backward_char (1, key
);
927 l
+= rl_character_len (rl_line_buffer
[rl_point
], rl_point
); /* not exactly right */
930 rl_begin_undo_group ();
932 if (count
> 1 || rl_explicit_arg
)
933 rl_kill_text (opoint
, rl_point
);
935 rl_delete_text (opoint
, rl_point
);
937 /* Emacs puts point at the beginning of the sequence of spaces. */
939 _rl_insert_char (l
, ' ');
942 rl_end_undo_group ();
947 /* Rubout the character behind point. */
949 rl_rubout (count
, key
)
953 return (rl_delete (-count
, key
));
961 if (rl_insert_mode
== RL_IM_OVERWRITE
)
962 return (_rl_overwrite_rubout (count
, key
));
964 return (_rl_rubout_char (count
, key
));
968 _rl_rubout_char (count
, key
)
974 /* Duplicated code because this is called from other parts of the library. */
976 return (rl_delete (-count
, key
));
984 if (count
> 1 || rl_explicit_arg
)
986 orig_point
= rl_point
;
987 #if defined (HANDLE_MULTIBYTE)
988 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
989 rl_backward_char (count
, key
);
992 rl_backward_byte (count
, key
);
993 rl_kill_text (orig_point
, rl_point
);
997 #if defined (HANDLE_MULTIBYTE)
998 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1001 c
= rl_line_buffer
[--rl_point
];
1002 rl_delete_text (rl_point
, rl_point
+ 1);
1003 #if defined (HANDLE_MULTIBYTE)
1009 orig_point
= rl_point
;
1010 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1011 c
= rl_line_buffer
[rl_point
];
1012 rl_delete_text (rl_point
, orig_point
);
1014 #endif /* HANDLE_MULTIBYTE */
1016 /* I don't think that the hack for end of line is needed for
1018 #if defined (HANDLE_MULTIBYTE)
1019 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1021 if (rl_point
== rl_end
&& ISPRINT (c
) && _rl_last_c_pos
)
1024 l
= rl_character_len (c
, rl_point
);
1025 _rl_erase_at_end_of_line (l
);
1032 /* Delete the character under the cursor. Given a numeric argument,
1033 kill that many characters instead. */
1035 rl_delete (count
, key
)
1041 return (_rl_rubout_char (-count
, key
));
1043 if (rl_point
== rl_end
)
1049 if (count
> 1 || rl_explicit_arg
)
1051 int orig_point
= rl_point
;
1052 #if defined (HANDLE_MULTIBYTE)
1053 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1054 rl_forward_char (count
, key
);
1057 rl_forward_byte (count
, key
);
1059 r
= rl_kill_text (orig_point
, rl_point
);
1060 rl_point
= orig_point
;
1066 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1067 new_point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
1069 new_point
= rl_point
+ 1;
1071 return (rl_delete_text (rl_point
, new_point
));
1075 /* Delete the character under the cursor, unless the insertion
1076 point is at the end of the line, in which case the character
1077 behind the cursor is deleted. COUNT is obeyed and may be used
1078 to delete forward or backward that many characters. */
1080 rl_rubout_or_delete (count
, key
)
1083 if (rl_end
!= 0 && rl_point
== rl_end
)
1084 return (_rl_rubout_char (count
, key
));
1086 return (rl_delete (count
, key
));
1089 /* Delete all spaces and tabs around point. */
1091 rl_delete_horizontal_space (count
, ignore
)
1094 int start
= rl_point
;
1096 while (rl_point
&& whitespace (rl_line_buffer
[rl_point
- 1]))
1101 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
1104 if (start
!= rl_point
)
1106 rl_delete_text (start
, rl_point
);
1112 /* Like the tcsh editing function delete-char-or-list. The eof character
1113 is caught before this is invoked, so this really does the same thing as
1114 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1116 rl_delete_or_show_completions (count
, key
)
1119 if (rl_end
!= 0 && rl_point
== rl_end
)
1120 return (rl_possible_completions (count
, key
));
1122 return (rl_delete (count
, key
));
1125 #ifndef RL_COMMENT_BEGIN_DEFAULT
1126 #define RL_COMMENT_BEGIN_DEFAULT "#"
1129 /* Turn the current line into a comment in shell history.
1130 A K*rn shell style function. */
1132 rl_insert_comment (count
, key
)
1135 char *rl_comment_text
;
1138 rl_beg_of_line (1, key
);
1139 rl_comment_text
= _rl_comment_begin
? _rl_comment_begin
: RL_COMMENT_BEGIN_DEFAULT
;
1141 if (rl_explicit_arg
== 0)
1142 rl_insert_text (rl_comment_text
);
1145 rl_comment_len
= strlen (rl_comment_text
);
1146 if (STREQN (rl_comment_text
, rl_line_buffer
, rl_comment_len
))
1147 rl_delete_text (rl_point
, rl_point
+ rl_comment_len
);
1149 rl_insert_text (rl_comment_text
);
1152 (*rl_redisplay_function
) ();
1153 rl_newline (1, '\n');
1158 /* **************************************************************** */
1162 /* **************************************************************** */
1164 /* The three kinds of things that we know how to do. */
1169 /* Uppercase the word at point. */
1171 rl_upcase_word (count
, key
)
1174 return (rl_change_case (count
, UpCase
));
1177 /* Lowercase the word at point. */
1179 rl_downcase_word (count
, key
)
1182 return (rl_change_case (count
, DownCase
));
1185 /* Upcase the first letter, downcase the rest. */
1187 rl_capitalize_word (count
, key
)
1190 return (rl_change_case (count
, CapCase
));
1193 /* The meaty function.
1194 Change the case of COUNT words, performing OP on them.
1195 OP is one of UpCase, DownCase, or CapCase.
1196 If a negative argument is given, leave point where it started,
1197 otherwise, leave it where it moves to. */
1199 rl_change_case (count
, op
)
1202 register int start
, end
;
1206 rl_forward_word (count
, 0);
1212 /* We are going to modify some text, so let's prepare to undo it. */
1213 rl_modifying (start
, end
);
1215 for (inword
= 0; start
< end
; start
++)
1217 c
= rl_line_buffer
[start
];
1221 rl_line_buffer
[start
] = _rl_to_upper (c
);
1225 rl_line_buffer
[start
] = _rl_to_lower (c
);
1229 rl_line_buffer
[start
] = (inword
== 0) ? _rl_to_upper (c
) : _rl_to_lower (c
);
1230 inword
= rl_alphabetic (rl_line_buffer
[start
]);
1242 /* **************************************************************** */
1246 /* **************************************************************** */
1248 /* Transpose the words at point. If point is at the end of the line,
1249 transpose the two words before point. */
1251 rl_transpose_words (count
, key
)
1254 char *word1
, *word2
;
1255 int w1_beg
, w1_end
, w2_beg
, w2_end
;
1256 int orig_point
= rl_point
;
1261 /* Find the two words. */
1262 rl_forward_word (count
, key
);
1264 rl_backward_word (1, key
);
1266 rl_backward_word (count
, key
);
1268 rl_forward_word (1, key
);
1271 /* Do some check to make sure that there really are two words. */
1272 if ((w1_beg
== w2_beg
) || (w2_beg
< w1_end
))
1275 rl_point
= orig_point
;
1279 /* Get the text of the words. */
1280 word1
= rl_copy_text (w1_beg
, w1_end
);
1281 word2
= rl_copy_text (w2_beg
, w2_end
);
1283 /* We are about to do many insertions and deletions. Remember them
1284 as one operation. */
1285 rl_begin_undo_group ();
1287 /* Do the stuff at word2 first, so that we don't have to worry
1288 about word1 moving. */
1290 rl_delete_text (w2_beg
, w2_end
);
1291 rl_insert_text (word1
);
1294 rl_delete_text (w1_beg
, w1_end
);
1295 rl_insert_text (word2
);
1297 /* This is exactly correct since the text before this point has not
1298 changed in length. */
1301 /* I think that does it. */
1302 rl_end_undo_group ();
1309 /* Transpose the characters at point. If point is at the end of the line,
1310 then transpose the characters before point. */
1312 rl_transpose_chars (count
, key
)
1315 #if defined (HANDLE_MULTIBYTE)
1326 if (!rl_point
|| rl_end
< 2)
1332 rl_begin_undo_group ();
1334 if (rl_point
== rl_end
)
1336 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1337 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1343 #if defined (HANDLE_MULTIBYTE)
1344 prev_point
= rl_point
;
1345 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1346 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1351 #if defined (HANDLE_MULTIBYTE)
1352 char_length
= prev_point
- rl_point
;
1353 dummy
= (char *)xmalloc (char_length
+ 1);
1354 for (i
= 0; i
< char_length
; i
++)
1355 dummy
[i
] = rl_line_buffer
[rl_point
+ i
];
1358 dummy
[0] = rl_line_buffer
[rl_point
];
1359 dummy
[char_length
= 1] = '\0';
1362 rl_delete_text (rl_point
, rl_point
+ char_length
);
1364 rl_point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
1367 rl_insert_text (dummy
);
1368 rl_end_undo_group ();
1370 #if defined (HANDLE_MULTIBYTE)
1377 /* **************************************************************** */
1379 /* Character Searching */
1381 /* **************************************************************** */
1384 #if defined (HANDLE_MULTIBYTE)
1385 _rl_char_search_internal (count
, dir
, smbchar
, len
)
1390 _rl_char_search_internal (count
, dir
, schar
)
1391 int count
, dir
, schar
;
1395 #if defined (HANDLE_MULTIBYTE)
1400 inc
= (dir
< 0) ? -1 : 1;
1403 if ((dir
< 0 && pos
<= 0) || (dir
> 0 && pos
>= rl_end
))
1409 #if defined (HANDLE_MULTIBYTE)
1410 pos
= (inc
> 0) ? _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)
1411 : _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
);
1417 #if defined (HANDLE_MULTIBYTE)
1418 if (_rl_is_mbchar_matched (rl_line_buffer
, pos
, rl_end
, smbchar
, len
))
1420 if (rl_line_buffer
[pos
] == schar
)
1425 rl_point
= (dir
== BTO
) ? _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)
1428 rl_point
= (dir
== FTO
) ? _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
)
1432 #if defined (HANDLE_MULTIBYTE)
1436 #if defined (HANDLE_MULTIBYTE)
1437 while ((dir
< 0) ? (pos
= _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
)) != prepos
1438 : (pos
= _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)) != prepos
);
1440 while ((dir
< 0) ? pos
-- : ++pos
< rl_end
);
1446 /* Search COUNT times for a character read from the current input stream.
1447 FDIR is the direction to search if COUNT is non-negative; otherwise
1448 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1449 that there are two separate versions of this function. */
1450 #if defined (HANDLE_MULTIBYTE)
1452 _rl_char_search (count
, fdir
, bdir
)
1453 int count
, fdir
, bdir
;
1455 char mbchar
[MB_LEN_MAX
];
1458 mb_len
= _rl_read_mbchar (mbchar
, MB_LEN_MAX
);
1461 return (_rl_char_search_internal (-count
, bdir
, mbchar
, mb_len
));
1463 return (_rl_char_search_internal (count
, fdir
, mbchar
, mb_len
));
1465 #else /* !HANDLE_MULTIBYTE */
1467 _rl_char_search (count
, fdir
, bdir
)
1468 int count
, fdir
, bdir
;
1472 RL_SETSTATE(RL_STATE_MOREINPUT
);
1474 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1477 return (_rl_char_search_internal (-count
, bdir
, c
));
1479 return (_rl_char_search_internal (count
, fdir
, c
));
1481 #endif /* !HANDLE_MULTIBYTE */
1484 rl_char_search (count
, key
)
1487 return (_rl_char_search (count
, FFIND
, BFIND
));
1491 rl_backward_char_search (count
, key
)
1494 return (_rl_char_search (count
, BFIND
, FFIND
));
1497 /* **************************************************************** */
1499 /* The Mark and the Region. */
1501 /* **************************************************************** */
1503 /* Set the mark at POSITION. */
1505 _rl_set_mark_at_pos (position
)
1508 if (position
> rl_end
)
1515 /* A bindable command to set the mark. */
1517 rl_set_mark (count
, key
)
1520 return (_rl_set_mark_at_pos (rl_explicit_arg
? count
: rl_point
));
1523 /* Exchange the position of mark and point. */
1525 rl_exchange_point_and_mark (count
, key
)
1528 if (rl_mark
> rl_end
)
1537 SWAP (rl_point
, rl_mark
);