1 /* text.c -- text handling commands for readline. */
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
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
- (VI_COMMAND_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 if (rl_point
== rl_end
&& EMACS_MODE())
305 point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
307 #if defined (VI_MODE)
308 if (point
>= rl_end
&& VI_COMMAND_MODE())
309 point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_end
, MB_FIND_NONZERO
);
312 if (rl_point
== point
)
323 #else /* !HANDLE_MULTIBYTE */
325 rl_forward_char (count
, key
)
328 return (rl_forward_byte (count
, key
));
330 #endif /* !HANDLE_MULTIBYTE */
332 /* Backwards compatibility. */
334 rl_forward (count
, key
)
337 return (rl_forward_char (count
, key
));
340 /* Move backward COUNT bytes. */
342 rl_backward_byte (count
, key
)
346 return (rl_forward_byte (-count
, key
));
350 if (rl_point
< count
)
365 #if defined (HANDLE_MULTIBYTE)
366 /* Move backward COUNT characters. */
368 rl_backward_char (count
, key
)
373 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
374 return (rl_backward_byte (count
, key
));
377 return (rl_forward_char (-count
, key
));
383 while (count
> 0 && point
> 0)
385 point
= _rl_find_prev_mbchar (rl_line_buffer
, point
, MB_FIND_NONZERO
);
401 rl_backward_char (count
, key
)
404 return (rl_backward_byte (count
, key
));
408 /* Backwards compatibility. */
410 rl_backward (count
, key
)
413 return (rl_backward_char (count
, key
));
416 /* Move to the beginning of the line. */
418 rl_beg_of_line (count
, key
)
425 /* Move to the end of the line. */
427 rl_end_of_line (count
, key
)
434 /* Move forward a word. We do what Emacs does. Handles multibyte chars. */
436 rl_forward_word (count
, key
)
442 return (rl_backward_word (-count
, key
));
446 if (rl_point
== rl_end
)
449 /* If we are not in a word, move forward until we are in one.
450 Then, move forward until we hit a non-alphabetic character. */
451 c
= _rl_char_value (rl_line_buffer
, rl_point
);
453 if (_rl_walphabetic (c
) == 0)
455 rl_point
= MB_NEXTCHAR (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
456 while (rl_point
< rl_end
)
458 c
= _rl_char_value (rl_line_buffer
, rl_point
);
459 if (_rl_walphabetic (c
))
461 rl_point
= MB_NEXTCHAR (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
465 if (rl_point
== rl_end
)
468 rl_point
= MB_NEXTCHAR (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
469 while (rl_point
< rl_end
)
471 c
= _rl_char_value (rl_line_buffer
, rl_point
);
472 if (_rl_walphabetic (c
) == 0)
474 rl_point
= MB_NEXTCHAR (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
483 /* Move backward a word. We do what Emacs does. Handles multibyte chars. */
485 rl_backward_word (count
, key
)
491 return (rl_forward_word (-count
, key
));
498 /* Like rl_forward_word (), except that we look at the characters
499 just before point. */
501 p
= MB_PREVCHAR (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
502 c
= _rl_char_value (rl_line_buffer
, p
);
504 if (_rl_walphabetic (c
) == 0)
509 p
= MB_PREVCHAR (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
510 c
= _rl_char_value (rl_line_buffer
, p
);
511 if (_rl_walphabetic (c
))
519 p
= MB_PREVCHAR (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
520 c
= _rl_char_value (rl_line_buffer
, p
);
521 if (_rl_walphabetic (c
) == 0)
533 /* Clear the current line. Numeric argument to C-l does this. */
535 rl_refresh_line (ignore1
, ignore2
)
536 int ignore1
, ignore2
;
540 curr_line
= _rl_current_display_line ();
542 _rl_move_vert (curr_line
);
543 _rl_move_cursor_relative (0, rl_line_buffer
); /* XXX is this right */
545 _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
547 rl_forced_update_display ();
548 rl_display_fixed
= 1;
553 /* C-l typed to a line without quoting clears the screen, and then reprints
554 the prompt and the current input line. Given a numeric arg, redraw only
557 rl_clear_screen (count
, key
)
562 rl_refresh_line (count
, key
);
566 _rl_clear_screen (); /* calls termcap function to clear screen */
567 rl_forced_update_display ();
568 rl_display_fixed
= 1;
574 rl_arrow_keys (count
, c
)
579 RL_SETSTATE(RL_STATE_MOREINPUT
);
581 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
583 switch (_rl_to_upper (ch
))
586 rl_get_previous_history (count
, ch
);
590 rl_get_next_history (count
, ch
);
594 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
595 rl_forward_char (count
, ch
);
597 rl_forward_byte (count
, ch
);
601 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
602 rl_backward_char (count
, ch
);
604 rl_backward_byte (count
, ch
);
614 /* **************************************************************** */
618 /* **************************************************************** */
620 #ifdef HANDLE_MULTIBYTE
621 static char pending_bytes
[MB_LEN_MAX
];
622 static int pending_bytes_length
= 0;
623 static mbstate_t ps
= {0};
626 /* Insert the character C at the current location, moving point forward.
627 If C introduces a multibyte sequence, we read the whole sequence and
628 then insert the multibyte char into the line buffer. */
630 _rl_insert_char (count
, c
)
635 #ifdef HANDLE_MULTIBYTE
637 char incoming
[MB_LEN_MAX
+ 1];
638 int incoming_length
= 0;
640 static int stored_count
= 0;
646 #if defined (HANDLE_MULTIBYTE)
647 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
658 if (stored_count
<= 0)
659 stored_count
= count
;
661 count
= stored_count
;
664 pending_bytes
[pending_bytes_length
++] = c
;
665 ret
= mbrtowc (&wc
, pending_bytes
, pending_bytes_length
, &ps
);
667 if (ret
== (size_t)-2)
669 /* Bytes too short to compose character, try to wait for next byte.
670 Restore the state of the byte sequence, because in this case the
671 effect of mbstate is undefined. */
675 else if (ret
== (size_t)-1)
677 /* Invalid byte sequence for the current locale. Treat first byte
678 as a single character. */
679 incoming
[0] = pending_bytes
[0];
682 pending_bytes_length
--;
683 memmove (pending_bytes
, pending_bytes
+ 1, pending_bytes_length
);
684 /* Clear the state of the byte sequence, because in this case the
685 effect of mbstate is undefined. */
686 memset (&ps
, 0, sizeof (mbstate_t));
688 else if (ret
== (size_t)0)
692 pending_bytes_length
--;
693 /* Clear the state of the byte sequence, because in this case the
694 effect of mbstate is undefined. */
695 memset (&ps
, 0, sizeof (mbstate_t));
699 /* We successfully read a single multibyte character. */
700 memcpy (incoming
, pending_bytes
, pending_bytes_length
);
701 incoming
[pending_bytes_length
] = '\0';
702 incoming_length
= pending_bytes_length
;
703 pending_bytes_length
= 0;
706 #endif /* HANDLE_MULTIBYTE */
708 /* If we can optimize, then do it. But don't let people crash
709 readline because of extra large arguments. */
710 if (count
> 1 && count
<= 1024)
712 #if defined (HANDLE_MULTIBYTE)
713 string_size
= count
* incoming_length
;
714 string
= (char *)xmalloc (1 + string_size
);
717 while (i
< string_size
)
719 strncpy (string
+ i
, incoming
, incoming_length
);
720 i
+= incoming_length
;
724 #else /* !HANDLE_MULTIBYTE */
725 string
= (char *)xmalloc (1 + count
);
727 for (i
= 0; i
< count
; i
++)
729 #endif /* !HANDLE_MULTIBYTE */
732 rl_insert_text (string
);
741 #if defined (HANDLE_MULTIBYTE)
742 string_size
= incoming_length
* 1024;
743 string
= (char *)xmalloc (1 + string_size
);
746 while (i
< string_size
)
748 strncpy (string
+ i
, incoming
, incoming_length
);
749 i
+= incoming_length
;
754 decreaser
= (count
> 1024) ? 1024 : count
;
755 string
[decreaser
*incoming_length
] = '\0';
756 rl_insert_text (string
);
763 #else /* !HANDLE_MULTIBYTE */
766 for (i
= 0; i
< 1024; i
++)
771 decreaser
= (count
> 1024 ? 1024 : count
);
772 str
[decreaser
] = '\0';
773 rl_insert_text (str
);
776 #endif /* !HANDLE_MULTIBYTE */
781 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
783 /* We are inserting a single character.
784 If there is pending input, then make a string of all of the
785 pending characters that are bound to rl_insert, and insert
787 if (_rl_any_typein ())
788 _rl_insert_typein (c
);
791 /* Inserting a single character. */
796 rl_insert_text (str
);
799 #if defined (HANDLE_MULTIBYTE)
802 rl_insert_text (incoming
);
810 /* Overwrite the character at point (or next COUNT characters) with C.
811 If C introduces a multibyte character sequence, read the entire sequence
812 before starting the overwrite loop. */
814 _rl_overwrite_char (count
, c
)
818 #if defined (HANDLE_MULTIBYTE)
819 char mbkey
[MB_LEN_MAX
];
822 /* Read an entire multibyte character sequence to insert COUNT times. */
823 if (count
> 0 && MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
824 k
= _rl_read_mbstring (c
, mbkey
, MB_LEN_MAX
);
827 rl_begin_undo_group ();
829 for (i
= 0; i
< count
; i
++)
831 #if defined (HANDLE_MULTIBYTE)
832 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
833 rl_insert_text (mbkey
);
836 _rl_insert_char (1, c
);
838 if (rl_point
< rl_end
)
842 rl_end_undo_group ();
851 return (rl_insert_mode
== RL_IM_INSERT
? _rl_insert_char (count
, c
)
852 : _rl_overwrite_char (count
, c
));
855 /* Insert the next typed character verbatim. */
857 _rl_insert_next (count
)
862 RL_SETSTATE(RL_STATE_MOREINPUT
);
864 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
869 #if defined (HANDLE_SIGNALS)
870 if (RL_ISSTATE (RL_STATE_CALLBACK
) == 0)
871 _rl_restore_tty_signals ();
874 return (_rl_insert_char (count
, c
));
877 #if defined (READLINE_CALLBACKS)
879 _rl_insert_next_callback (data
)
880 _rl_callback_generic_arg
*data
;
886 /* Deregister function, let rl_callback_read_char deallocate data */
887 _rl_callback_func
= 0;
888 _rl_want_redisplay
= 1;
890 return _rl_insert_next (count
);
895 rl_quoted_insert (count
, key
)
898 /* Let's see...should the callback interface futz with signal handling? */
899 #if defined (HANDLE_SIGNALS)
900 if (RL_ISSTATE (RL_STATE_CALLBACK
) == 0)
901 _rl_disable_tty_signals ();
904 #if defined (READLINE_CALLBACKS)
905 if (RL_ISSTATE (RL_STATE_CALLBACK
))
907 _rl_callback_data
= _rl_callback_data_alloc (count
);
908 _rl_callback_func
= _rl_insert_next_callback
;
913 return _rl_insert_next (count
);
916 /* Insert a tab character. */
918 rl_tab_insert (count
, key
)
921 return (_rl_insert_char (count
, '\t'));
924 /* What to do when a NEWLINE is pressed. We accept the whole line.
925 KEY is the key that invoked this command. I guess it could have
926 meaning in the future. */
928 rl_newline (count
, key
)
933 if (_rl_history_preserve_point
)
934 _rl_history_saved_point
= (rl_point
== rl_end
) ? -1 : rl_point
;
936 RL_SETSTATE(RL_STATE_DONE
);
938 #if defined (VI_MODE)
939 if (rl_editing_mode
== vi_mode
)
941 _rl_vi_done_inserting ();
942 if (_rl_vi_textmod_command (_rl_vi_last_command
) == 0) /* XXX */
943 _rl_vi_reset_last ();
947 /* If we've been asked to erase empty lines, suppress the final update,
948 since _rl_update_final calls rl_crlf(). */
949 if (rl_erase_empty_line
&& rl_point
== 0 && rl_end
== 0)
957 /* What to do for some uppercase characters, like meta characters,
958 and some characters appearing in emacs_ctlx_keymap. This function
959 is just a stub, you bind keys to it and the code in _rl_dispatch ()
962 rl_do_lowercase_version (ignore1
, ignore2
)
963 int ignore1
, ignore2
;
968 /* This is different from what vi does, so the code's not shared. Emacs
969 rubout in overwrite mode has one oddity: it replaces a control
970 character that's displayed as two characters (^X) with two spaces. */
972 _rl_overwrite_rubout (count
, key
)
986 /* L == number of spaces to insert */
987 for (i
= l
= 0; i
< count
; i
++)
989 rl_backward_char (1, key
);
990 l
+= rl_character_len (rl_line_buffer
[rl_point
], rl_point
); /* not exactly right */
993 rl_begin_undo_group ();
995 if (count
> 1 || rl_explicit_arg
)
996 rl_kill_text (opoint
, rl_point
);
998 rl_delete_text (opoint
, rl_point
);
1000 /* Emacs puts point at the beginning of the sequence of spaces. */
1001 if (rl_point
< rl_end
)
1004 _rl_insert_char (l
, ' ');
1008 rl_end_undo_group ();
1013 /* Rubout the character behind point. */
1015 rl_rubout (count
, key
)
1019 return (rl_delete (-count
, key
));
1027 if (rl_insert_mode
== RL_IM_OVERWRITE
)
1028 return (_rl_overwrite_rubout (count
, key
));
1030 return (_rl_rubout_char (count
, key
));
1034 _rl_rubout_char (count
, key
)
1040 /* Duplicated code because this is called from other parts of the library. */
1042 return (rl_delete (-count
, key
));
1050 orig_point
= rl_point
;
1051 if (count
> 1 || rl_explicit_arg
)
1053 rl_backward_char (count
, key
);
1054 rl_kill_text (orig_point
, rl_point
);
1056 else if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1058 c
= rl_line_buffer
[--rl_point
];
1059 rl_delete_text (rl_point
, orig_point
);
1060 /* The erase-at-end-of-line hack is of questionable merit now. */
1061 if (rl_point
== rl_end
&& ISPRINT (c
) && _rl_last_c_pos
)
1064 l
= rl_character_len (c
, rl_point
);
1065 _rl_erase_at_end_of_line (l
);
1070 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1071 rl_delete_text (rl_point
, orig_point
);
1077 /* Delete the character under the cursor. Given a numeric argument,
1078 kill that many characters instead. */
1080 rl_delete (count
, key
)
1086 return (_rl_rubout_char (-count
, key
));
1088 if (rl_point
== rl_end
)
1094 if (count
> 1 || rl_explicit_arg
)
1097 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1098 rl_forward_char (count
, key
);
1100 rl_forward_byte (count
, key
);
1102 rl_kill_text (xpoint
, rl_point
);
1107 xpoint
= MB_NEXTCHAR (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
1108 rl_delete_text (rl_point
, xpoint
);
1113 /* Delete the character under the cursor, unless the insertion
1114 point is at the end of the line, in which case the character
1115 behind the cursor is deleted. COUNT is obeyed and may be used
1116 to delete forward or backward that many characters. */
1118 rl_rubout_or_delete (count
, key
)
1121 if (rl_end
!= 0 && rl_point
== rl_end
)
1122 return (_rl_rubout_char (count
, key
));
1124 return (rl_delete (count
, key
));
1127 /* Delete all spaces and tabs around point. */
1129 rl_delete_horizontal_space (count
, ignore
)
1132 int start
= rl_point
;
1134 while (rl_point
&& whitespace (rl_line_buffer
[rl_point
- 1]))
1139 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
1142 if (start
!= rl_point
)
1144 rl_delete_text (start
, rl_point
);
1154 /* Like the tcsh editing function delete-char-or-list. The eof character
1155 is caught before this is invoked, so this really does the same thing as
1156 delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1158 rl_delete_or_show_completions (count
, key
)
1161 if (rl_end
!= 0 && rl_point
== rl_end
)
1162 return (rl_possible_completions (count
, key
));
1164 return (rl_delete (count
, key
));
1167 #ifndef RL_COMMENT_BEGIN_DEFAULT
1168 #define RL_COMMENT_BEGIN_DEFAULT "#"
1171 /* Turn the current line into a comment in shell history.
1172 A K*rn shell style function. */
1174 rl_insert_comment (count
, key
)
1177 char *rl_comment_text
;
1180 rl_beg_of_line (1, key
);
1181 rl_comment_text
= _rl_comment_begin
? _rl_comment_begin
: RL_COMMENT_BEGIN_DEFAULT
;
1183 if (rl_explicit_arg
== 0)
1184 rl_insert_text (rl_comment_text
);
1187 rl_comment_len
= strlen (rl_comment_text
);
1188 if (STREQN (rl_comment_text
, rl_line_buffer
, rl_comment_len
))
1189 rl_delete_text (rl_point
, rl_point
+ rl_comment_len
);
1191 rl_insert_text (rl_comment_text
);
1194 (*rl_redisplay_function
) ();
1195 rl_newline (1, '\n');
1200 /* **************************************************************** */
1204 /* **************************************************************** */
1206 /* The three kinds of things that we know how to do. */
1211 /* Uppercase the word at point. */
1213 rl_upcase_word (count
, key
)
1216 return (rl_change_case (count
, UpCase
));
1219 /* Lowercase the word at point. */
1221 rl_downcase_word (count
, key
)
1224 return (rl_change_case (count
, DownCase
));
1227 /* Upcase the first letter, downcase the rest. */
1229 rl_capitalize_word (count
, key
)
1232 return (rl_change_case (count
, CapCase
));
1235 /* The meaty function.
1236 Change the case of COUNT words, performing OP on them.
1237 OP is one of UpCase, DownCase, or CapCase.
1238 If a negative argument is given, leave point where it started,
1239 otherwise, leave it where it moves to. */
1241 rl_change_case (count
, op
)
1244 int start
, next
, end
;
1245 int inword
, c
, nc
, nop
;
1246 #if defined (HANDLE_MULTIBYTE)
1248 char mb
[MB_LEN_MAX
+1];
1254 rl_forward_word (count
, 0);
1257 if (op
!= UpCase
&& op
!= DownCase
&& op
!= CapCase
)
1266 #if defined (HANDLE_MULTIBYTE)
1267 memset (&mps
, 0, sizeof (mbstate_t));
1270 /* We are going to modify some text, so let's prepare to undo it. */
1271 rl_modifying (start
, end
);
1276 c
= _rl_char_value (rl_line_buffer
, start
);
1277 /* This assumes that the upper and lower case versions are the same width. */
1278 next
= MB_NEXTCHAR (rl_line_buffer
, start
, 1, MB_FIND_NONZERO
);
1280 if (_rl_walphabetic (c
) == 0)
1289 nop
= inword
? DownCase
: UpCase
;
1294 if (MB_CUR_MAX
== 1 || rl_byte_oriented
|| isascii (c
))
1296 nc
= (nop
== UpCase
) ? _rl_to_upper (c
) : _rl_to_lower (c
);
1297 rl_line_buffer
[start
] = nc
;
1299 #if defined (HANDLE_MULTIBYTE)
1302 mbrtowc (&wc
, rl_line_buffer
+ start
, end
- start
, &mps
);
1303 nwc
= (nop
== UpCase
) ? _rl_to_wupper (wc
) : _rl_to_wlower (wc
);
1304 if (nwc
!= wc
) /* just skip unchanged characters */
1306 mlen
= wcrtomb (mb
, nwc
, &mps
);
1309 /* Assume the same width */
1310 strncpy (rl_line_buffer
+ start
, mb
, mlen
);
1322 /* **************************************************************** */
1326 /* **************************************************************** */
1328 /* Transpose the words at point. If point is at the end of the line,
1329 transpose the two words before point. */
1331 rl_transpose_words (count
, key
)
1334 char *word1
, *word2
;
1335 int w1_beg
, w1_end
, w2_beg
, w2_end
;
1336 int orig_point
= rl_point
;
1341 /* Find the two words. */
1342 rl_forward_word (count
, key
);
1344 rl_backward_word (1, key
);
1346 rl_backward_word (count
, key
);
1348 rl_forward_word (1, key
);
1351 /* Do some check to make sure that there really are two words. */
1352 if ((w1_beg
== w2_beg
) || (w2_beg
< w1_end
))
1355 rl_point
= orig_point
;
1359 /* Get the text of the words. */
1360 word1
= rl_copy_text (w1_beg
, w1_end
);
1361 word2
= rl_copy_text (w2_beg
, w2_end
);
1363 /* We are about to do many insertions and deletions. Remember them
1364 as one operation. */
1365 rl_begin_undo_group ();
1367 /* Do the stuff at word2 first, so that we don't have to worry
1368 about word1 moving. */
1370 rl_delete_text (w2_beg
, w2_end
);
1371 rl_insert_text (word1
);
1374 rl_delete_text (w1_beg
, w1_end
);
1375 rl_insert_text (word2
);
1377 /* This is exactly correct since the text before this point has not
1378 changed in length. */
1381 /* I think that does it. */
1382 rl_end_undo_group ();
1389 /* Transpose the characters at point. If point is at the end of the line,
1390 then transpose the characters before point. */
1392 rl_transpose_chars (count
, key
)
1395 #if defined (HANDLE_MULTIBYTE)
1401 int char_length
, prev_point
;
1406 if (!rl_point
|| rl_end
< 2)
1412 rl_begin_undo_group ();
1414 if (rl_point
== rl_end
)
1416 rl_point
= MB_PREVCHAR (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1420 prev_point
= rl_point
;
1421 rl_point
= MB_PREVCHAR (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1423 #if defined (HANDLE_MULTIBYTE)
1424 char_length
= prev_point
- rl_point
;
1425 dummy
= (char *)xmalloc (char_length
+ 1);
1426 for (i
= 0; i
< char_length
; i
++)
1427 dummy
[i
] = rl_line_buffer
[rl_point
+ i
];
1430 dummy
[0] = rl_line_buffer
[rl_point
];
1431 dummy
[char_length
= 1] = '\0';
1434 rl_delete_text (rl_point
, rl_point
+ char_length
);
1436 rl_point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
1439 rl_insert_text (dummy
);
1440 rl_end_undo_group ();
1442 #if defined (HANDLE_MULTIBYTE)
1449 /* **************************************************************** */
1451 /* Character Searching */
1453 /* **************************************************************** */
1456 #if defined (HANDLE_MULTIBYTE)
1457 _rl_char_search_internal (count
, dir
, smbchar
, len
)
1462 _rl_char_search_internal (count
, dir
, schar
)
1463 int count
, dir
, schar
;
1467 #if defined (HANDLE_MULTIBYTE)
1472 inc
= (dir
< 0) ? -1 : 1;
1475 if ((dir
< 0 && pos
<= 0) || (dir
> 0 && pos
>= rl_end
))
1481 #if defined (HANDLE_MULTIBYTE)
1482 pos
= (inc
> 0) ? _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)
1483 : _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
);
1489 #if defined (HANDLE_MULTIBYTE)
1490 if (_rl_is_mbchar_matched (rl_line_buffer
, pos
, rl_end
, smbchar
, len
))
1492 if (rl_line_buffer
[pos
] == schar
)
1497 rl_point
= (dir
== BTO
) ? _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)
1500 rl_point
= (dir
== FTO
) ? _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
)
1504 #if defined (HANDLE_MULTIBYTE)
1508 #if defined (HANDLE_MULTIBYTE)
1509 while ((dir
< 0) ? (pos
= _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
)) != prepos
1510 : (pos
= _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
)) != prepos
);
1512 while ((dir
< 0) ? pos
-- : ++pos
< rl_end
);
1518 /* Search COUNT times for a character read from the current input stream.
1519 FDIR is the direction to search if COUNT is non-negative; otherwise
1520 the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
1521 that there are two separate versions of this function. */
1522 #if defined (HANDLE_MULTIBYTE)
1524 _rl_char_search (count
, fdir
, bdir
)
1525 int count
, fdir
, bdir
;
1527 char mbchar
[MB_LEN_MAX
];
1530 mb_len
= _rl_read_mbchar (mbchar
, MB_LEN_MAX
);
1536 return (_rl_char_search_internal (-count
, bdir
, mbchar
, mb_len
));
1538 return (_rl_char_search_internal (count
, fdir
, mbchar
, mb_len
));
1540 #else /* !HANDLE_MULTIBYTE */
1542 _rl_char_search (count
, fdir
, bdir
)
1543 int count
, fdir
, bdir
;
1547 RL_SETSTATE(RL_STATE_MOREINPUT
);
1549 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1555 return (_rl_char_search_internal (-count
, bdir
, c
));
1557 return (_rl_char_search_internal (count
, fdir
, c
));
1559 #endif /* !HANDLE_MULTIBYTE */
1561 #if defined (READLINE_CALLBACKS)
1563 _rl_char_search_callback (data
)
1564 _rl_callback_generic_arg
*data
;
1566 _rl_callback_func
= 0;
1567 _rl_want_redisplay
= 1;
1569 return (_rl_char_search (data
->count
, data
->i1
, data
->i2
));
1574 rl_char_search (count
, key
)
1577 #if defined (READLINE_CALLBACKS)
1578 if (RL_ISSTATE (RL_STATE_CALLBACK
))
1580 _rl_callback_data
= _rl_callback_data_alloc (count
);
1581 _rl_callback_data
->i1
= FFIND
;
1582 _rl_callback_data
->i2
= BFIND
;
1583 _rl_callback_func
= _rl_char_search_callback
;
1588 return (_rl_char_search (count
, FFIND
, BFIND
));
1592 rl_backward_char_search (count
, key
)
1595 #if defined (READLINE_CALLBACKS)
1596 if (RL_ISSTATE (RL_STATE_CALLBACK
))
1598 _rl_callback_data
= _rl_callback_data_alloc (count
);
1599 _rl_callback_data
->i1
= BFIND
;
1600 _rl_callback_data
->i2
= FFIND
;
1601 _rl_callback_func
= _rl_char_search_callback
;
1606 return (_rl_char_search (count
, BFIND
, FFIND
));
1609 /* **************************************************************** */
1611 /* The Mark and the Region. */
1613 /* **************************************************************** */
1615 /* Set the mark at POSITION. */
1617 _rl_set_mark_at_pos (position
)
1620 if (position
> rl_end
)
1627 /* A bindable command to set the mark. */
1629 rl_set_mark (count
, key
)
1632 return (_rl_set_mark_at_pos (rl_explicit_arg
? count
: rl_point
));
1635 /* Exchange the position of mark and point. */
1637 rl_exchange_point_and_mark (count
, key
)
1640 if (rl_mark
> rl_end
)
1649 SWAP (rl_point
, rl_mark
);