115b117eaSkettenis /* text.c -- text handling commands for readline. */
215b117eaSkettenis
315b117eaSkettenis /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
415b117eaSkettenis
515b117eaSkettenis This file is part of the GNU Readline Library, a library for
615b117eaSkettenis reading lines of text with interactive input and history editing.
715b117eaSkettenis
815b117eaSkettenis The GNU Readline Library is free software; you can redistribute it
915b117eaSkettenis and/or modify it under the terms of the GNU General Public License
1015b117eaSkettenis as published by the Free Software Foundation; either version 2, or
1115b117eaSkettenis (at your option) any later version.
1215b117eaSkettenis
1315b117eaSkettenis The GNU Readline Library is distributed in the hope that it will be
1415b117eaSkettenis useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1515b117eaSkettenis of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1615b117eaSkettenis GNU General Public License for more details.
1715b117eaSkettenis
1815b117eaSkettenis The GNU General Public License is often shipped with GNU software, and
1915b117eaSkettenis is generally kept in a file called COPYING or LICENSE. If you do not
2015b117eaSkettenis have a copy of the license, write to the Free Software Foundation,
2115b117eaSkettenis 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
2215b117eaSkettenis #define READLINE_LIBRARY
2315b117eaSkettenis
2415b117eaSkettenis #if defined (HAVE_CONFIG_H)
2515b117eaSkettenis # include <config.h>
2615b117eaSkettenis #endif
2715b117eaSkettenis
2815b117eaSkettenis #if defined (HAVE_UNISTD_H)
2915b117eaSkettenis # include <unistd.h>
3015b117eaSkettenis #endif /* HAVE_UNISTD_H */
3115b117eaSkettenis
3215b117eaSkettenis #if defined (HAVE_STDLIB_H)
3315b117eaSkettenis # include <stdlib.h>
3415b117eaSkettenis #else
3515b117eaSkettenis # include "ansi_stdlib.h"
3615b117eaSkettenis #endif /* HAVE_STDLIB_H */
3715b117eaSkettenis
3815b117eaSkettenis #if defined (HAVE_LOCALE_H)
3915b117eaSkettenis # include <locale.h>
4015b117eaSkettenis #endif
4115b117eaSkettenis
4215b117eaSkettenis #include <stdio.h>
4315b117eaSkettenis
4415b117eaSkettenis /* System-specific feature definitions and include files. */
4515b117eaSkettenis #include "rldefs.h"
4615b117eaSkettenis #include "rlmbutil.h"
4715b117eaSkettenis
4815b117eaSkettenis #if defined (__EMX__)
4915b117eaSkettenis # define INCL_DOSPROCESS
5015b117eaSkettenis # include <os2.h>
5115b117eaSkettenis #endif /* __EMX__ */
5215b117eaSkettenis
5315b117eaSkettenis /* Some standard library routines. */
5415b117eaSkettenis #include "readline.h"
5515b117eaSkettenis #include "history.h"
5615b117eaSkettenis
5715b117eaSkettenis #include "rlprivate.h"
5815b117eaSkettenis #include "rlshell.h"
5915b117eaSkettenis #include "xmalloc.h"
6015b117eaSkettenis
6115b117eaSkettenis /* Forward declarations. */
6215b117eaSkettenis static int rl_change_case PARAMS((int, int));
6315b117eaSkettenis static int _rl_char_search PARAMS((int, int, int));
6415b117eaSkettenis
6515b117eaSkettenis /* **************************************************************** */
6615b117eaSkettenis /* */
6715b117eaSkettenis /* Insert and Delete */
6815b117eaSkettenis /* */
6915b117eaSkettenis /* **************************************************************** */
7015b117eaSkettenis
7115b117eaSkettenis /* Insert a string of text into the line at point. This is the only
7215b117eaSkettenis way that you should do insertion. _rl_insert_char () calls this
7315b117eaSkettenis function. Returns the number of characters inserted. */
7415b117eaSkettenis int
rl_insert_text(string)7515b117eaSkettenis rl_insert_text (string)
7615b117eaSkettenis const char *string;
7715b117eaSkettenis {
7815b117eaSkettenis register int i, l;
7915b117eaSkettenis
8015b117eaSkettenis l = (string && *string) ? strlen (string) : 0;
8115b117eaSkettenis if (l == 0)
8215b117eaSkettenis return 0;
8315b117eaSkettenis
8415b117eaSkettenis if (rl_end + l >= rl_line_buffer_len)
8515b117eaSkettenis rl_extend_line_buffer (rl_end + l);
8615b117eaSkettenis
8715b117eaSkettenis for (i = rl_end; i >= rl_point; i--)
8815b117eaSkettenis rl_line_buffer[i + l] = rl_line_buffer[i];
8915b117eaSkettenis strncpy (rl_line_buffer + rl_point, string, l);
9015b117eaSkettenis
9115b117eaSkettenis /* Remember how to undo this if we aren't undoing something. */
9215b117eaSkettenis if (_rl_doing_an_undo == 0)
9315b117eaSkettenis {
9415b117eaSkettenis /* If possible and desirable, concatenate the undos. */
9515b117eaSkettenis if ((l == 1) &&
9615b117eaSkettenis rl_undo_list &&
9715b117eaSkettenis (rl_undo_list->what == UNDO_INSERT) &&
9815b117eaSkettenis (rl_undo_list->end == rl_point) &&
9915b117eaSkettenis (rl_undo_list->end - rl_undo_list->start < 20))
10015b117eaSkettenis rl_undo_list->end++;
10115b117eaSkettenis else
10215b117eaSkettenis rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
10315b117eaSkettenis }
10415b117eaSkettenis rl_point += l;
10515b117eaSkettenis rl_end += l;
10615b117eaSkettenis rl_line_buffer[rl_end] = '\0';
10715b117eaSkettenis return l;
10815b117eaSkettenis }
10915b117eaSkettenis
11015b117eaSkettenis /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
11115b117eaSkettenis Returns the number of characters deleted. */
11215b117eaSkettenis int
rl_delete_text(from,to)11315b117eaSkettenis rl_delete_text (from, to)
11415b117eaSkettenis int from, to;
11515b117eaSkettenis {
11615b117eaSkettenis register char *text;
11715b117eaSkettenis register int diff, i;
11815b117eaSkettenis
11915b117eaSkettenis /* Fix it if the caller is confused. */
12015b117eaSkettenis if (from > to)
12115b117eaSkettenis SWAP (from, to);
12215b117eaSkettenis
12315b117eaSkettenis /* fix boundaries */
12415b117eaSkettenis if (to > rl_end)
12515b117eaSkettenis {
12615b117eaSkettenis to = rl_end;
12715b117eaSkettenis if (from > to)
12815b117eaSkettenis from = to;
12915b117eaSkettenis }
13015b117eaSkettenis if (from < 0)
13115b117eaSkettenis from = 0;
13215b117eaSkettenis
13315b117eaSkettenis text = rl_copy_text (from, to);
13415b117eaSkettenis
13515b117eaSkettenis /* Some versions of strncpy() can't handle overlapping arguments. */
13615b117eaSkettenis diff = to - from;
13715b117eaSkettenis for (i = from; i < rl_end - diff; i++)
13815b117eaSkettenis rl_line_buffer[i] = rl_line_buffer[i + diff];
13915b117eaSkettenis
14015b117eaSkettenis /* Remember how to undo this delete. */
14115b117eaSkettenis if (_rl_doing_an_undo == 0)
14215b117eaSkettenis rl_add_undo (UNDO_DELETE, from, to, text);
14315b117eaSkettenis else
14415b117eaSkettenis free (text);
14515b117eaSkettenis
14615b117eaSkettenis rl_end -= diff;
14715b117eaSkettenis rl_line_buffer[rl_end] = '\0';
14815b117eaSkettenis return (diff);
14915b117eaSkettenis }
15015b117eaSkettenis
15115b117eaSkettenis /* Fix up point so that it is within the line boundaries after killing
15215b117eaSkettenis text. If FIX_MARK_TOO is non-zero, the mark is forced within line
15315b117eaSkettenis boundaries also. */
15415b117eaSkettenis
15515b117eaSkettenis #define _RL_FIX_POINT(x) \
15615b117eaSkettenis do { \
15715b117eaSkettenis if (x > rl_end) \
15815b117eaSkettenis x = rl_end; \
15915b117eaSkettenis else if (x < 0) \
16015b117eaSkettenis x = 0; \
16115b117eaSkettenis } while (0)
16215b117eaSkettenis
16315b117eaSkettenis void
_rl_fix_point(fix_mark_too)16415b117eaSkettenis _rl_fix_point (fix_mark_too)
16515b117eaSkettenis int fix_mark_too;
16615b117eaSkettenis {
16715b117eaSkettenis _RL_FIX_POINT (rl_point);
16815b117eaSkettenis if (fix_mark_too)
16915b117eaSkettenis _RL_FIX_POINT (rl_mark);
17015b117eaSkettenis }
17115b117eaSkettenis #undef _RL_FIX_POINT
17215b117eaSkettenis
17315b117eaSkettenis int
_rl_replace_text(text,start,end)17415b117eaSkettenis _rl_replace_text (text, start, end)
17515b117eaSkettenis const char *text;
17615b117eaSkettenis int start, end;
17715b117eaSkettenis {
17815b117eaSkettenis int n;
17915b117eaSkettenis
18015b117eaSkettenis rl_begin_undo_group ();
18115b117eaSkettenis rl_delete_text (start, end + 1);
18215b117eaSkettenis rl_point = start;
18315b117eaSkettenis n = rl_insert_text (text);
18415b117eaSkettenis rl_end_undo_group ();
18515b117eaSkettenis
18615b117eaSkettenis return n;
18715b117eaSkettenis }
18815b117eaSkettenis
18915b117eaSkettenis /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
19015b117eaSkettenis non-zero, we free the current undo list. */
19115b117eaSkettenis void
rl_replace_line(text,clear_undo)19215b117eaSkettenis rl_replace_line (text, clear_undo)
19315b117eaSkettenis const char *text;
19415b117eaSkettenis int clear_undo;
19515b117eaSkettenis {
19615b117eaSkettenis int len;
19715b117eaSkettenis
19815b117eaSkettenis len = strlen (text);
19915b117eaSkettenis if (len >= rl_line_buffer_len)
20015b117eaSkettenis rl_extend_line_buffer (len);
201*9480732dSkettenis strlcpy (rl_line_buffer, text, rl_line_buffer_len);
20215b117eaSkettenis rl_end = len;
20315b117eaSkettenis
20415b117eaSkettenis if (clear_undo)
20515b117eaSkettenis rl_free_undo_list ();
20615b117eaSkettenis
20715b117eaSkettenis _rl_fix_point (1);
20815b117eaSkettenis }
20915b117eaSkettenis
21015b117eaSkettenis /* **************************************************************** */
21115b117eaSkettenis /* */
21215b117eaSkettenis /* Readline character functions */
21315b117eaSkettenis /* */
21415b117eaSkettenis /* **************************************************************** */
21515b117eaSkettenis
21615b117eaSkettenis /* This is not a gap editor, just a stupid line input routine. No hair
21715b117eaSkettenis is involved in writing any of the functions, and none should be. */
21815b117eaSkettenis
21915b117eaSkettenis /* Note that:
22015b117eaSkettenis
22115b117eaSkettenis rl_end is the place in the string that we would place '\0';
22215b117eaSkettenis i.e., it is always safe to place '\0' there.
22315b117eaSkettenis
22415b117eaSkettenis rl_point is the place in the string where the cursor is. Sometimes
22515b117eaSkettenis this is the same as rl_end.
22615b117eaSkettenis
22715b117eaSkettenis Any command that is called interactively receives two arguments.
22815b117eaSkettenis The first is a count: the numeric arg pased to this command.
22915b117eaSkettenis The second is the key which invoked this command.
23015b117eaSkettenis */
23115b117eaSkettenis
23215b117eaSkettenis /* **************************************************************** */
23315b117eaSkettenis /* */
23415b117eaSkettenis /* Movement Commands */
23515b117eaSkettenis /* */
23615b117eaSkettenis /* **************************************************************** */
23715b117eaSkettenis
23815b117eaSkettenis /* Note that if you `optimize' the display for these functions, you cannot
23915b117eaSkettenis use said functions in other functions which do not do optimizing display.
24015b117eaSkettenis I.e., you will have to update the data base for rl_redisplay, and you
24115b117eaSkettenis might as well let rl_redisplay do that job. */
24215b117eaSkettenis
24315b117eaSkettenis /* Move forward COUNT bytes. */
24415b117eaSkettenis int
rl_forward_byte(count,key)24515b117eaSkettenis rl_forward_byte (count, key)
24615b117eaSkettenis int count, key;
24715b117eaSkettenis {
24815b117eaSkettenis if (count < 0)
24915b117eaSkettenis return (rl_backward_byte (-count, key));
25015b117eaSkettenis
25115b117eaSkettenis if (count > 0)
25215b117eaSkettenis {
25315b117eaSkettenis int end = rl_point + count;
25415b117eaSkettenis #if defined (VI_MODE)
25515b117eaSkettenis int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
25615b117eaSkettenis #else
25715b117eaSkettenis int lend = rl_end;
25815b117eaSkettenis #endif
25915b117eaSkettenis
26015b117eaSkettenis if (end > lend)
26115b117eaSkettenis {
26215b117eaSkettenis rl_point = lend;
26315b117eaSkettenis rl_ding ();
26415b117eaSkettenis }
26515b117eaSkettenis else
26615b117eaSkettenis rl_point = end;
26715b117eaSkettenis }
26815b117eaSkettenis
26915b117eaSkettenis if (rl_end < 0)
27015b117eaSkettenis rl_end = 0;
27115b117eaSkettenis
27215b117eaSkettenis return 0;
27315b117eaSkettenis }
27415b117eaSkettenis
27515b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
27615b117eaSkettenis /* Move forward COUNT characters. */
27715b117eaSkettenis int
rl_forward_char(count,key)27815b117eaSkettenis rl_forward_char (count, key)
27915b117eaSkettenis int count, key;
28015b117eaSkettenis {
28115b117eaSkettenis int point;
28215b117eaSkettenis
28315b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
28415b117eaSkettenis return (rl_forward_byte (count, key));
28515b117eaSkettenis
28615b117eaSkettenis if (count < 0)
28715b117eaSkettenis return (rl_backward_char (-count, key));
28815b117eaSkettenis
28915b117eaSkettenis if (count > 0)
29015b117eaSkettenis {
29115b117eaSkettenis point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
29215b117eaSkettenis
29315b117eaSkettenis #if defined (VI_MODE)
29415b117eaSkettenis if (rl_end <= point && rl_editing_mode == vi_mode)
29515b117eaSkettenis point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
29615b117eaSkettenis #endif
29715b117eaSkettenis
29815b117eaSkettenis if (rl_point == point)
29915b117eaSkettenis rl_ding ();
30015b117eaSkettenis
30115b117eaSkettenis rl_point = point;
30215b117eaSkettenis
30315b117eaSkettenis if (rl_end < 0)
30415b117eaSkettenis rl_end = 0;
30515b117eaSkettenis }
30615b117eaSkettenis
30715b117eaSkettenis return 0;
30815b117eaSkettenis }
30915b117eaSkettenis #else /* !HANDLE_MULTIBYTE */
31015b117eaSkettenis int
rl_forward_char(count,key)31115b117eaSkettenis rl_forward_char (count, key)
31215b117eaSkettenis int count, key;
31315b117eaSkettenis {
31415b117eaSkettenis return (rl_forward_byte (count, key));
31515b117eaSkettenis }
31615b117eaSkettenis #endif /* !HANDLE_MULTIBYTE */
31715b117eaSkettenis
31815b117eaSkettenis /* Backwards compatibility. */
31915b117eaSkettenis int
rl_forward(count,key)32015b117eaSkettenis rl_forward (count, key)
32115b117eaSkettenis int count, key;
32215b117eaSkettenis {
32315b117eaSkettenis return (rl_forward_char (count, key));
32415b117eaSkettenis }
32515b117eaSkettenis
32615b117eaSkettenis /* Move backward COUNT bytes. */
32715b117eaSkettenis int
rl_backward_byte(count,key)32815b117eaSkettenis rl_backward_byte (count, key)
32915b117eaSkettenis int count, key;
33015b117eaSkettenis {
33115b117eaSkettenis if (count < 0)
33215b117eaSkettenis return (rl_forward_byte (-count, key));
33315b117eaSkettenis
33415b117eaSkettenis if (count > 0)
33515b117eaSkettenis {
33615b117eaSkettenis if (rl_point < count)
33715b117eaSkettenis {
33815b117eaSkettenis rl_point = 0;
33915b117eaSkettenis rl_ding ();
34015b117eaSkettenis }
34115b117eaSkettenis else
34215b117eaSkettenis rl_point -= count;
34315b117eaSkettenis }
34415b117eaSkettenis
34515b117eaSkettenis if (rl_point < 0)
34615b117eaSkettenis rl_point = 0;
34715b117eaSkettenis
34815b117eaSkettenis return 0;
34915b117eaSkettenis }
35015b117eaSkettenis
35115b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
35215b117eaSkettenis /* Move backward COUNT characters. */
35315b117eaSkettenis int
rl_backward_char(count,key)35415b117eaSkettenis rl_backward_char (count, key)
35515b117eaSkettenis int count, key;
35615b117eaSkettenis {
35715b117eaSkettenis int point;
35815b117eaSkettenis
35915b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
36015b117eaSkettenis return (rl_backward_byte (count, key));
36115b117eaSkettenis
36215b117eaSkettenis if (count < 0)
36315b117eaSkettenis return (rl_forward_char (-count, key));
36415b117eaSkettenis
36515b117eaSkettenis if (count > 0)
36615b117eaSkettenis {
36715b117eaSkettenis point = rl_point;
36815b117eaSkettenis
36915b117eaSkettenis while (count > 0 && point > 0)
37015b117eaSkettenis {
37115b117eaSkettenis point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
37215b117eaSkettenis count--;
37315b117eaSkettenis }
37415b117eaSkettenis if (count > 0)
37515b117eaSkettenis {
37615b117eaSkettenis rl_point = 0;
37715b117eaSkettenis rl_ding ();
37815b117eaSkettenis }
37915b117eaSkettenis else
38015b117eaSkettenis rl_point = point;
38115b117eaSkettenis }
38215b117eaSkettenis
38315b117eaSkettenis return 0;
38415b117eaSkettenis }
38515b117eaSkettenis #else
38615b117eaSkettenis int
rl_backward_char(count,key)38715b117eaSkettenis rl_backward_char (count, key)
38815b117eaSkettenis int count, key;
38915b117eaSkettenis {
39015b117eaSkettenis return (rl_backward_byte (count, key));
39115b117eaSkettenis }
39215b117eaSkettenis #endif
39315b117eaSkettenis
39415b117eaSkettenis /* Backwards compatibility. */
39515b117eaSkettenis int
rl_backward(count,key)39615b117eaSkettenis rl_backward (count, key)
39715b117eaSkettenis int count, key;
39815b117eaSkettenis {
39915b117eaSkettenis return (rl_backward_char (count, key));
40015b117eaSkettenis }
40115b117eaSkettenis
40215b117eaSkettenis /* Move to the beginning of the line. */
40315b117eaSkettenis int
rl_beg_of_line(count,key)40415b117eaSkettenis rl_beg_of_line (count, key)
40515b117eaSkettenis int count, key;
40615b117eaSkettenis {
40715b117eaSkettenis rl_point = 0;
40815b117eaSkettenis return 0;
40915b117eaSkettenis }
41015b117eaSkettenis
41115b117eaSkettenis /* Move to the end of the line. */
41215b117eaSkettenis int
rl_end_of_line(count,key)41315b117eaSkettenis rl_end_of_line (count, key)
41415b117eaSkettenis int count, key;
41515b117eaSkettenis {
41615b117eaSkettenis rl_point = rl_end;
41715b117eaSkettenis return 0;
41815b117eaSkettenis }
41915b117eaSkettenis
42015b117eaSkettenis /* XXX - these might need changes for multibyte characters */
42115b117eaSkettenis /* Move forward a word. We do what Emacs does. */
42215b117eaSkettenis int
rl_forward_word(count,key)42315b117eaSkettenis rl_forward_word (count, key)
42415b117eaSkettenis int count, key;
42515b117eaSkettenis {
42615b117eaSkettenis int c;
42715b117eaSkettenis
42815b117eaSkettenis if (count < 0)
42915b117eaSkettenis return (rl_backward_word (-count, key));
43015b117eaSkettenis
43115b117eaSkettenis while (count)
43215b117eaSkettenis {
43315b117eaSkettenis if (rl_point == rl_end)
43415b117eaSkettenis return 0;
43515b117eaSkettenis
43615b117eaSkettenis /* If we are not in a word, move forward until we are in one.
43715b117eaSkettenis Then, move forward until we hit a non-alphabetic character. */
43815b117eaSkettenis c = rl_line_buffer[rl_point];
43915b117eaSkettenis if (rl_alphabetic (c) == 0)
44015b117eaSkettenis {
44115b117eaSkettenis while (++rl_point < rl_end)
44215b117eaSkettenis {
44315b117eaSkettenis c = rl_line_buffer[rl_point];
44415b117eaSkettenis if (rl_alphabetic (c))
44515b117eaSkettenis break;
44615b117eaSkettenis }
44715b117eaSkettenis }
44815b117eaSkettenis
44915b117eaSkettenis if (rl_point == rl_end)
45015b117eaSkettenis return 0;
45115b117eaSkettenis
45215b117eaSkettenis while (++rl_point < rl_end)
45315b117eaSkettenis {
45415b117eaSkettenis c = rl_line_buffer[rl_point];
45515b117eaSkettenis if (rl_alphabetic (c) == 0)
45615b117eaSkettenis break;
45715b117eaSkettenis }
45815b117eaSkettenis --count;
45915b117eaSkettenis }
46015b117eaSkettenis
46115b117eaSkettenis return 0;
46215b117eaSkettenis }
46315b117eaSkettenis
46415b117eaSkettenis /* Move backward a word. We do what Emacs does. */
46515b117eaSkettenis int
rl_backward_word(count,key)46615b117eaSkettenis rl_backward_word (count, key)
46715b117eaSkettenis int count, key;
46815b117eaSkettenis {
46915b117eaSkettenis int c;
47015b117eaSkettenis
47115b117eaSkettenis if (count < 0)
47215b117eaSkettenis return (rl_forward_word (-count, key));
47315b117eaSkettenis
47415b117eaSkettenis while (count)
47515b117eaSkettenis {
47615b117eaSkettenis if (!rl_point)
47715b117eaSkettenis return 0;
47815b117eaSkettenis
47915b117eaSkettenis /* Like rl_forward_word (), except that we look at the characters
48015b117eaSkettenis just before point. */
48115b117eaSkettenis
48215b117eaSkettenis c = rl_line_buffer[rl_point - 1];
48315b117eaSkettenis if (rl_alphabetic (c) == 0)
48415b117eaSkettenis {
48515b117eaSkettenis while (--rl_point)
48615b117eaSkettenis {
48715b117eaSkettenis c = rl_line_buffer[rl_point - 1];
48815b117eaSkettenis if (rl_alphabetic (c))
48915b117eaSkettenis break;
49015b117eaSkettenis }
49115b117eaSkettenis }
49215b117eaSkettenis
49315b117eaSkettenis while (rl_point)
49415b117eaSkettenis {
49515b117eaSkettenis c = rl_line_buffer[rl_point - 1];
49615b117eaSkettenis if (rl_alphabetic (c) == 0)
49715b117eaSkettenis break;
49815b117eaSkettenis else
49915b117eaSkettenis --rl_point;
50015b117eaSkettenis }
50115b117eaSkettenis
50215b117eaSkettenis --count;
50315b117eaSkettenis }
50415b117eaSkettenis
50515b117eaSkettenis return 0;
50615b117eaSkettenis }
50715b117eaSkettenis
50815b117eaSkettenis /* Clear the current line. Numeric argument to C-l does this. */
50915b117eaSkettenis int
rl_refresh_line(ignore1,ignore2)51015b117eaSkettenis rl_refresh_line (ignore1, ignore2)
51115b117eaSkettenis int ignore1, ignore2;
51215b117eaSkettenis {
51315b117eaSkettenis int curr_line;
51415b117eaSkettenis
51515b117eaSkettenis curr_line = _rl_current_display_line ();
51615b117eaSkettenis
51715b117eaSkettenis _rl_move_vert (curr_line);
51815b117eaSkettenis _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
51915b117eaSkettenis
52015b117eaSkettenis _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
52115b117eaSkettenis
52215b117eaSkettenis rl_forced_update_display ();
52315b117eaSkettenis rl_display_fixed = 1;
52415b117eaSkettenis
52515b117eaSkettenis return 0;
52615b117eaSkettenis }
52715b117eaSkettenis
52815b117eaSkettenis /* C-l typed to a line without quoting clears the screen, and then reprints
52915b117eaSkettenis the prompt and the current input line. Given a numeric arg, redraw only
53015b117eaSkettenis the current line. */
53115b117eaSkettenis int
rl_clear_screen(count,key)53215b117eaSkettenis rl_clear_screen (count, key)
53315b117eaSkettenis int count, key;
53415b117eaSkettenis {
53515b117eaSkettenis if (rl_explicit_arg)
53615b117eaSkettenis {
53715b117eaSkettenis rl_refresh_line (count, key);
53815b117eaSkettenis return 0;
53915b117eaSkettenis }
54015b117eaSkettenis
54115b117eaSkettenis _rl_clear_screen (); /* calls termcap function to clear screen */
54215b117eaSkettenis rl_forced_update_display ();
54315b117eaSkettenis rl_display_fixed = 1;
54415b117eaSkettenis
54515b117eaSkettenis return 0;
54615b117eaSkettenis }
54715b117eaSkettenis
54815b117eaSkettenis int
rl_arrow_keys(count,c)54915b117eaSkettenis rl_arrow_keys (count, c)
55015b117eaSkettenis int count, c;
55115b117eaSkettenis {
55215b117eaSkettenis int ch;
55315b117eaSkettenis
55415b117eaSkettenis RL_SETSTATE(RL_STATE_MOREINPUT);
55515b117eaSkettenis ch = rl_read_key ();
55615b117eaSkettenis RL_UNSETSTATE(RL_STATE_MOREINPUT);
55715b117eaSkettenis
55815b117eaSkettenis switch (_rl_to_upper (ch))
55915b117eaSkettenis {
56015b117eaSkettenis case 'A':
56115b117eaSkettenis rl_get_previous_history (count, ch);
56215b117eaSkettenis break;
56315b117eaSkettenis
56415b117eaSkettenis case 'B':
56515b117eaSkettenis rl_get_next_history (count, ch);
56615b117eaSkettenis break;
56715b117eaSkettenis
56815b117eaSkettenis case 'C':
56915b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
57015b117eaSkettenis rl_forward_char (count, ch);
57115b117eaSkettenis else
57215b117eaSkettenis rl_forward_byte (count, ch);
57315b117eaSkettenis break;
57415b117eaSkettenis
57515b117eaSkettenis case 'D':
57615b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
57715b117eaSkettenis rl_backward_char (count, ch);
57815b117eaSkettenis else
57915b117eaSkettenis rl_backward_byte (count, ch);
58015b117eaSkettenis break;
58115b117eaSkettenis
58215b117eaSkettenis default:
58315b117eaSkettenis rl_ding ();
58415b117eaSkettenis }
58515b117eaSkettenis
58615b117eaSkettenis return 0;
58715b117eaSkettenis }
58815b117eaSkettenis
58915b117eaSkettenis /* **************************************************************** */
59015b117eaSkettenis /* */
59115b117eaSkettenis /* Text commands */
59215b117eaSkettenis /* */
59315b117eaSkettenis /* **************************************************************** */
59415b117eaSkettenis
59515b117eaSkettenis #ifdef HANDLE_MULTIBYTE
59615b117eaSkettenis static char pending_bytes[MB_LEN_MAX];
59715b117eaSkettenis static int pending_bytes_length = 0;
59815b117eaSkettenis static mbstate_t ps = {0};
59915b117eaSkettenis #endif
60015b117eaSkettenis
60115b117eaSkettenis /* Insert the character C at the current location, moving point forward.
60215b117eaSkettenis If C introduces a multibyte sequence, we read the whole sequence and
60315b117eaSkettenis then insert the multibyte char into the line buffer. */
60415b117eaSkettenis int
_rl_insert_char(count,c)60515b117eaSkettenis _rl_insert_char (count, c)
60615b117eaSkettenis int count, c;
60715b117eaSkettenis {
60815b117eaSkettenis register int i;
60915b117eaSkettenis char *string;
61015b117eaSkettenis #ifdef HANDLE_MULTIBYTE
61115b117eaSkettenis int string_size;
61215b117eaSkettenis char incoming[MB_LEN_MAX + 1];
61315b117eaSkettenis int incoming_length = 0;
61415b117eaSkettenis mbstate_t ps_back;
61515b117eaSkettenis static int stored_count = 0;
61615b117eaSkettenis #endif
61715b117eaSkettenis
61815b117eaSkettenis if (count <= 0)
61915b117eaSkettenis return 0;
62015b117eaSkettenis
62115b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
62215b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
62315b117eaSkettenis {
62415b117eaSkettenis incoming[0] = c;
62515b117eaSkettenis incoming[1] = '\0';
62615b117eaSkettenis incoming_length = 1;
62715b117eaSkettenis }
62815b117eaSkettenis else
62915b117eaSkettenis {
63015b117eaSkettenis wchar_t wc;
63115b117eaSkettenis size_t ret;
63215b117eaSkettenis
63315b117eaSkettenis if (stored_count <= 0)
63415b117eaSkettenis stored_count = count;
63515b117eaSkettenis else
63615b117eaSkettenis count = stored_count;
63715b117eaSkettenis
63815b117eaSkettenis ps_back = ps;
63915b117eaSkettenis pending_bytes[pending_bytes_length++] = c;
64015b117eaSkettenis ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
64115b117eaSkettenis
64215b117eaSkettenis if (ret == (size_t)-2)
64315b117eaSkettenis {
64415b117eaSkettenis /* Bytes too short to compose character, try to wait for next byte.
64515b117eaSkettenis Restore the state of the byte sequence, because in this case the
64615b117eaSkettenis effect of mbstate is undefined. */
64715b117eaSkettenis ps = ps_back;
64815b117eaSkettenis return 1;
64915b117eaSkettenis }
65015b117eaSkettenis else if (ret == (size_t)-1)
65115b117eaSkettenis {
65215b117eaSkettenis /* Invalid byte sequence for the current locale. Treat first byte
65315b117eaSkettenis as a single character. */
65415b117eaSkettenis incoming[0] = pending_bytes[0];
65515b117eaSkettenis incoming[1] = '\0';
65615b117eaSkettenis incoming_length = 1;
65715b117eaSkettenis pending_bytes_length--;
65815b117eaSkettenis memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
65915b117eaSkettenis /* Clear the state of the byte sequence, because in this case the
66015b117eaSkettenis effect of mbstate is undefined. */
66115b117eaSkettenis memset (&ps, 0, sizeof (mbstate_t));
66215b117eaSkettenis }
66315b117eaSkettenis else if (ret == (size_t)0)
66415b117eaSkettenis {
66515b117eaSkettenis incoming[0] = '\0';
66615b117eaSkettenis incoming_length = 0;
66715b117eaSkettenis pending_bytes_length--;
66815b117eaSkettenis /* Clear the state of the byte sequence, because in this case the
66915b117eaSkettenis effect of mbstate is undefined. */
67015b117eaSkettenis memset (&ps, 0, sizeof (mbstate_t));
67115b117eaSkettenis }
67215b117eaSkettenis else
67315b117eaSkettenis {
67415b117eaSkettenis /* We successfully read a single multibyte character. */
67515b117eaSkettenis memcpy (incoming, pending_bytes, pending_bytes_length);
67615b117eaSkettenis incoming[pending_bytes_length] = '\0';
67715b117eaSkettenis incoming_length = pending_bytes_length;
67815b117eaSkettenis pending_bytes_length = 0;
67915b117eaSkettenis }
68015b117eaSkettenis }
68115b117eaSkettenis #endif /* HANDLE_MULTIBYTE */
68215b117eaSkettenis
68315b117eaSkettenis /* If we can optimize, then do it. But don't let people crash
68415b117eaSkettenis readline because of extra large arguments. */
68515b117eaSkettenis if (count > 1 && count <= 1024)
68615b117eaSkettenis {
68715b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
68815b117eaSkettenis string_size = count * incoming_length;
68915b117eaSkettenis string = (char *)xmalloc (1 + string_size);
69015b117eaSkettenis
69115b117eaSkettenis i = 0;
69215b117eaSkettenis while (i < string_size)
69315b117eaSkettenis {
69415b117eaSkettenis strncpy (string + i, incoming, incoming_length);
69515b117eaSkettenis i += incoming_length;
69615b117eaSkettenis }
69715b117eaSkettenis incoming_length = 0;
69815b117eaSkettenis stored_count = 0;
69915b117eaSkettenis #else /* !HANDLE_MULTIBYTE */
70015b117eaSkettenis string = (char *)xmalloc (1 + count);
70115b117eaSkettenis
70215b117eaSkettenis for (i = 0; i < count; i++)
70315b117eaSkettenis string[i] = c;
70415b117eaSkettenis #endif /* !HANDLE_MULTIBYTE */
70515b117eaSkettenis
70615b117eaSkettenis string[i] = '\0';
70715b117eaSkettenis rl_insert_text (string);
70815b117eaSkettenis free (string);
70915b117eaSkettenis
71015b117eaSkettenis return 0;
71115b117eaSkettenis }
71215b117eaSkettenis
71315b117eaSkettenis if (count > 1024)
71415b117eaSkettenis {
71515b117eaSkettenis int decreaser;
71615b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
71715b117eaSkettenis string_size = incoming_length * 1024;
71815b117eaSkettenis string = (char *)xmalloc (1 + string_size);
71915b117eaSkettenis
72015b117eaSkettenis i = 0;
72115b117eaSkettenis while (i < string_size)
72215b117eaSkettenis {
72315b117eaSkettenis strncpy (string + i, incoming, incoming_length);
72415b117eaSkettenis i += incoming_length;
72515b117eaSkettenis }
72615b117eaSkettenis
72715b117eaSkettenis while (count)
72815b117eaSkettenis {
72915b117eaSkettenis decreaser = (count > 1024) ? 1024 : count;
73015b117eaSkettenis string[decreaser*incoming_length] = '\0';
73115b117eaSkettenis rl_insert_text (string);
73215b117eaSkettenis count -= decreaser;
73315b117eaSkettenis }
73415b117eaSkettenis
73515b117eaSkettenis free (string);
73615b117eaSkettenis incoming_length = 0;
73715b117eaSkettenis stored_count = 0;
73815b117eaSkettenis #else /* !HANDLE_MULTIBYTE */
73915b117eaSkettenis char str[1024+1];
74015b117eaSkettenis
74115b117eaSkettenis for (i = 0; i < 1024; i++)
74215b117eaSkettenis str[i] = c;
74315b117eaSkettenis
74415b117eaSkettenis while (count)
74515b117eaSkettenis {
74615b117eaSkettenis decreaser = (count > 1024 ? 1024 : count);
74715b117eaSkettenis str[decreaser] = '\0';
74815b117eaSkettenis rl_insert_text (str);
74915b117eaSkettenis count -= decreaser;
75015b117eaSkettenis }
75115b117eaSkettenis #endif /* !HANDLE_MULTIBYTE */
75215b117eaSkettenis
75315b117eaSkettenis return 0;
75415b117eaSkettenis }
75515b117eaSkettenis
75615b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
75715b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
75815b117eaSkettenis {
75915b117eaSkettenis #endif
76015b117eaSkettenis /* We are inserting a single character.
76115b117eaSkettenis If there is pending input, then make a string of all of the
76215b117eaSkettenis pending characters that are bound to rl_insert, and insert
76315b117eaSkettenis them all. */
76415b117eaSkettenis if (_rl_any_typein ())
76515b117eaSkettenis _rl_insert_typein (c);
76615b117eaSkettenis else
76715b117eaSkettenis {
76815b117eaSkettenis /* Inserting a single character. */
76915b117eaSkettenis char str[2];
77015b117eaSkettenis
77115b117eaSkettenis str[1] = '\0';
77215b117eaSkettenis str[0] = c;
77315b117eaSkettenis rl_insert_text (str);
77415b117eaSkettenis }
77515b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
77615b117eaSkettenis }
77715b117eaSkettenis else
77815b117eaSkettenis {
77915b117eaSkettenis rl_insert_text (incoming);
78015b117eaSkettenis stored_count = 0;
78115b117eaSkettenis }
78215b117eaSkettenis #endif
78315b117eaSkettenis
78415b117eaSkettenis return 0;
78515b117eaSkettenis }
78615b117eaSkettenis
78715b117eaSkettenis /* Overwrite the character at point (or next COUNT characters) with C.
78815b117eaSkettenis If C introduces a multibyte character sequence, read the entire sequence
78915b117eaSkettenis before starting the overwrite loop. */
79015b117eaSkettenis int
_rl_overwrite_char(count,c)79115b117eaSkettenis _rl_overwrite_char (count, c)
79215b117eaSkettenis int count, c;
79315b117eaSkettenis {
79415b117eaSkettenis int i;
79515b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
79615b117eaSkettenis char mbkey[MB_LEN_MAX];
79715b117eaSkettenis int k;
79815b117eaSkettenis
79915b117eaSkettenis /* Read an entire multibyte character sequence to insert COUNT times. */
80015b117eaSkettenis if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
80115b117eaSkettenis k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
80215b117eaSkettenis #endif
80315b117eaSkettenis
80415b117eaSkettenis for (i = 0; i < count; i++)
80515b117eaSkettenis {
80615b117eaSkettenis rl_begin_undo_group ();
80715b117eaSkettenis
80815b117eaSkettenis if (rl_point < rl_end)
80915b117eaSkettenis rl_delete (1, c);
81015b117eaSkettenis
81115b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
81215b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
81315b117eaSkettenis rl_insert_text (mbkey);
81415b117eaSkettenis else
81515b117eaSkettenis #endif
81615b117eaSkettenis _rl_insert_char (1, c);
81715b117eaSkettenis
81815b117eaSkettenis rl_end_undo_group ();
81915b117eaSkettenis }
82015b117eaSkettenis
82115b117eaSkettenis return 0;
82215b117eaSkettenis }
82315b117eaSkettenis
82415b117eaSkettenis int
rl_insert(count,c)82515b117eaSkettenis rl_insert (count, c)
82615b117eaSkettenis int count, c;
82715b117eaSkettenis {
82815b117eaSkettenis return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
82915b117eaSkettenis : _rl_overwrite_char (count, c));
83015b117eaSkettenis }
83115b117eaSkettenis
83215b117eaSkettenis /* Insert the next typed character verbatim. */
83315b117eaSkettenis int
rl_quoted_insert(count,key)83415b117eaSkettenis rl_quoted_insert (count, key)
83515b117eaSkettenis int count, key;
83615b117eaSkettenis {
83715b117eaSkettenis int c;
83815b117eaSkettenis
83915b117eaSkettenis #if defined (HANDLE_SIGNALS)
84015b117eaSkettenis _rl_disable_tty_signals ();
84115b117eaSkettenis #endif
84215b117eaSkettenis
84315b117eaSkettenis RL_SETSTATE(RL_STATE_MOREINPUT);
84415b117eaSkettenis c = rl_read_key ();
84515b117eaSkettenis RL_UNSETSTATE(RL_STATE_MOREINPUT);
84615b117eaSkettenis
84715b117eaSkettenis #if defined (HANDLE_SIGNALS)
84815b117eaSkettenis _rl_restore_tty_signals ();
84915b117eaSkettenis #endif
85015b117eaSkettenis
85115b117eaSkettenis return (_rl_insert_char (count, c));
85215b117eaSkettenis }
85315b117eaSkettenis
85415b117eaSkettenis /* Insert a tab character. */
85515b117eaSkettenis int
rl_tab_insert(count,key)85615b117eaSkettenis rl_tab_insert (count, key)
85715b117eaSkettenis int count, key;
85815b117eaSkettenis {
85915b117eaSkettenis return (_rl_insert_char (count, '\t'));
86015b117eaSkettenis }
86115b117eaSkettenis
86215b117eaSkettenis /* What to do when a NEWLINE is pressed. We accept the whole line.
86315b117eaSkettenis KEY is the key that invoked this command. I guess it could have
86415b117eaSkettenis meaning in the future. */
86515b117eaSkettenis int
rl_newline(count,key)86615b117eaSkettenis rl_newline (count, key)
86715b117eaSkettenis int count, key;
86815b117eaSkettenis {
86915b117eaSkettenis rl_done = 1;
87015b117eaSkettenis
87115b117eaSkettenis if (_rl_history_preserve_point)
87215b117eaSkettenis _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
87315b117eaSkettenis
87415b117eaSkettenis RL_SETSTATE(RL_STATE_DONE);
87515b117eaSkettenis
87615b117eaSkettenis #if defined (VI_MODE)
87715b117eaSkettenis if (rl_editing_mode == vi_mode)
87815b117eaSkettenis {
87915b117eaSkettenis _rl_vi_done_inserting ();
88015b117eaSkettenis _rl_vi_reset_last ();
88115b117eaSkettenis }
88215b117eaSkettenis #endif /* VI_MODE */
88315b117eaSkettenis
88415b117eaSkettenis /* If we've been asked to erase empty lines, suppress the final update,
88515b117eaSkettenis since _rl_update_final calls rl_crlf(). */
88615b117eaSkettenis if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
88715b117eaSkettenis return 0;
88815b117eaSkettenis
88915b117eaSkettenis if (readline_echoing_p)
89015b117eaSkettenis _rl_update_final ();
89115b117eaSkettenis return 0;
89215b117eaSkettenis }
89315b117eaSkettenis
89415b117eaSkettenis /* What to do for some uppercase characters, like meta characters,
89515b117eaSkettenis and some characters appearing in emacs_ctlx_keymap. This function
89615b117eaSkettenis is just a stub, you bind keys to it and the code in _rl_dispatch ()
89715b117eaSkettenis is special cased. */
89815b117eaSkettenis int
rl_do_lowercase_version(ignore1,ignore2)89915b117eaSkettenis rl_do_lowercase_version (ignore1, ignore2)
90015b117eaSkettenis int ignore1, ignore2;
90115b117eaSkettenis {
90215b117eaSkettenis return 0;
90315b117eaSkettenis }
90415b117eaSkettenis
90515b117eaSkettenis /* This is different from what vi does, so the code's not shared. Emacs
90615b117eaSkettenis rubout in overwrite mode has one oddity: it replaces a control
90715b117eaSkettenis character that's displayed as two characters (^X) with two spaces. */
90815b117eaSkettenis int
_rl_overwrite_rubout(count,key)90915b117eaSkettenis _rl_overwrite_rubout (count, key)
91015b117eaSkettenis int count, key;
91115b117eaSkettenis {
91215b117eaSkettenis int opoint;
91315b117eaSkettenis int i, l;
91415b117eaSkettenis
91515b117eaSkettenis if (rl_point == 0)
91615b117eaSkettenis {
91715b117eaSkettenis rl_ding ();
91815b117eaSkettenis return 1;
91915b117eaSkettenis }
92015b117eaSkettenis
92115b117eaSkettenis opoint = rl_point;
92215b117eaSkettenis
92315b117eaSkettenis /* L == number of spaces to insert */
92415b117eaSkettenis for (i = l = 0; i < count; i++)
92515b117eaSkettenis {
92615b117eaSkettenis rl_backward_char (1, key);
92715b117eaSkettenis l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
92815b117eaSkettenis }
92915b117eaSkettenis
93015b117eaSkettenis rl_begin_undo_group ();
93115b117eaSkettenis
93215b117eaSkettenis if (count > 1 || rl_explicit_arg)
93315b117eaSkettenis rl_kill_text (opoint, rl_point);
93415b117eaSkettenis else
93515b117eaSkettenis rl_delete_text (opoint, rl_point);
93615b117eaSkettenis
93715b117eaSkettenis /* Emacs puts point at the beginning of the sequence of spaces. */
93815b117eaSkettenis opoint = rl_point;
93915b117eaSkettenis _rl_insert_char (l, ' ');
94015b117eaSkettenis rl_point = opoint;
94115b117eaSkettenis
94215b117eaSkettenis rl_end_undo_group ();
94315b117eaSkettenis
94415b117eaSkettenis return 0;
94515b117eaSkettenis }
94615b117eaSkettenis
94715b117eaSkettenis /* Rubout the character behind point. */
94815b117eaSkettenis int
rl_rubout(count,key)94915b117eaSkettenis rl_rubout (count, key)
95015b117eaSkettenis int count, key;
95115b117eaSkettenis {
95215b117eaSkettenis if (count < 0)
95315b117eaSkettenis return (rl_delete (-count, key));
95415b117eaSkettenis
95515b117eaSkettenis if (!rl_point)
95615b117eaSkettenis {
95715b117eaSkettenis rl_ding ();
95815b117eaSkettenis return -1;
95915b117eaSkettenis }
96015b117eaSkettenis
96115b117eaSkettenis if (rl_insert_mode == RL_IM_OVERWRITE)
96215b117eaSkettenis return (_rl_overwrite_rubout (count, key));
96315b117eaSkettenis
96415b117eaSkettenis return (_rl_rubout_char (count, key));
96515b117eaSkettenis }
96615b117eaSkettenis
96715b117eaSkettenis int
_rl_rubout_char(count,key)96815b117eaSkettenis _rl_rubout_char (count, key)
96915b117eaSkettenis int count, key;
97015b117eaSkettenis {
97115b117eaSkettenis int orig_point;
97215b117eaSkettenis unsigned char c;
97315b117eaSkettenis
97415b117eaSkettenis /* Duplicated code because this is called from other parts of the library. */
97515b117eaSkettenis if (count < 0)
97615b117eaSkettenis return (rl_delete (-count, key));
97715b117eaSkettenis
97815b117eaSkettenis if (rl_point == 0)
97915b117eaSkettenis {
98015b117eaSkettenis rl_ding ();
98115b117eaSkettenis return -1;
98215b117eaSkettenis }
98315b117eaSkettenis
98415b117eaSkettenis if (count > 1 || rl_explicit_arg)
98515b117eaSkettenis {
98615b117eaSkettenis orig_point = rl_point;
98715b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
98815b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
98915b117eaSkettenis rl_backward_char (count, key);
99015b117eaSkettenis else
99115b117eaSkettenis #endif
99215b117eaSkettenis rl_backward_byte (count, key);
99315b117eaSkettenis rl_kill_text (orig_point, rl_point);
99415b117eaSkettenis }
99515b117eaSkettenis else
99615b117eaSkettenis {
99715b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
99815b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
99915b117eaSkettenis {
100015b117eaSkettenis #endif
100115b117eaSkettenis c = rl_line_buffer[--rl_point];
100215b117eaSkettenis rl_delete_text (rl_point, rl_point + 1);
100315b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
100415b117eaSkettenis }
100515b117eaSkettenis else
100615b117eaSkettenis {
100715b117eaSkettenis int orig_point;
100815b117eaSkettenis
100915b117eaSkettenis orig_point = rl_point;
101015b117eaSkettenis rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
101115b117eaSkettenis c = rl_line_buffer[rl_point];
101215b117eaSkettenis rl_delete_text (rl_point, orig_point);
101315b117eaSkettenis }
101415b117eaSkettenis #endif /* HANDLE_MULTIBYTE */
101515b117eaSkettenis
101615b117eaSkettenis /* I don't think that the hack for end of line is needed for
101715b117eaSkettenis multibyte chars. */
101815b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
101915b117eaSkettenis if (MB_CUR_MAX == 1 || rl_byte_oriented)
102015b117eaSkettenis #endif
102115b117eaSkettenis if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
102215b117eaSkettenis {
102315b117eaSkettenis int l;
102415b117eaSkettenis l = rl_character_len (c, rl_point);
102515b117eaSkettenis _rl_erase_at_end_of_line (l);
102615b117eaSkettenis }
102715b117eaSkettenis }
102815b117eaSkettenis
102915b117eaSkettenis return 0;
103015b117eaSkettenis }
103115b117eaSkettenis
103215b117eaSkettenis /* Delete the character under the cursor. Given a numeric argument,
103315b117eaSkettenis kill that many characters instead. */
103415b117eaSkettenis int
rl_delete(count,key)103515b117eaSkettenis rl_delete (count, key)
103615b117eaSkettenis int count, key;
103715b117eaSkettenis {
103815b117eaSkettenis int r;
103915b117eaSkettenis
104015b117eaSkettenis if (count < 0)
104115b117eaSkettenis return (_rl_rubout_char (-count, key));
104215b117eaSkettenis
104315b117eaSkettenis if (rl_point == rl_end)
104415b117eaSkettenis {
104515b117eaSkettenis rl_ding ();
104615b117eaSkettenis return -1;
104715b117eaSkettenis }
104815b117eaSkettenis
104915b117eaSkettenis if (count > 1 || rl_explicit_arg)
105015b117eaSkettenis {
105115b117eaSkettenis int orig_point = rl_point;
105215b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
105315b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
105415b117eaSkettenis rl_forward_char (count, key);
105515b117eaSkettenis else
105615b117eaSkettenis #endif
105715b117eaSkettenis rl_forward_byte (count, key);
105815b117eaSkettenis
105915b117eaSkettenis r = rl_kill_text (orig_point, rl_point);
106015b117eaSkettenis rl_point = orig_point;
106115b117eaSkettenis return r;
106215b117eaSkettenis }
106315b117eaSkettenis else
106415b117eaSkettenis {
106515b117eaSkettenis int new_point;
106615b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
106715b117eaSkettenis new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
106815b117eaSkettenis else
106915b117eaSkettenis new_point = rl_point + 1;
107015b117eaSkettenis
107115b117eaSkettenis return (rl_delete_text (rl_point, new_point));
107215b117eaSkettenis }
107315b117eaSkettenis }
107415b117eaSkettenis
107515b117eaSkettenis /* Delete the character under the cursor, unless the insertion
107615b117eaSkettenis point is at the end of the line, in which case the character
107715b117eaSkettenis behind the cursor is deleted. COUNT is obeyed and may be used
107815b117eaSkettenis to delete forward or backward that many characters. */
107915b117eaSkettenis int
rl_rubout_or_delete(count,key)108015b117eaSkettenis rl_rubout_or_delete (count, key)
108115b117eaSkettenis int count, key;
108215b117eaSkettenis {
108315b117eaSkettenis if (rl_end != 0 && rl_point == rl_end)
108415b117eaSkettenis return (_rl_rubout_char (count, key));
108515b117eaSkettenis else
108615b117eaSkettenis return (rl_delete (count, key));
108715b117eaSkettenis }
108815b117eaSkettenis
108915b117eaSkettenis /* Delete all spaces and tabs around point. */
109015b117eaSkettenis int
rl_delete_horizontal_space(count,ignore)109115b117eaSkettenis rl_delete_horizontal_space (count, ignore)
109215b117eaSkettenis int count, ignore;
109315b117eaSkettenis {
109415b117eaSkettenis int start = rl_point;
109515b117eaSkettenis
109615b117eaSkettenis while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
109715b117eaSkettenis rl_point--;
109815b117eaSkettenis
109915b117eaSkettenis start = rl_point;
110015b117eaSkettenis
110115b117eaSkettenis while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
110215b117eaSkettenis rl_point++;
110315b117eaSkettenis
110415b117eaSkettenis if (start != rl_point)
110515b117eaSkettenis {
110615b117eaSkettenis rl_delete_text (start, rl_point);
110715b117eaSkettenis rl_point = start;
110815b117eaSkettenis }
110915b117eaSkettenis return 0;
111015b117eaSkettenis }
111115b117eaSkettenis
111215b117eaSkettenis /* Like the tcsh editing function delete-char-or-list. The eof character
111315b117eaSkettenis is caught before this is invoked, so this really does the same thing as
111415b117eaSkettenis delete-char-or-list-or-eof, as long as it's bound to the eof character. */
111515b117eaSkettenis int
rl_delete_or_show_completions(count,key)111615b117eaSkettenis rl_delete_or_show_completions (count, key)
111715b117eaSkettenis int count, key;
111815b117eaSkettenis {
111915b117eaSkettenis if (rl_end != 0 && rl_point == rl_end)
112015b117eaSkettenis return (rl_possible_completions (count, key));
112115b117eaSkettenis else
112215b117eaSkettenis return (rl_delete (count, key));
112315b117eaSkettenis }
112415b117eaSkettenis
112515b117eaSkettenis #ifndef RL_COMMENT_BEGIN_DEFAULT
112615b117eaSkettenis #define RL_COMMENT_BEGIN_DEFAULT "#"
112715b117eaSkettenis #endif
112815b117eaSkettenis
112915b117eaSkettenis /* Turn the current line into a comment in shell history.
113015b117eaSkettenis A K*rn shell style function. */
113115b117eaSkettenis int
rl_insert_comment(count,key)113215b117eaSkettenis rl_insert_comment (count, key)
113315b117eaSkettenis int count, key;
113415b117eaSkettenis {
113515b117eaSkettenis char *rl_comment_text;
113615b117eaSkettenis int rl_comment_len;
113715b117eaSkettenis
113815b117eaSkettenis rl_beg_of_line (1, key);
113915b117eaSkettenis rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
114015b117eaSkettenis
114115b117eaSkettenis if (rl_explicit_arg == 0)
114215b117eaSkettenis rl_insert_text (rl_comment_text);
114315b117eaSkettenis else
114415b117eaSkettenis {
114515b117eaSkettenis rl_comment_len = strlen (rl_comment_text);
114615b117eaSkettenis if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
114715b117eaSkettenis rl_delete_text (rl_point, rl_point + rl_comment_len);
114815b117eaSkettenis else
114915b117eaSkettenis rl_insert_text (rl_comment_text);
115015b117eaSkettenis }
115115b117eaSkettenis
115215b117eaSkettenis (*rl_redisplay_function) ();
115315b117eaSkettenis rl_newline (1, '\n');
115415b117eaSkettenis
115515b117eaSkettenis return (0);
115615b117eaSkettenis }
115715b117eaSkettenis
115815b117eaSkettenis /* **************************************************************** */
115915b117eaSkettenis /* */
116015b117eaSkettenis /* Changing Case */
116115b117eaSkettenis /* */
116215b117eaSkettenis /* **************************************************************** */
116315b117eaSkettenis
116415b117eaSkettenis /* The three kinds of things that we know how to do. */
116515b117eaSkettenis #define UpCase 1
116615b117eaSkettenis #define DownCase 2
116715b117eaSkettenis #define CapCase 3
116815b117eaSkettenis
116915b117eaSkettenis /* Uppercase the word at point. */
117015b117eaSkettenis int
rl_upcase_word(count,key)117115b117eaSkettenis rl_upcase_word (count, key)
117215b117eaSkettenis int count, key;
117315b117eaSkettenis {
117415b117eaSkettenis return (rl_change_case (count, UpCase));
117515b117eaSkettenis }
117615b117eaSkettenis
117715b117eaSkettenis /* Lowercase the word at point. */
117815b117eaSkettenis int
rl_downcase_word(count,key)117915b117eaSkettenis rl_downcase_word (count, key)
118015b117eaSkettenis int count, key;
118115b117eaSkettenis {
118215b117eaSkettenis return (rl_change_case (count, DownCase));
118315b117eaSkettenis }
118415b117eaSkettenis
118515b117eaSkettenis /* Upcase the first letter, downcase the rest. */
118615b117eaSkettenis int
rl_capitalize_word(count,key)118715b117eaSkettenis rl_capitalize_word (count, key)
118815b117eaSkettenis int count, key;
118915b117eaSkettenis {
119015b117eaSkettenis return (rl_change_case (count, CapCase));
119115b117eaSkettenis }
119215b117eaSkettenis
119315b117eaSkettenis /* The meaty function.
119415b117eaSkettenis Change the case of COUNT words, performing OP on them.
119515b117eaSkettenis OP is one of UpCase, DownCase, or CapCase.
119615b117eaSkettenis If a negative argument is given, leave point where it started,
119715b117eaSkettenis otherwise, leave it where it moves to. */
119815b117eaSkettenis static int
rl_change_case(count,op)119915b117eaSkettenis rl_change_case (count, op)
120015b117eaSkettenis int count, op;
120115b117eaSkettenis {
120215b117eaSkettenis register int start, end;
120315b117eaSkettenis int inword, c;
120415b117eaSkettenis
120515b117eaSkettenis start = rl_point;
120615b117eaSkettenis rl_forward_word (count, 0);
120715b117eaSkettenis end = rl_point;
120815b117eaSkettenis
120915b117eaSkettenis if (count < 0)
121015b117eaSkettenis SWAP (start, end);
121115b117eaSkettenis
121215b117eaSkettenis /* We are going to modify some text, so let's prepare to undo it. */
121315b117eaSkettenis rl_modifying (start, end);
121415b117eaSkettenis
121515b117eaSkettenis for (inword = 0; start < end; start++)
121615b117eaSkettenis {
121715b117eaSkettenis c = rl_line_buffer[start];
121815b117eaSkettenis switch (op)
121915b117eaSkettenis {
122015b117eaSkettenis case UpCase:
122115b117eaSkettenis rl_line_buffer[start] = _rl_to_upper (c);
122215b117eaSkettenis break;
122315b117eaSkettenis
122415b117eaSkettenis case DownCase:
122515b117eaSkettenis rl_line_buffer[start] = _rl_to_lower (c);
122615b117eaSkettenis break;
122715b117eaSkettenis
122815b117eaSkettenis case CapCase:
122915b117eaSkettenis rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
123015b117eaSkettenis inword = rl_alphabetic (rl_line_buffer[start]);
123115b117eaSkettenis break;
123215b117eaSkettenis
123315b117eaSkettenis default:
123415b117eaSkettenis rl_ding ();
123515b117eaSkettenis return -1;
123615b117eaSkettenis }
123715b117eaSkettenis }
123815b117eaSkettenis rl_point = end;
123915b117eaSkettenis return 0;
124015b117eaSkettenis }
124115b117eaSkettenis
124215b117eaSkettenis /* **************************************************************** */
124315b117eaSkettenis /* */
124415b117eaSkettenis /* Transposition */
124515b117eaSkettenis /* */
124615b117eaSkettenis /* **************************************************************** */
124715b117eaSkettenis
124815b117eaSkettenis /* Transpose the words at point. If point is at the end of the line,
124915b117eaSkettenis transpose the two words before point. */
125015b117eaSkettenis int
rl_transpose_words(count,key)125115b117eaSkettenis rl_transpose_words (count, key)
125215b117eaSkettenis int count, key;
125315b117eaSkettenis {
125415b117eaSkettenis char *word1, *word2;
125515b117eaSkettenis int w1_beg, w1_end, w2_beg, w2_end;
125615b117eaSkettenis int orig_point = rl_point;
125715b117eaSkettenis
125815b117eaSkettenis if (!count)
125915b117eaSkettenis return 0;
126015b117eaSkettenis
126115b117eaSkettenis /* Find the two words. */
126215b117eaSkettenis rl_forward_word (count, key);
126315b117eaSkettenis w2_end = rl_point;
126415b117eaSkettenis rl_backward_word (1, key);
126515b117eaSkettenis w2_beg = rl_point;
126615b117eaSkettenis rl_backward_word (count, key);
126715b117eaSkettenis w1_beg = rl_point;
126815b117eaSkettenis rl_forward_word (1, key);
126915b117eaSkettenis w1_end = rl_point;
127015b117eaSkettenis
127115b117eaSkettenis /* Do some check to make sure that there really are two words. */
127215b117eaSkettenis if ((w1_beg == w2_beg) || (w2_beg < w1_end))
127315b117eaSkettenis {
127415b117eaSkettenis rl_ding ();
127515b117eaSkettenis rl_point = orig_point;
127615b117eaSkettenis return -1;
127715b117eaSkettenis }
127815b117eaSkettenis
127915b117eaSkettenis /* Get the text of the words. */
128015b117eaSkettenis word1 = rl_copy_text (w1_beg, w1_end);
128115b117eaSkettenis word2 = rl_copy_text (w2_beg, w2_end);
128215b117eaSkettenis
128315b117eaSkettenis /* We are about to do many insertions and deletions. Remember them
128415b117eaSkettenis as one operation. */
128515b117eaSkettenis rl_begin_undo_group ();
128615b117eaSkettenis
128715b117eaSkettenis /* Do the stuff at word2 first, so that we don't have to worry
128815b117eaSkettenis about word1 moving. */
128915b117eaSkettenis rl_point = w2_beg;
129015b117eaSkettenis rl_delete_text (w2_beg, w2_end);
129115b117eaSkettenis rl_insert_text (word1);
129215b117eaSkettenis
129315b117eaSkettenis rl_point = w1_beg;
129415b117eaSkettenis rl_delete_text (w1_beg, w1_end);
129515b117eaSkettenis rl_insert_text (word2);
129615b117eaSkettenis
129715b117eaSkettenis /* This is exactly correct since the text before this point has not
129815b117eaSkettenis changed in length. */
129915b117eaSkettenis rl_point = w2_end;
130015b117eaSkettenis
130115b117eaSkettenis /* I think that does it. */
130215b117eaSkettenis rl_end_undo_group ();
130315b117eaSkettenis free (word1);
130415b117eaSkettenis free (word2);
130515b117eaSkettenis
130615b117eaSkettenis return 0;
130715b117eaSkettenis }
130815b117eaSkettenis
130915b117eaSkettenis /* Transpose the characters at point. If point is at the end of the line,
131015b117eaSkettenis then transpose the characters before point. */
131115b117eaSkettenis int
rl_transpose_chars(count,key)131215b117eaSkettenis rl_transpose_chars (count, key)
131315b117eaSkettenis int count, key;
131415b117eaSkettenis {
131515b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
131615b117eaSkettenis char *dummy;
131715b117eaSkettenis int i, prev_point;
131815b117eaSkettenis #else
131915b117eaSkettenis char dummy[2];
132015b117eaSkettenis #endif
132115b117eaSkettenis int char_length;
132215b117eaSkettenis
132315b117eaSkettenis if (count == 0)
132415b117eaSkettenis return 0;
132515b117eaSkettenis
132615b117eaSkettenis if (!rl_point || rl_end < 2)
132715b117eaSkettenis {
132815b117eaSkettenis rl_ding ();
132915b117eaSkettenis return -1;
133015b117eaSkettenis }
133115b117eaSkettenis
133215b117eaSkettenis rl_begin_undo_group ();
133315b117eaSkettenis
133415b117eaSkettenis if (rl_point == rl_end)
133515b117eaSkettenis {
133615b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
133715b117eaSkettenis rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
133815b117eaSkettenis else
133915b117eaSkettenis --rl_point;
134015b117eaSkettenis count = 1;
134115b117eaSkettenis }
134215b117eaSkettenis
134315b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
134415b117eaSkettenis prev_point = rl_point;
134515b117eaSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
134615b117eaSkettenis rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
134715b117eaSkettenis else
134815b117eaSkettenis #endif
134915b117eaSkettenis rl_point--;
135015b117eaSkettenis
135115b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
135215b117eaSkettenis char_length = prev_point - rl_point;
135315b117eaSkettenis dummy = (char *)xmalloc (char_length + 1);
135415b117eaSkettenis for (i = 0; i < char_length; i++)
135515b117eaSkettenis dummy[i] = rl_line_buffer[rl_point + i];
135615b117eaSkettenis dummy[i] = '\0';
135715b117eaSkettenis #else
135815b117eaSkettenis dummy[0] = rl_line_buffer[rl_point];
135915b117eaSkettenis dummy[char_length = 1] = '\0';
136015b117eaSkettenis #endif
136115b117eaSkettenis
136215b117eaSkettenis rl_delete_text (rl_point, rl_point + char_length);
136315b117eaSkettenis
136415b117eaSkettenis rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
136515b117eaSkettenis
136615b117eaSkettenis _rl_fix_point (0);
136715b117eaSkettenis rl_insert_text (dummy);
136815b117eaSkettenis rl_end_undo_group ();
136915b117eaSkettenis
137015b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
137115b117eaSkettenis free (dummy);
137215b117eaSkettenis #endif
137315b117eaSkettenis
137415b117eaSkettenis return 0;
137515b117eaSkettenis }
137615b117eaSkettenis
137715b117eaSkettenis /* **************************************************************** */
137815b117eaSkettenis /* */
137915b117eaSkettenis /* Character Searching */
138015b117eaSkettenis /* */
138115b117eaSkettenis /* **************************************************************** */
138215b117eaSkettenis
138315b117eaSkettenis int
138415b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
_rl_char_search_internal(count,dir,smbchar,len)138515b117eaSkettenis _rl_char_search_internal (count, dir, smbchar, len)
138615b117eaSkettenis int count, dir;
138715b117eaSkettenis char *smbchar;
138815b117eaSkettenis int len;
138915b117eaSkettenis #else
139015b117eaSkettenis _rl_char_search_internal (count, dir, schar)
139115b117eaSkettenis int count, dir, schar;
139215b117eaSkettenis #endif
139315b117eaSkettenis {
139415b117eaSkettenis int pos, inc;
139515b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
139615b117eaSkettenis int prepos;
139715b117eaSkettenis #endif
139815b117eaSkettenis
139915b117eaSkettenis pos = rl_point;
140015b117eaSkettenis inc = (dir < 0) ? -1 : 1;
140115b117eaSkettenis while (count)
140215b117eaSkettenis {
140315b117eaSkettenis if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
140415b117eaSkettenis {
140515b117eaSkettenis rl_ding ();
140615b117eaSkettenis return -1;
140715b117eaSkettenis }
140815b117eaSkettenis
140915b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
141015b117eaSkettenis pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
141115b117eaSkettenis : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
141215b117eaSkettenis #else
141315b117eaSkettenis pos += inc;
141415b117eaSkettenis #endif
141515b117eaSkettenis do
141615b117eaSkettenis {
141715b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
141815b117eaSkettenis if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
141915b117eaSkettenis #else
142015b117eaSkettenis if (rl_line_buffer[pos] == schar)
142115b117eaSkettenis #endif
142215b117eaSkettenis {
142315b117eaSkettenis count--;
142415b117eaSkettenis if (dir < 0)
142515b117eaSkettenis rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
142615b117eaSkettenis : pos;
142715b117eaSkettenis else
142815b117eaSkettenis rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
142915b117eaSkettenis : pos;
143015b117eaSkettenis break;
143115b117eaSkettenis }
143215b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
143315b117eaSkettenis prepos = pos;
143415b117eaSkettenis #endif
143515b117eaSkettenis }
143615b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
143715b117eaSkettenis while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
143815b117eaSkettenis : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
143915b117eaSkettenis #else
144015b117eaSkettenis while ((dir < 0) ? pos-- : ++pos < rl_end);
144115b117eaSkettenis #endif
144215b117eaSkettenis }
144315b117eaSkettenis return (0);
144415b117eaSkettenis }
144515b117eaSkettenis
144615b117eaSkettenis /* Search COUNT times for a character read from the current input stream.
144715b117eaSkettenis FDIR is the direction to search if COUNT is non-negative; otherwise
144815b117eaSkettenis the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
144915b117eaSkettenis that there are two separate versions of this function. */
145015b117eaSkettenis #if defined (HANDLE_MULTIBYTE)
145115b117eaSkettenis static int
_rl_char_search(count,fdir,bdir)145215b117eaSkettenis _rl_char_search (count, fdir, bdir)
145315b117eaSkettenis int count, fdir, bdir;
145415b117eaSkettenis {
145515b117eaSkettenis char mbchar[MB_LEN_MAX];
145615b117eaSkettenis int mb_len;
145715b117eaSkettenis
145815b117eaSkettenis mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
145915b117eaSkettenis
146015b117eaSkettenis if (count < 0)
146115b117eaSkettenis return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
146215b117eaSkettenis else
146315b117eaSkettenis return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
146415b117eaSkettenis }
146515b117eaSkettenis #else /* !HANDLE_MULTIBYTE */
146615b117eaSkettenis static int
_rl_char_search(count,fdir,bdir)146715b117eaSkettenis _rl_char_search (count, fdir, bdir)
146815b117eaSkettenis int count, fdir, bdir;
146915b117eaSkettenis {
147015b117eaSkettenis int c;
147115b117eaSkettenis
147215b117eaSkettenis RL_SETSTATE(RL_STATE_MOREINPUT);
147315b117eaSkettenis c = rl_read_key ();
147415b117eaSkettenis RL_UNSETSTATE(RL_STATE_MOREINPUT);
147515b117eaSkettenis
147615b117eaSkettenis if (count < 0)
147715b117eaSkettenis return (_rl_char_search_internal (-count, bdir, c));
147815b117eaSkettenis else
147915b117eaSkettenis return (_rl_char_search_internal (count, fdir, c));
148015b117eaSkettenis }
148115b117eaSkettenis #endif /* !HANDLE_MULTIBYTE */
148215b117eaSkettenis
148315b117eaSkettenis int
rl_char_search(count,key)148415b117eaSkettenis rl_char_search (count, key)
148515b117eaSkettenis int count, key;
148615b117eaSkettenis {
148715b117eaSkettenis return (_rl_char_search (count, FFIND, BFIND));
148815b117eaSkettenis }
148915b117eaSkettenis
149015b117eaSkettenis int
rl_backward_char_search(count,key)149115b117eaSkettenis rl_backward_char_search (count, key)
149215b117eaSkettenis int count, key;
149315b117eaSkettenis {
149415b117eaSkettenis return (_rl_char_search (count, BFIND, FFIND));
149515b117eaSkettenis }
149615b117eaSkettenis
149715b117eaSkettenis /* **************************************************************** */
149815b117eaSkettenis /* */
149915b117eaSkettenis /* The Mark and the Region. */
150015b117eaSkettenis /* */
150115b117eaSkettenis /* **************************************************************** */
150215b117eaSkettenis
150315b117eaSkettenis /* Set the mark at POSITION. */
150415b117eaSkettenis int
_rl_set_mark_at_pos(position)150515b117eaSkettenis _rl_set_mark_at_pos (position)
150615b117eaSkettenis int position;
150715b117eaSkettenis {
150815b117eaSkettenis if (position > rl_end)
150915b117eaSkettenis return -1;
151015b117eaSkettenis
151115b117eaSkettenis rl_mark = position;
151215b117eaSkettenis return 0;
151315b117eaSkettenis }
151415b117eaSkettenis
151515b117eaSkettenis /* A bindable command to set the mark. */
151615b117eaSkettenis int
rl_set_mark(count,key)151715b117eaSkettenis rl_set_mark (count, key)
151815b117eaSkettenis int count, key;
151915b117eaSkettenis {
152015b117eaSkettenis return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
152115b117eaSkettenis }
152215b117eaSkettenis
152315b117eaSkettenis /* Exchange the position of mark and point. */
152415b117eaSkettenis int
rl_exchange_point_and_mark(count,key)152515b117eaSkettenis rl_exchange_point_and_mark (count, key)
152615b117eaSkettenis int count, key;
152715b117eaSkettenis {
152815b117eaSkettenis if (rl_mark > rl_end)
152915b117eaSkettenis rl_mark = -1;
153015b117eaSkettenis
153115b117eaSkettenis if (rl_mark == -1)
153215b117eaSkettenis {
153315b117eaSkettenis rl_ding ();
153415b117eaSkettenis return -1;
153515b117eaSkettenis }
153615b117eaSkettenis else
153715b117eaSkettenis SWAP (rl_point, rl_mark);
153815b117eaSkettenis
153915b117eaSkettenis return 0;
154015b117eaSkettenis }
1541