bash-5.0-beta release

This commit is contained in:
Chet Ramey
2018-09-17 15:10:56 -04:00
parent 9a51695bed
commit 2f5dfe5a18
144 changed files with 27560 additions and 36005 deletions
+2 -1
View File
@@ -2987,7 +2987,8 @@ _rl_update_final (void)
putc (last_line[_rl_screenwidth - 1 + woff], rl_outstream);
}
_rl_vis_botlin = 0;
rl_crlf ();
if (botline_length > 0 || _rl_last_c_pos > 0)
rl_crlf ();
fflush (rl_outstream);
rl_display_fixed++;
}
+19 -3
View File
@@ -403,7 +403,7 @@ to the ``normal'' terminating characters.
Return an array of tokens parsed out of @var{string}, much as the
shell might. The tokens are split on the characters in the
@var{history_word_delimiters} variable,
and shell quoting conventions are obeyed.
and shell quoting conventions are obeyed as described below.
@end deftypefun
@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
@@ -476,8 +476,24 @@ carriage return, and @samp{=}.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, double-quoted words are not scanned for the history expansion
character or the history comment character. The default value is 0.
If non-zero, the history expansion code implements shell-like quoting:
single-quoted words are not scanned for the history expansion
character or the history comment character, and double-quoted words may
have history expansion performed, since single quotes are not special
within double quotes.
The default value is 0.
@end deftypevar
@deftypevar int history_quoting_state
An application may set this variable to indicate that the current line
being expanded is subject to existing quoting. If set to @samp{'}, the
history expansion function will assume that the line is single-quoted and
inhibit expansion until it reads an unquoted closing single quote; if set
to @samp{"}, history expansion will assume the line is double quoted until
it reads an unquoted closing double quote. If set to zero, the default,
the history expansion function will assume the line is not quoted and
treat quote characters within the line as described above.
This is only effective if @var{history_quotes_inhibit_expansion} is set.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function
+14 -4
View File
@@ -262,8 +262,8 @@ fix errors in previous commands quickly.
@ifset BashFeatures
History expansion is performed immediately after a complete line
is read, before the shell breaks it into words, and is performed
on each line individually without taking quoting on previous lines into
account.
on each line individually. Bash attempts to inform the history
expansion functions about quoting still in effect from previous lines.
@end ifset
History expansion takes place in two parts. The first is to determine
@@ -277,9 +277,19 @@ that Bash does, so that several words
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
History expansion implements shell-like quoting conventions:
a backslash can be used to remove the special handling for the next character;
single quotes enclose verbatim sequences of characters, and can be used to
inhibit history expansion;
and characters enclosed within double quotes may be subject to history
expansion, since backslash can escape the history expansion character,
but single quotes may not, since they are not treated specially within
double quotes.
@ifset BashFeatures
Only @samp{\} and @samp{'} may be used to escape the history expansion
character, but the history expansion character is
When using the shell, only @samp{\} and @samp{'} may be used to escape the
history expansion character, but the history expansion character is
also treated as quoted if it immediately precedes the closing double quote
in a double-quoted string.
@end ifset
+5 -1
View File
@@ -846,12 +846,16 @@ Return the function invoked by @var{keyseq} in keymap @var{map}.
If @var{map} is @code{NULL}, the current keymap is used. If @var{type} is
not @code{NULL}, the type of the object is returned in the @code{int} variable
it points to (one of @code{ISFUNC}, @code{ISKMAP}, or @code{ISMACR}).
It takes a "translated" key sequence and should not be used if the key sequence
can include NUL.
@end deftypefun
@deftypefun {rl_command_func_t *} rl_function_of_keyseq_len (const char *keyseq, size_t len Keymap map, int *type)
@deftypefun {rl_command_func_t *} rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type)
Return the function invoked by @var{keyseq} of length @var{len}
in keymap @var{map}. Equivalent to @code{rl_function_of_keyseq} with the
addition of the @var{len} parameter.
It takes a "translated" key sequence and should be used if the key sequence
can include NUL.
@end deftypefun
@deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function)
+29 -15
View File
@@ -475,6 +475,7 @@ The default value is @samp{off}.
If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline
treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when
performing case-insensitive filename matching and completion.
The default value is @samp{off}.
@item completion-prefix-display-length
@vindex completion-prefix-display-length
@@ -802,7 +803,7 @@ Meta-Rubout: backward-kill-word
Control-o: "> output"
@end example
In the above example, @kbd{C-u} is bound to the function
In the example above, @kbd{C-u} is bound to the function
@code{universal-argument},
@kbd{M-DEL} is bound to the function @code{backward-kill-word}, and
@kbd{C-o} is bound to run the macro
@@ -1352,7 +1353,7 @@ This function is intended to be bound to the "bracketed paste" escape
sequence sent by some terminals, and such a binding is assigned by default.
It allows Readline to insert the pasted text as a single unit without treating
each character as if it had been read from the keyboard. The characters
are inserted as if each one was bound to @code{self-insert}) instead of
are inserted as if each one was bound to @code{self-insert} instead of
executing any editing commands.
@item transpose-chars (C-t)
@@ -2019,10 +2020,10 @@ matches were generated.
@item complete
@btindex complete
@example
@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DE] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}]
[-F @var{function}] [-C @var{command}] [-X @var{filterpat}]
@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}] [-G @var{globpat}]
[-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}]
[-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]}
@code{complete -pr [-DE] [@var{name} @dots{}]}
@code{complete -pr [-DEI] [@var{name} @dots{}]}
@end example
Specify how arguments to each @var{name} should be completed.
@@ -2032,16 +2033,24 @@ reused as input.
The @option{-r} option removes a completion specification for
each @var{name}, or, if no @var{name}s are supplied, all
completion specifications.
The @option{-D} option indicates that the remaining options and actions should
The @option{-D} option indicates that other supplied options and actions should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
The @option{-E} option indicates that the remaining options and actions should
The @option{-E} option indicates that other supplied options and actions should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
The @option{-I} option indicates that other supplied options and actions should
apply to completion on the inital non-assignment word on the line, or after a
command delimiter such as @samp{;} or @samp{|}, which is usually command
name completion.
If multiple options are supplied, the @option{-D} option takes precedence
over @option{-E}, and both take precedence over @option{-I}.
If any of @option{-D}, @option{-E}, or @option{-I} are supplied, any other
@var{name} arguments are ignored; these completions only apply to the case
specified by the option.
The process of applying these completion specifications when word completion
is attempted is described above (@pxref{Programmable Completion}). The
@option{-D} option takes precedence over @option{-E}.
is attempted is described above (@pxref{Programmable Completion}).
Other options, if specified, have the following meanings.
The arguments to the @option{-G}, @option{-W}, and @option{-X} options
@@ -2071,7 +2080,7 @@ Perform directory name completion if the compspec generates no matches.
@item filenames
Tell Readline that the compspec generates filenames, so it can perform any
filename-specific processing (like adding a slash to directory names
filename-specific processing (like adding a slash to directory names,
quoting special characters, or suppressing trailing spaces).
This option is intended to be used with shell functions specified
with @option{-F}.
@@ -2226,7 +2235,7 @@ an error occurs adding a completion specification.
@item compopt
@btindex compopt
@example
@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}]
@code{compopt} [-o @var{option}] [-DEI] [+o @var{option}] [@var{name}]
@end example
Modify completion options for each @var{name} according to the
@var{option}s, or for the currently-executing completion if no @var{name}s
@@ -2235,14 +2244,19 @@ If no @var{option}s are given, display the completion options for each
@var{name} or the current completion.
The possible values of @var{option} are those valid for the @code{complete}
builtin described above.
The @option{-D} option indicates that the remaining options should
The @option{-D} option indicates that other supplied options should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
The @option{-E} option indicates that the remaining options should
The @option{-E} option indicates that other supplied options should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
The @option{-I} option indicates that other supplied options should
apply to completion on the inital non-assignment word on the line, or after a
command delimiter such as @samp{;} or @samp{|}, which is usually command
name completion.
The @option{-D} option takes precedence over @option{-E}.
If multiple options are supplied, the @option{-D} option takes precedence
over @option{-E}, and both take precedence over @option{-I}
The return value is true unless an invalid option is supplied, an attempt
is made to modify the options for a @var{name} for which no completion
@@ -2289,7 +2303,7 @@ _comp_cd()
local cur _skipdot _cdpath
local i j k
# Tilde expansion, with side effect of expanding tilde to full pathname
# Tilde expansion, which also expands tilde to full pathname
case "$2" in
\~*) eval cur="$2" ;;
*) cur=$2 ;;
+6 -6
View File
@@ -1,10 +1,10 @@
@ignore
Copyright (C) 1988-2017 Free Software Foundation, Inc.
Copyright (C) 1988-2018 Free Software Foundation, Inc.
@end ignore
@set EDITION 7.0
@set VERSION 7.0
@set UPDATED 28 December 2017
@set UPDATED-MONTH December 2017
@set EDITION 8.0
@set VERSION 8.0
@set UPDATED 6 July 2018
@set UPDATED-MONTH July 2018
@set LASTCHANGE Thu Dec 28 14:44:16 EST 2017
@set LASTCHANGE Fri Jul 6 16:25:22 MDT 2018
+58 -35
View File
@@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
/* Copyright (C) 1989-2018 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -107,6 +107,8 @@ char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
particular history expansion should be performed. */
rl_linebuf_func_t *history_inhibit_expansion_function;
int history_quoting_state = 0;
/* **************************************************************** */
/* */
/* History Expansion */
@@ -961,7 +963,22 @@ history_expand (char *hstring, char **output)
/* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */
for (i = dquote = squote = 0; string[i]; i++)
dquote = history_quoting_state == '"';
squote = history_quoting_state == '\'';
/* If the calling application tells us we are already reading a
single-quoted string, consume the rest of the string right now
and then go on. */
i = 0;
if (squote && history_quotes_inhibit_expansion)
{
hist_string_extract_single_quoted (string, &i, 0);
squote = 0;
if (string[i])
i++;
}
for ( ; string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -1049,7 +1066,29 @@ history_expand (char *hstring, char **output)
}
/* Extract and perform the substitution. */
for (passc = dquote = squote = i = j = 0; i < l; i++)
dquote = history_quoting_state == '"';
squote = history_quoting_state == '\'';
/* If the calling application tells us we are already reading a
single-quoted string, consume the rest of the string right now
and then go on. */
i = j = 0;
if (squote && history_quotes_inhibit_expansion)
{
int c;
hist_string_extract_single_quoted (string, &i, 0);
squote = 0;
for (c = 0; c < i; c++)
ADD_CHAR (string[c]);
if (string[i])
{
ADD_CHAR (string[i]);
i++;
}
}
for (passc = 0; i < l; i++)
{
int qc, tchar = string[i];
@@ -1429,11 +1468,11 @@ history_tokenize_word (const char *string, int ind)
}
}
if (member (string[i], "<>;&|$"))
if (member (string[i], "<>;&|"))
{
int peek = string[i + 1];
if (peek == string[i] && peek != '$')
if (peek == string[i])
{
if (peek == '<' && string[i + 2] == '-')
i++;
@@ -1456,9 +1495,8 @@ history_tokenize_word (const char *string, int ind)
i += 2;
return i;
}
/* XXX - separated out for later -- bash-4.2 */
else if ((peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /*)*/
/* XXX - process substitution -- separated out for later -- bash-4.2 */
else if (peek == '(' && (string[i] == '>' || string[i] == '<')) /*)*/
{
i += 2;
delimopen = '(';
@@ -1466,34 +1504,9 @@ history_tokenize_word (const char *string, int ind)
nestdelim = 1;
goto get_word;
}
#if 0
else if (peek == '\'' && string[i] == '$')
{
i += 2; /* XXX */
return i;
}
#endif
if (string[i] != '$')
{
i++;
return i;
}
}
/* same code also used for $(...)/<(...)/>(...) above */
if (member (string[i], "!@?+*"))
{
int peek = string[i + 1];
if (peek == '(') /*)*/
{
/* Shell extended globbing patterns */
i += 2;
delimopen = '(';
delimiter = ')'; /* XXX - not perfect */
nestdelim = 1;
}
i++;
return i;
}
get_word:
@@ -1538,6 +1551,16 @@ get_word:
continue;
}
/* Command and process substitution; shell extended globbing patterns */
if (nestdelim == 0 && delimiter == 0 && member (string[i], "<>$!@?+*") && string[i+1] == '(') /*)*/
{
i += 2;
delimopen = '(';
delimiter = ')';
nestdelim = 1;
continue;
}
if (delimiter == 0 && (member (string[i], history_word_delimiters)))
break;
+2 -2
View File
@@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
/* Copyright (C) 1989-2018 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -396,7 +396,7 @@ read_history_range (const char *filename, int from, int to)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
if (last_ts == NULL && history_multiline_entries)
if (last_ts == NULL && history_length > 0 && history_multiline_entries)
_hs_append_history_line (history_length - 1, line_start);
else
add_history (line_start);
+2
View File
@@ -261,7 +261,9 @@ extern char *history_word_delimiters;
extern char history_comment_char;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
extern int history_quoting_state;
extern int history_write_timestamps;
+4 -4
View File
@@ -322,7 +322,7 @@ rl_unix_word_rubout (int count, int key)
rl_point--;
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
rl_point--;
rl_point--; /* XXX - multibyte? */
}
rl_kill_text (orig_point, rl_point);
@@ -359,7 +359,7 @@ rl_unix_filename_rubout (int count, int key)
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
rl_point--; /* XXX - multibyte? */
c = rl_line_buffer[rl_point - 1];
}
}
@@ -677,7 +677,7 @@ rl_bracketed_paste_begin (int count, int key)
size_t len, cap;
char *buf;
retval = 1;
retval = 0;
len = 0;
buf = xmalloc (cap = 64);
@@ -708,7 +708,7 @@ rl_bracketed_paste_begin (int count, int key)
if (len == cap)
buf = xrealloc (buf, cap + 1);
buf[len] = '\0';
retval = rl_insert_text (buf);
retval = rl_insert_text (buf) == len ? 0 : 1;
}
xfree (buf);
+59 -3
View File
@@ -75,6 +75,57 @@ int _rl_utf8locale = 0;
#if defined(HANDLE_MULTIBYTE)
/* **************************************************************** */
/* */
/* UTF-8 specific Character Utility Functions */
/* */
/* **************************************************************** */
/* Return the length in bytes of the possibly-multibyte character beginning
at S. Encoding is UTF-8. */
static int
_rl_utf8_mblen (const char *s, size_t n)
{
unsigned char c, c1;
if (s == 0)
return (0); /* no shift states */
if (n <= 0)
return (-1);
c = (unsigned char)*s;
if (c < 0x80)
return (c != 0);
if (c >= 0xc2)
{
c1 = (unsigned char)s[1];
if (c < 0xe0)
{
if (n >= 2 && (s[1] ^ 0x80) < 0x40)
return 2;
}
else if (c < 0xf0)
{
if (n >= 3
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
&& (c >= 0xe1 || c1 >= 0xa0)
&& (c != 0xed || c1 < 0xa0))
return 3;
}
else if (c < 0xf8)
{
if (n >= 4
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
&& (s[3] ^ 0x80) < 0x40
&& (c >= 0xf1 || c1 >= 0x90)
&& (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
return 4;
}
}
/* invalid or incomplete multibyte character */
return -1;
}
static int
_rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero)
{
@@ -228,11 +279,16 @@ _rl_get_char_len (char *src, mbstate_t *ps)
/* Look at no more than MB_CUR_MAX characters */
l = (size_t)strlen (src);
mb_cur_max = MB_CUR_MAX;
tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src))
tmp = (*src != 0) ? 1 : 0;
else
{
mb_cur_max = MB_CUR_MAX;
tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
}
if (tmp == (size_t)(-2))
{
/* shorted to compose multibyte char */
/* too short to compose multibyte char */
if (ps)
memset (ps, 0, sizeof(mbstate_t));
return -2;
+7 -6
View File
@@ -214,6 +214,9 @@ int _rl_eof_char = CTRL ('D');
/* Non-zero makes this the next keystroke to read. */
int rl_pending_input = 0;
/* If non-zero when readline_internal returns, it means we found EOF */
int _rl_eof_found = 0;
/* Pointer to a useful terminal name. */
const char *rl_terminal_name = (const char *)NULL;
@@ -222,7 +225,7 @@ int _rl_horizontal_scroll_mode = 0;
/* Non-zero means to display an asterisk at the starts of history lines
which have been modified. */
int _rl_mark_modified_lines = 0;
int _rl_mark_modified_lines = 0;
/* The style of `bell' notification preferred. This can be set to NO_BELL,
AUDIBLE_BELL, or VISIBLE_BELL. */
@@ -664,11 +667,9 @@ readline_internal_charloop (void)
static char *
readline_internal (void)
{
int eof;
readline_internal_setup ();
eof = readline_internal_charloop ();
return (readline_internal_teardown (eof));
_rl_eof_found = readline_internal_charloop ();
return (readline_internal_teardown (_rl_eof_found));
}
void
@@ -1055,7 +1056,7 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq)
/* We probably shadowed a keymap, so keep going. */
r = _rl_dispatch (ANYOTHERKEY, m);
}
else if (r && map[ANYOTHERKEY].function)
else if (r < 0 && map[ANYOTHERKEY].function)
{
/* We didn't match (r is probably -1), so return something to
tell the caller that it should try ANYOTHERKEY for an
+2 -2
View File
@@ -39,8 +39,8 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0700 /* Readline 7.0 */
#define RL_VERSION_MAJOR 7
#define RL_READLINE_VERSION 0x0800 /* Readline 8.0 */
#define RL_VERSION_MAJOR 8
#define RL_VERSION_MINOR 0
/* Readline data structures. */
+2
View File
@@ -173,6 +173,8 @@ _rl_wcwidth (wc)
#endif
#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0)
#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0)
#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80)
#else /* !HANDLE_MULTIBYTE */
+2
View File
@@ -382,6 +382,7 @@ extern void _rl_set_cursor PARAMS((int, int));
extern void _rl_fix_point PARAMS((int));
extern int _rl_replace_text PARAMS((const char *, int, int));
extern int _rl_forward_char_internal PARAMS((int));
extern int _rl_backward_char_internal PARAMS((int));
extern int _rl_insert_char PARAMS((int, int));
extern int _rl_overwrite_char PARAMS((int, int));
extern int _rl_overwrite_rubout PARAMS((int, int));
@@ -511,6 +512,7 @@ extern FILE *_rl_in_stream;
extern FILE *_rl_out_stream;
extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern int _rl_eof_found;
extern procenv_t _rl_top_level;
extern _rl_keyseq_cxt *_rl_kscxt;
extern int _rl_keyseq_timeout;
+5 -1
View File
@@ -691,7 +691,11 @@ rl_deprep_terminal (void)
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (terminal_prepped & TPX_BRACKPASTE)
fprintf (rl_outstream, BRACK_PASTE_FINI);
{
fprintf (rl_outstream, BRACK_PASTE_FINI);
if (_rl_eof_found)
fprintf (rl_outstream, "\n");
}
if (_rl_enable_keypad)
_rl_control_keypad (0);
+30 -3
View File
@@ -297,13 +297,40 @@ _rl_forward_char_internal (int count)
#endif
if (rl_end < 0)
rl_end = 0;
rl_end = 0;
#else
point = rl_point + count;
if (point > rl_end)
point = rl_end;
#endif
if (point > rl_end)
point = rl_end;
return (point);
}
int
_rl_backward_char_internal (int count)
{
int point;
point = rl_point;
#if defined (HANDLE_MULTIBYTE)
if (count > 0)
{
while (count > 0 && point > 0)
{
point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
count--;
}
if (count > 0)
return 0; /* XXX - rl_ding() here? */
}
#else
if (count > 0)
point -= count;
#endif
if (point < 0)
point = 0;
return (point);
}
+168 -74
View File
@@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
/* Copyright (C) 1987-2018 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -63,6 +63,19 @@
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif
/* Increment START to the next character in RL_LINE_BUFFER, handling multibyte chars */
#if defined (HANDLE_MULTIBYTE)
#define INCREMENT_POS(start) \
do { \
if (MB_CUR_MAX == 1 || rl_byte_oriented) \
start++; \
else \
start = _rl_find_next_mbchar (rl_line_buffer, start, 1, MB_FIND_ANY); \
} while (0)
#else /* !HANDLE_MULTIBYTE */
#define INCREMENT_POS(start) (start)++
#endif /* !HANDLE_MULTIBYTE */
/* This is global so other parts of the code can check whether the last
command was a text modification command. */
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
@@ -118,7 +131,7 @@ static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
static void vi_save_insert_buffer PARAMS ((int, int));
static void _rl_vi_backup PARAMS((void));
static inline void _rl_vi_backup PARAMS((void));
static int _rl_vi_arg_dispatch PARAMS((int));
static int rl_digit_loop1 PARAMS((void));
@@ -126,6 +139,9 @@ static int rl_digit_loop1 PARAMS((void));
static int _rl_vi_set_mark PARAMS((void));
static int _rl_vi_goto_mark PARAMS((void));
static inline int _rl_vi_advance_point PARAMS((void));
static inline int _rl_vi_backup_point PARAMS((void));
static void _rl_vi_append_forward PARAMS((int));
static int _rl_vi_callback_getchar PARAMS((char *, int));
@@ -383,7 +399,7 @@ rl_vi_complete (int ignore, int key)
{
if (!whitespace (rl_line_buffer[rl_point + 1]))
rl_vi_end_word (1, 'E');
rl_point++;
_rl_vi_advance_point ();
}
if (key == '*')
@@ -451,6 +467,69 @@ rl_vi_next_word (int count, int key)
return (0);
}
static inline int
_rl_vi_advance_point (void)
{
int point;
point = rl_point;
if (rl_point < rl_end)
#if defined (HANDLE_MULTIBYTE)
{
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
{
point = rl_point;
rl_point = _rl_forward_char_internal (1);
if (point == rl_point || rl_point > rl_end)
rl_point = rl_end;
}
}
#else
rl_point++;
#endif
return point;
}
/* Move the cursor back one character. */
static inline void
_rl_vi_backup (void)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
}
/* Move the point back one character, returning the starting value and not
doing anything at the beginning of the line */
static inline int
_rl_vi_backup_point (void)
{
int point;
point = rl_point;
if (rl_point > 0)
#if defined (HANDLE_MULTIBYTE)
{
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point--;
else
{
point = rl_point;
rl_point = _rl_backward_char_internal (1);
if (rl_point < 0)
rl_point = 0; /* XXX - not really necessary */
}
}
#else
rl_point--;
#endif
return point;
}
/* Move to the end of the ?next? word. */
int
rl_vi_end_word (int count, int key)
@@ -476,11 +555,11 @@ rl_vi_fWord (int count, int ignore)
{
/* Skip until whitespace. */
while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
_rl_vi_advance_point ();
/* Now skip whitespace. */
while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
_rl_vi_advance_point ();
}
return (0);
}
@@ -497,12 +576,18 @@ rl_vi_bWord (int count, int ignore)
rl_point--;
while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
rl_point--;
_rl_vi_backup_point ();
if (rl_point > 0)
{
while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
rl_point++;
do
_rl_vi_backup_point ();
while (rl_point > 0 && !whitespace (rl_line_buffer[rl_point]));
if (rl_point > 0) /* hit whitespace */
rl_point++;
if (rl_point < 0)
rl_point = 0;
}
}
return (0);
@@ -511,28 +596,32 @@ rl_vi_bWord (int count, int ignore)
int
rl_vi_eWord (int count, int ignore)
{
int opoint;
while (count-- && rl_point < (rl_end - 1))
{
if (!whitespace (rl_line_buffer[rl_point]))
rl_point++;
if (whitespace (rl_line_buffer[rl_point]) == 0)
_rl_vi_advance_point ();
/* Move to the next non-whitespace character (to the start of the
next word). */
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
_rl_vi_advance_point ();
if (rl_point && rl_point < rl_end)
{
opoint = rl_point;
/* Skip whitespace. */
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
opoint = _rl_vi_advance_point (); /* XXX - why? */
/* Skip until whitespace. */
while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
rl_point++;
opoint = _rl_vi_advance_point ();
/* Move back to the last character of the word. */
rl_point--;
rl_point = opoint;
}
}
return (0);
@@ -541,24 +630,28 @@ rl_vi_eWord (int count, int ignore)
int
rl_vi_fword (int count, int ignore)
{
int opoint;
while (count-- && rl_point < (rl_end - 1))
{
/* Move to white space (really non-identifer). */
if (_rl_isident (rl_line_buffer[rl_point]))
{
while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
_rl_vi_advance_point ();
}
else /* if (!whitespace (rl_line_buffer[rl_point])) */
{
while (!_rl_isident (rl_line_buffer[rl_point]) &&
!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
_rl_vi_advance_point ();
}
opoint = rl_point;
/* Move past whitespace. */
while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
opoint = _rl_vi_advance_point ();
}
return (0);
}
@@ -566,9 +659,11 @@ rl_vi_fword (int count, int ignore)
int
rl_vi_bword (int count, int ignore)
{
int opoint;
while (count-- && rl_point > 0)
{
int last_is_ident;
int prev_is_ident, cur_is_ident;
/* If we are at the start of a word, move back to whitespace
so we will go back to the start of the previous word. */
@@ -581,22 +676,35 @@ rl_vi_bword (int count, int ignore)
back so we don't get messed up by the rl_point++ down there in
the while loop. Without this code, words like `l;' screw up the
function. */
last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
(!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
rl_point--;
cur_is_ident = _rl_isident (rl_line_buffer[rl_point]);
opoint = _rl_vi_backup_point ();
prev_is_ident = _rl_isident (rl_line_buffer[rl_point]);
if ((cur_is_ident && !prev_is_ident) || (!cur_is_ident && prev_is_ident))
; /* leave point alone, we backed it up one character */
else
rl_point = opoint;
while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
rl_point--;
_rl_vi_backup_point ();
if (rl_point > 0)
{
opoint = rl_point;
if (_rl_isident (rl_line_buffer[rl_point]))
while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
do
opoint = _rl_vi_backup_point ();
while (rl_point > 0 && _rl_isident (rl_line_buffer[rl_point]));
else
while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
do
opoint = _rl_vi_backup_point ();
while (rl_point > 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
!whitespace (rl_line_buffer[rl_point]));
rl_point++;
if (rl_point > 0)
rl_point = opoint;
if (rl_point < 0)
rl_point = 0;
}
}
return (0);
@@ -605,23 +713,34 @@ rl_vi_bword (int count, int ignore)
int
rl_vi_eword (int count, int ignore)
{
while (count-- && rl_point < rl_end - 1)
int opoint;
while (count-- && rl_point < (rl_end - 1))
{
if (!whitespace (rl_line_buffer[rl_point]))
rl_point++;
if (whitespace (rl_line_buffer[rl_point]) == 0)
_rl_vi_advance_point ();
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
_rl_vi_advance_point ();
opoint = rl_point;
if (rl_point < rl_end)
{
if (_rl_isident (rl_line_buffer[rl_point]))
while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
do
{
opoint = _rl_vi_advance_point ();
}
while (rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
else
while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
do
{
opoint = _rl_vi_advance_point ();
}
while (rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
&& !whitespace (rl_line_buffer[rl_point]));
}
rl_point--;
rl_point = opoint;
}
return (0);
}
@@ -637,20 +756,7 @@ rl_vi_insert_beg (int count, int key)
static void
_rl_vi_append_forward (int key)
{
int point;
if (rl_point < rl_end)
{
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
{
point = rl_point;
rl_point = _rl_forward_char_internal (1);
if (point == rl_point)
rl_point = rl_end;
}
}
_rl_vi_advance_point ();
}
int
@@ -859,7 +965,7 @@ _rl_vi_change_mbchar_case (int count)
rl_begin_undo_group ();
rl_vi_delete (1, 0);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++; /* XXX - should we advance more than 1 for mbchar? */
_rl_vi_advance_point ();
rl_insert_text (mb);
rl_end_undo_group ();
rl_vi_check ();
@@ -931,27 +1037,12 @@ rl_vi_put (int count, int key)
return (0);
}
/* Move the cursor back one character. */
static void
_rl_vi_backup (void)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
}
/* Move the cursor back one character if you're at the end of the line */
int
rl_vi_check (void)
{
if (rl_point && rl_point == rl_end)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
}
_rl_vi_backup ();
return (0);
}
@@ -962,7 +1053,10 @@ rl_vi_column (int count, int key)
if (count > rl_end)
rl_end_of_line (1, key);
else
rl_point = count - 1;
{
rl_point = 0;
rl_point = _rl_forward_char_internal (count - 1);
}
return (0);
}
@@ -1113,7 +1207,7 @@ _rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m)
non-whitespace character, move back one (presumably to whitespace). */
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
!whitespace (rl_line_buffer[rl_point]))
rl_point--;
rl_point--; /* XXX */
/* If cw or cW, back up to the end of a word, so the behaviour of ce
or cE is the actual result. Brute-force, no subtlety. */
@@ -1126,14 +1220,14 @@ _rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m)
/* Posix.2 says that if cw or cW moves the cursor towards the end of
the line, the character under the cursor should be deleted. */
if (rl_point == rl_mark)
rl_point++;
_rl_vi_advance_point ();
else
{
/* Move past the end of the word so that the kill doesn't
remove the last letter of the previous word. Only do this
if we are not at the end of the line. */
if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
rl_point++;
_rl_vi_advance_point ();
}
}
@@ -1271,7 +1365,7 @@ vi_delete_dispatch (_rl_vimotion_cxt *m)
mark. */
if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
INCREMENT_POS (rl_mark);
rl_kill_text (rl_point, rl_mark);
return (0);
@@ -1334,7 +1428,7 @@ vi_change_dispatch (_rl_vimotion_cxt *m)
and already leave the mark at the correct location. */
if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
INCREMENT_POS (rl_mark);
/* The cursor never moves with c[wW]. */
if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
@@ -1421,7 +1515,7 @@ vi_yank_dispatch (_rl_vimotion_cxt *m)
mark. */
if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
INCREMENT_POS (rl_mark);
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
@@ -1611,8 +1705,8 @@ rl_vi_unix_word_rubout (int count, int key)
while (rl_point && vi_unix_word_boundary (rl_line_buffer[rl_point - 1]))
rl_point--;
else if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0)
while (rl_point && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0))
rl_point--;
while (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0))
_rl_vi_backup_point ();
}
rl_kill_text (orig_point, rl_point);
@@ -2100,7 +2194,7 @@ rl_vi_possible_completions (void)
{
while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
rl_line_buffer[rl_point] != ';')
rl_point++;
_rl_vi_advance_point ();
}
else if (rl_line_buffer[rl_point - 1] == ';')
{