Bash-4.4 distribution sources and documentation

This commit is contained in:
Chet Ramey 2016-09-15 16:59:08 -04:00
commit a0c0a00fc4
588 changed files with 130746 additions and 80164 deletions

View file

@ -28,7 +28,7 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
srcdir = @srcdir@
VPATH = .:@srcdir@
VPATH = @srcdir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
@ -52,8 +52,10 @@ SHELL = @MAKE_SHELL@
ETAGS = etags -tw
CTAGS = ctags -tw
DEBUG = @DEBUG@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
@ -175,7 +177,8 @@ bind.o: history.h rlstdc.h
callback.o: rlconf.h ansi_stdlib.h
callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
compat.o: rlstdc.h
compat.o: ${BUILD_DIR}/config.h
compat.o: rlstdc.h rltypedefs.h
complete.o: ansi_stdlib.h posixdir.h posixstat.h
complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
@ -237,6 +240,7 @@ readline.o: posixstat.h ansi_stdlib.h posixjmp.h
rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
rltty.o: rltty.h
rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
savestring.o: ${BUILD_DIR}/config.h
search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
search.o: ansi_stdlib.h history.h rlstdc.h

View file

@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -74,8 +74,13 @@ Keymap rl_binding_keymap;
static int _rl_skip_to_delim PARAMS((char *, int, int));
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
static void _rl_init_file_error ();
#endif
static char *_rl_read_file PARAMS((char *, size_t *));
static void _rl_init_file_error PARAMS((const char *));
static int _rl_read_init_file PARAMS((const char *, int));
static int glean_key_from_name PARAMS((char *));
@ -117,6 +122,9 @@ rl_bind_key (key, function)
int key;
rl_command_func_t *function;
{
char keyseq[3];
int l;
if (key < 0)
return (key);
@ -135,8 +143,24 @@ rl_bind_key (key, function)
return (key);
}
_rl_keymap[key].type = ISFUNC;
_rl_keymap[key].function = function;
/* If it's bound to a function or macro, just overwrite. Otherwise we have
to treat it as a key sequence so rl_generic_bind handles shadow keymaps
for us. If we are binding '\' make sure to escape it so it makes it
through the call to rl_translate_keyseq. */
if (_rl_keymap[key].type != ISKMAP)
{
_rl_keymap[key].type = ISFUNC;
_rl_keymap[key].function = function;
}
else
{
l = 0;
if (key == '\\')
keyseq[l++] = '\\';
keyseq[l++] = key;
keyseq[l] = '\0';
rl_bind_keyseq (keyseq, function);
}
rl_binding_keymap = _rl_keymap;
return (0);
}
@ -542,7 +566,7 @@ rl_translate_keyseq (seq, array, len)
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
i++;
for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
c = (c * 8) + OCTVALUE (seq[i]);
i--; /* auto-increment in for loop */
array[l++] = c & largest_char;
@ -970,14 +994,35 @@ _rl_read_init_file (filename, include_level)
}
static void
_rl_init_file_error (msg)
const char *msg;
#if defined (PREFER_STDARG)
_rl_init_file_error (const char *format, ...)
#else
_rl_init_file_error (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
if (currently_reading_init_file)
_rl_errmsg ("%s: line %d: %s\n", current_readline_init_file,
current_readline_init_lineno, msg);
else
_rl_errmsg ("%s", msg);
fprintf (stderr, "%s: line %d: ", current_readline_init_file,
current_readline_init_lineno);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
}
/* **************************************************************** */
@ -1197,7 +1242,7 @@ handle_parser_directive (statement)
}
/* display an error message about the unknown parser directive */
_rl_init_file_error ("unknown parser directive");
_rl_init_file_error ("%s: unknown parser directive", directive);
return (1);
}
@ -1243,7 +1288,7 @@ rl_parse_and_bind (string)
{
char *funname, *kname;
register int c, i;
int key, equivalency;
int key, equivalency, foundmod, foundsep;
while (string && whitespace (*string))
string++;
@ -1273,7 +1318,7 @@ rl_parse_and_bind (string)
/* If we didn't find a closing quote, abort the line. */
if (string[i] == '\0')
{
_rl_init_file_error ("no closing `\"' in key binding");
_rl_init_file_error ("%s: no closing `\"' in key binding", string);
return 1;
}
else
@ -1285,6 +1330,8 @@ rl_parse_and_bind (string)
equivalency = (c == ':' && string[i + 1] == '=');
foundsep = c != 0;
/* Mark the end of the command (or keyname). */
if (string[i])
string[i++] = '\0';
@ -1374,6 +1421,12 @@ remove_trailing:
return 0;
}
if (foundsep == 0)
{
_rl_init_file_error ("%s: no key sequence terminator", string);
return 1;
}
/* If this is a new-style key-binding, then do the binding with
rl_bind_keyseq (). Otherwise, let the older code deal with it. */
if (*string == '"')
@ -1430,11 +1483,24 @@ remove_trailing:
key = glean_key_from_name (kname);
/* Add in control and meta bits. */
foundmod = 0;
if (substring_member_of_array (string, _rl_possible_control_prefixes))
key = CTRL (_rl_to_upper (key));
{
key = CTRL (_rl_to_upper (key));
foundmod = 1;
}
if (substring_member_of_array (string, _rl_possible_meta_prefixes))
key = META (key);
{
key = META (key);
foundmod = 1;
}
if (foundmod == 0 && kname != string)
{
_rl_init_file_error ("%s: unknown key modifier", string);
return 1;
}
/* Temporary. Handle old-style keyname with macro-binding. */
if (*funname == '\'' || *funname == '"')
@ -1461,6 +1527,7 @@ remove_trailing:
#endif /* PREFIX_META_HACK */
else
rl_bind_key (key, rl_named_function (funname));
return 0;
}
@ -1479,6 +1546,7 @@ static const struct {
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
#if defined (COLOR_SUPPORT)
{ "colored-completion-prefix",&_rl_colored_completion_prefix, 0 },
{ "colored-stats", &_rl_colored_stats, 0 },
#endif
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
@ -1486,6 +1554,7 @@ static const struct {
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
{ "enable-bracketed-paste", &_rl_enable_bracketed_paste, 0 },
{ "enable-keypad", &_rl_enable_keypad, 0 },
{ "enable-meta-key", &_rl_enable_meta, 0 },
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
@ -1569,10 +1638,13 @@ static int sv_dispprefix PARAMS((const char *));
static int sv_compquery PARAMS((const char *));
static int sv_compwidth PARAMS((const char *));
static int sv_editmode PARAMS((const char *));
static int sv_emacs_modestr PARAMS((const char *));
static int sv_histsize PARAMS((const char *));
static int sv_isrchterm PARAMS((const char *));
static int sv_keymap PARAMS((const char *));
static int sv_seqtimeout PARAMS((const char *));
static int sv_viins_modestr PARAMS((const char *));
static int sv_vicmd_modestr PARAMS((const char *));
static const struct {
const char * const name;
@ -1585,10 +1657,13 @@ static const struct {
{ "completion-prefix-display-length", V_INT, sv_dispprefix },
{ "completion-query-items", V_INT, sv_compquery },
{ "editing-mode", V_STRING, sv_editmode },
{ "emacs-mode-string", V_STRING, sv_emacs_modestr },
{ "history-size", V_INT, sv_histsize },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
{ "keyseq-timeout", V_INT, sv_seqtimeout },
{ "vi-cmd-mode-string", V_STRING, sv_vicmd_modestr },
{ "vi-ins-mode-string", V_STRING, sv_viins_modestr },
{ (char *)NULL, 0, (_rl_sv_func_t *)0 }
};
@ -1605,7 +1680,7 @@ find_string_var (name)
}
/* A boolean value that can appear in a `set variable' command is true if
the value is null or empty, `on' (case-insenstive), or "1". Any other
the value is null or empty, `on' (case-insensitive), or "1". Any other
values result in 0 (false). */
static int
bool_to_int (value)
@ -1654,10 +1729,14 @@ rl_variable_bind (name, value)
i = find_string_var (name);
/* For the time being, unknown variable names or string names without a
handler function are simply ignored. */
/* For the time being, string names without a handler function are simply
ignored. */
if (i < 0 || string_varlist[i].set_func == 0)
return 0;
{
if (i < 0)
_rl_init_file_error ("%s: unknown variable name", name);
return 0;
}
v = (*string_varlist[i].set_func) (value);
return v;
@ -1832,7 +1911,7 @@ sv_isrchterm (value)
}
else
{
for (beg = end = 0; whitespace (v[end]) == 0; end++)
for (beg = end = 0; v[end] && whitespace (v[end]) == 0; end++)
;
}
@ -1846,7 +1925,96 @@ sv_isrchterm (value)
xfree (v);
return 0;
}
extern char *_rl_emacs_mode_str;
static int
sv_emacs_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_emacs_mode_str, &_rl_emacs_modestr_len);
_rl_emacs_mode_str[_rl_emacs_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = (char *)xmalloc (1);
_rl_emacs_mode_str[_rl_emacs_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_emacs_mode_str);
_rl_emacs_mode_str = 0; /* prompt_modestr does the right thing */
_rl_emacs_modestr_len = 0;
return 0;
}
return 1;
}
static int
sv_viins_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_vi_ins_mode_str, &_rl_vi_ins_modestr_len);
_rl_vi_ins_mode_str[_rl_vi_ins_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = (char *)xmalloc (1);
_rl_vi_ins_mode_str[_rl_vi_ins_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_vi_ins_mode_str);
_rl_vi_ins_mode_str = 0; /* prompt_modestr does the right thing */
_rl_vi_ins_modestr_len = 0;
return 0;
}
return 1;
}
static int
sv_vicmd_modestr (value)
const char *value;
{
if (value && *value)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_vi_cmd_mode_str, &_rl_vi_cmd_modestr_len);
_rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len] = '\0';
return 0;
}
else if (value)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = (char *)xmalloc (1);
_rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len = 0] = '\0';
return 0;
}
else if (value == 0)
{
FREE (_rl_vi_cmd_mode_str);
_rl_vi_cmd_mode_str = 0; /* prompt_modestr does the right thing */
_rl_vi_cmd_modestr_len = 0;
return 0;
}
return 1;
}
/* Return the character which matches NAME.
For example, `Space' returns ' '. */
@ -2420,6 +2588,12 @@ _rl_get_string_variable_value (name)
sprintf (numbuf, "%d", _rl_keyseq_timeout);
return (numbuf);
}
else if (_rl_stricmp (name, "emacs-mode-string") == 0)
return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT);
else if (_rl_stricmp (name, "vi-cmd-mode-string") == 0)
return (_rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT);
else if (_rl_stricmp (name, "vi-ins-mode-string") == 0)
return (_rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT);
else
return (0);
}

View file

@ -1,6 +1,6 @@
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -50,6 +50,14 @@
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* Applications can set this to non-zero to have readline's signal handlers
installed during the entire duration of reading a complete line, as in
readline-6.2. This should be used with care, because it can result in
readline receiving signals and not handling them until it's called again
via rl_callback_read_char, thereby stealing them from the application.
By default, signal handlers are only active while readline is active. */
int rl_persistent_signal_handlers = 0;
/* **************************************************************** */
/* */
/* Callback Readline Functions */
@ -82,6 +90,11 @@ _rl_callback_newline ()
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
if (rl_persistent_signal_handlers)
rl_set_signals ();
#endif
}
readline_internal_setup ();
@ -103,7 +116,8 @@ rl_callback_handler_install (prompt, linefunc)
#if defined (HANDLE_SIGNALS)
#define CALLBACK_READ_RETURN() \
do { \
rl_clear_signals (); \
if (rl_persistent_signal_handlers == 0) \
rl_clear_signals (); \
return; \
} while (0)
#else
@ -140,7 +154,8 @@ rl_callback_read_char ()
#if defined (HANDLE_SIGNALS)
/* Install signal handlers only when readline has control. */
rl_set_signals ();
if (rl_persistent_signal_handlers == 0)
rl_set_signals ();
#endif
do
@ -161,6 +176,36 @@ rl_callback_read_char ()
CALLBACK_READ_RETURN ();
}
#if defined (VI_MODE)
/* States that can occur while in state VIMOTION have to be checked
before RL_STATE_VIMOTION */
else if (RL_ISSTATE (RL_STATE_CHARSEARCH))
{
int k;
k = _rl_callback_data->i2;
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is
cleaned up. */
if (_rl_callback_func == 0) /* XXX - just sanity check */
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
}
/* Messy case where vi motion command can be char search */
if (RL_ISSTATE (RL_STATE_VIMOTION))
{
_rl_vi_domove_motion_cleanup (k, _rl_vimvcxt);
_rl_internal_char_cleanup ();
CALLBACK_READ_RETURN ();
}
_rl_internal_char_cleanup ();
}
else if (RL_ISSTATE (RL_STATE_VIMOTION))
{
eof = _rl_vi_domove_callback (_rl_vimvcxt);
@ -284,10 +329,36 @@ _rl_callback_data_alloc (count)
return arg;
}
void _rl_callback_data_dispose (arg)
void
_rl_callback_data_dispose (arg)
_rl_callback_generic_arg *arg;
{
xfree (arg);
}
/* Make sure that this agrees with cases in rl_callback_read_char */
void
rl_callback_sigcleanup ()
{
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
return;
if (RL_ISSTATE (RL_STATE_ISEARCH))
_rl_isearch_cleanup (_rl_iscxt, 0);
else if (RL_ISSTATE (RL_STATE_NSEARCH))
_rl_nsearch_cleanup (_rl_nscxt, 0);
else if (RL_ISSTATE (RL_STATE_VIMOTION))
RL_UNSETSTATE (RL_STATE_VIMOTION);
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
_rl_argcxt = 0;
RL_UNSETSTATE (RL_STATE_NUMERICARG);
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
RL_UNSETSTATE (RL_STATE_MULTIKEY);
if (RL_ISSTATE (RL_STATE_CHARSEARCH))
RL_UNSETSTATE (RL_STATE_CHARSEARCH);
_rl_callback_func = 0;
}
#endif

View file

@ -1,6 +1,6 @@
/* chardefs.h -- Character definitions for readline. */
/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
/* Copyright (C) 1994-2015 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.
@ -73,7 +73,7 @@
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus)
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
# define isxdigit(c) (isdigit((unsigned char)(c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#if defined (CTYPE_NON_ASCII)
@ -87,13 +87,13 @@
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c))
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))

View file

@ -2,8 +2,8 @@
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation,
Inc.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -98,9 +98,29 @@ _rl_set_normal_color (void)
}
}
bool
_rl_print_prefix_color (void)
{
struct bin_str *s;
/* What do we want to use for the prefix? Let's try cyan first, see colors.h */
s = &_rl_color_indicator[C_PREFIX];
if (s->string != NULL)
{
if (is_colored (C_NORM))
restore_default_color ();
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (s);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
return 0;
}
else
return 1;
}
/* Returns whether any color sequence was printed. */
bool
_rl_print_color_indicator (char *f)
_rl_print_color_indicator (const char *f)
{
enum indicator_no colored_filetype;
COLOR_EXT_TYPE *ext; /* Color extension */
@ -108,10 +128,9 @@ _rl_print_color_indicator (char *f)
const char* name;
char *filename;
struct stat astat;
struct stat astat, linkstat;
mode_t mode;
int linkok;
int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */
int stat_ok;
name = f;
@ -130,10 +149,20 @@ _rl_print_color_indicator (char *f)
#else
stat_ok = stat(name, &astat);
#endif
if( stat_ok == 0 ) {
mode = astat.st_mode;
linkok = 1; //f->linkok;
}
if (stat_ok == 0)
{
mode = astat.st_mode;
#if defined (HAVE_LSTAT)
if (S_ISLNK (mode))
{
linkok = stat (name, &linkstat) == 0;
if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0)
mode = linkstat.st_mode;
}
else
#endif
linkok = 1;
}
else
linkok = -1;
@ -141,6 +170,8 @@ _rl_print_color_indicator (char *f)
if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
colored_filetype = C_MISSING;
else if (linkok == 0 && S_ISLNK(mode) && _rl_color_indicator[C_ORPHAN].string != NULL)
colored_filetype = C_ORPHAN; /* dangling symlink */
else if(stat_ok != 0)
{
static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
@ -181,10 +212,7 @@ _rl_print_color_indicator (char *f)
#endif
}
else if (S_ISLNK (mode))
colored_filetype = ((linkok == 0
&& (!strncmp (_rl_color_indicator[C_LINK].string, "target", 6)
|| _rl_color_indicator[C_ORPHAN].string))
? C_ORPHAN : C_LINK);
colored_filetype = C_LINK;
else if (S_ISFIFO (mode))
colored_filetype = C_FIFO;
else if (S_ISSOCK (mode))

View file

@ -2,8 +2,8 @@
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation,
Inc.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -114,9 +114,13 @@ enum filetype
arg_directory
};
/* Prefix color, currently same as socket */
#define C_PREFIX C_SOCK
extern void _rl_put_indicator (const struct bin_str *ind);
extern void _rl_set_normal_color (void);
extern bool _rl_print_color_indicator (char *f);
extern bool _rl_print_prefix_color (void);
extern bool _rl_print_color_indicator (const char *f);
extern void _rl_prep_non_filename_text (void);
#endif /* !_COLORS_H_ */

View file

@ -1,6 +1,6 @@
/* complete.c -- filename completion for readline. */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -111,8 +111,10 @@ static int stat_char PARAMS((char *));
#endif
#if defined (COLOR_SUPPORT)
static int colored_stat_start PARAMS((char *));
static int colored_stat_start PARAMS((const char *));
static void colored_stat_end PARAMS((void));
static int colored_prefix_start PARAMS((void));
static void colored_prefix_end PARAMS((void));
#endif
static int path_isdir PARAMS((const char *));
@ -126,7 +128,7 @@ static int get_y_or_n PARAMS((int));
static int _rl_internal_pager PARAMS((int));
static char *printable_part PARAMS((char *));
static int fnwidth PARAMS((const char *));
static int fnprint PARAMS((const char *, int));
static int fnprint PARAMS((const char *, int, const char *));
static int print_filename PARAMS((char *, char *, int));
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
@ -172,7 +174,7 @@ int _rl_complete_mark_symlink_dirs = 0;
int _rl_print_completions_horizontally;
/* Non-zero means that case is not significant in filename completion. */
#if defined (__MSDOS__) && !defined (__DJGPP__)
#if (defined (__MSDOS__) && !defined (__DJGPP__)) || (defined (_WIN32) && !defined (__CYGWIN__))
int _rl_completion_case_fold = 1;
#else
int _rl_completion_case_fold = 0;
@ -209,6 +211,10 @@ int rl_visible_stats = 0;
/* Non-zero means to use colors to indicate file type when listing possible
completions. The colors used are taken from $LS_COLORS, if set. */
int _rl_colored_stats = 0;
/* Non-zero means to use a color (currently magenta) to indicate the common
prefix of a set of possible word completions. */
int _rl_colored_completion_prefix = 0;
#endif
/* If non-zero, when completing in the middle of a word, don't insert
@ -404,6 +410,8 @@ static int completion_changed_buffer;
/* The result of the query to the user about displaying completion matches */
static int completion_y_or_n;
static int _rl_complete_display_matches_interrupt = 0;
/*************************************/
/* */
/* Bindable completion functions */
@ -487,7 +495,10 @@ _rl_complete_sigcleanup (sig, ptr)
void *ptr;
{
if (sig == SIGINT) /* XXX - for now */
_rl_free_match_list ((char **)ptr);
{
_rl_free_match_list ((char **)ptr);
_rl_complete_display_matches_interrupt = 1;
}
}
/* Set default values for readline word completion. These are the variables
@ -505,6 +516,9 @@ set_completion_defaults (what_to_do)
/* The completion entry function may optionally change this. */
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
/* Reset private state. */
_rl_complete_display_matches_interrupt = 0;
}
/* The user must press "y" or "n". Non-zero return means "y" pressed. */
@ -638,11 +652,23 @@ stat_char (filename)
#endif
else if (S_ISREG (finfo.st_mode))
{
#if defined (_WIN32) && !defined (__CYGWIN__)
char *ext;
/* Windows doesn't do access and X_OK; check file extension instead */
ext = strrchr (fn, '.');
if (ext && (_rl_stricmp (ext, ".exe") == 0 ||
_rl_stricmp (ext, ".cmd") == 0 ||
_rl_stricmp (ext, ".bat") == 0 ||
_rl_stricmp (ext, ".com") == 0))
character = '*';
#else
if (access (filename, X_OK) == 0)
character = '*';
#endif
}
free (f);
xfree (f);
return (character);
}
#endif /* VISIBLE_STATS */
@ -650,7 +676,7 @@ stat_char (filename)
#if defined (COLOR_SUPPORT)
static int
colored_stat_start (filename)
char *filename;
const char *filename;
{
_rl_set_normal_color ();
return (_rl_print_color_indicator (filename));
@ -662,6 +688,19 @@ colored_stat_end ()
_rl_prep_non_filename_text ();
_rl_put_indicator (&_rl_color_indicator[C_CLR_TO_EOL]);
}
static int
colored_prefix_start ()
{
_rl_set_normal_color ();
return (_rl_print_prefix_color ());
}
static void
colored_prefix_end ()
{
colored_stat_end (); /* for now */
}
#endif
/* Return the portion of PATHNAME that should be output when listing
@ -682,7 +721,7 @@ printable_part (pathname)
return (pathname);
temp = strrchr (pathname, '/');
#if defined (__MSDOS__)
#if defined (__MSDOS__) || defined (_WIN32)
if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
temp = pathname + 1;
#endif
@ -761,12 +800,14 @@ fnwidth (string)
#define ELLIPSIS_LEN 3
static int
fnprint (to_print, prefix_bytes)
fnprint (to_print, prefix_bytes, real_pathname)
const char *to_print;
int prefix_bytes;
const char *real_pathname;
{
int printed_len, w;
const char *s;
int common_prefix_len, print_len;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
const char *end;
@ -774,18 +815,26 @@ fnprint (to_print, prefix_bytes)
int width;
wchar_t wc;
end = to_print + strlen (to_print) + 1;
print_len = strlen (to_print);
end = to_print + print_len + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
printed_len = 0;
printed_len = common_prefix_len = 0;
/* Don't print only the ellipsis if the common prefix is one of the
possible completions */
if (to_print[prefix_bytes] == '\0')
possible completions. Only cut off prefix_bytes if we're going to be
printing the ellipsis, which takes precedence over coloring the
completion prefix (see print_filename() below). */
if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len)
prefix_bytes = 0;
if (prefix_bytes)
#if defined (COLOR_SUPPORT)
if (_rl_colored_stats && (prefix_bytes == 0 || _rl_colored_completion_prefix <= 0))
colored_stat_start (real_pathname);
#endif
if (prefix_bytes && _rl_completion_prefix_display_length > 0)
{
char ellipsis;
@ -794,6 +843,15 @@ fnprint (to_print, prefix_bytes)
putc (ellipsis, rl_outstream);
printed_len = ELLIPSIS_LEN;
}
#if defined (COLOR_SUPPORT)
else if (prefix_bytes && _rl_colored_completion_prefix > 0)
{
common_prefix_len = prefix_bytes;
prefix_bytes = 0;
/* XXX - print color indicator start here */
colored_prefix_start ();
}
#endif
s = to_print + prefix_bytes;
while (*s)
@ -844,8 +902,25 @@ fnprint (to_print, prefix_bytes)
printed_len++;
#endif
}
if (common_prefix_len > 0 && (s - to_print) >= common_prefix_len)
{
#if defined (COLOR_SUPPORT)
/* printed bytes = s - to_print */
/* printed bytes should never be > but check for paranoia's sake */
colored_prefix_end ();
if (_rl_colored_stats)
colored_stat_start (real_pathname); /* XXX - experiment */
#endif
common_prefix_len = 0;
}
}
#if defined (COLOR_SUPPORT)
/* XXX - unconditional for now */
if (_rl_colored_stats)
colored_stat_end ();
#endif
return printed_len;
}
@ -866,7 +941,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
/* Defer printing if we want to prefix with a color indicator */
if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0)
#endif
printed_len = fnprint (to_print, prefix_bytes);
printed_len = fnprint (to_print, prefix_bytes, to_print);
if (rl_filename_completion_desired && (
#if defined (VISIBLE_STATS)
@ -928,20 +1003,17 @@ print_filename (to_print, full_pathname, prefix_bytes)
{
dn = savestring (new_full_pathname);
(*rl_filename_stat_hook) (&dn);
free (new_full_pathname);
xfree (new_full_pathname);
new_full_pathname = dn;
}
if (path_isdir (new_full_pathname))
extension_char = '/';
}
/* Move colored-stats code inside fnprint() */
#if defined (COLOR_SUPPORT)
if (_rl_colored_stats)
{
colored_stat_start (new_full_pathname);
printed_len = fnprint (to_print, prefix_bytes);
colored_stat_end ();
}
printed_len = fnprint (to_print, prefix_bytes, new_full_pathname);
#endif
xfree (new_full_pathname);
@ -958,15 +1030,11 @@ print_filename (to_print, full_pathname, prefix_bytes)
if (_rl_complete_mark_directories && path_isdir (s))
extension_char = '/';
/* Move colored-stats code inside fnprint() */
#if defined (COLOR_SUPPORT)
if (_rl_colored_stats)
{
colored_stat_start (s);
printed_len = fnprint (to_print, prefix_bytes);
colored_stat_end ();
}
printed_len = fnprint (to_print, prefix_bytes, s);
#endif
}
xfree (s);
@ -1504,15 +1572,29 @@ rl_display_match_list (matches, len, max)
if (_rl_completion_prefix_display_length > 0)
{
t = printable_part (matches[0]);
temp = strrchr (t, '/');
/* check again in case of /usr/src/ */
temp = rl_filename_completion_desired ? strrchr (t, '/') : 0;
common_length = temp ? fnwidth (temp) : fnwidth (t);
sind = temp ? strlen (temp) : strlen (t);
if (common_length > max || sind > max)
common_length = sind = 0;
if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN)
max -= common_length - ELLIPSIS_LEN;
else
common_length = sind = 0;
}
#if defined (COLOR_SUPPORT)
else if (_rl_colored_completion_prefix > 0)
{
t = printable_part (matches[0]);
temp = rl_filename_completion_desired ? strrchr (t, '/') : 0;
common_length = temp ? fnwidth (temp) : fnwidth (t);
sind = temp ? RL_STRLEN (temp+1) : RL_STRLEN (t); /* want portion after final slash */
if (common_length > max || sind > max)
common_length = sind = 0;
}
#endif
/* How many items of MAX length can we fit in the screen window? */
cols = complete_get_screenwidth ();
@ -1559,12 +1641,23 @@ rl_display_match_list (matches, len, max)
printed_len = print_filename (temp, matches[l], sind);
if (j + 1 < limit)
for (k = 0; k < max - printed_len; k++)
putc (' ', rl_outstream);
{
if (max <= printed_len)
putc (' ', rl_outstream);
else
for (k = 0; k < max - printed_len; k++)
putc (' ', rl_outstream);
}
}
l += count;
}
rl_crlf ();
#if defined (SIGWINCH)
if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0)
#else
if (RL_SIG_RECEIVED ())
#endif
return;
lines++;
if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
{
@ -1582,6 +1675,12 @@ rl_display_match_list (matches, len, max)
temp = printable_part (matches[i]);
printed_len = print_filename (temp, matches[i], sind);
/* Have we reached the end of this line? */
#if defined (SIGWINCH)
if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0)
#else
if (RL_SIG_RECEIVED ())
#endif
return;
if (matches[i+1])
{
if (limit == 1 || (i && (limit > 1) && (i % limit) == 0))
@ -1595,6 +1694,8 @@ rl_display_match_list (matches, len, max)
return;
}
}
else if (max <= printed_len)
putc (' ', rl_outstream);
else
for (k = 0; k < max - printed_len; k++)
putc (' ', rl_outstream);
@ -2046,8 +2147,16 @@ rl_complete_internal (what_to_do)
{
_rl_sigcleanup = _rl_complete_sigcleanup;
_rl_sigcleanarg = matches;
_rl_complete_display_matches_interrupt = 0;
}
display_matches (matches);
if (_rl_complete_display_matches_interrupt)
{
matches = 0; /* already freed by rl_complete_sigcleanup */
_rl_complete_display_matches_interrupt = 0;
if (rl_signal_event_hook)
(*rl_signal_event_hook) (); /* XXX */
}
_rl_sigcleanup = 0;
_rl_sigcleanarg = 0;
break;
@ -2073,6 +2182,8 @@ rl_complete_internal (what_to_do)
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
RL_CHECK_SIGNALS ();
return 0;
}
@ -2372,6 +2483,7 @@ rl_filename_completion_function (text, state)
static int filename_len;
char *temp, *dentry, *convfn;
int dirlen, dentlen, convlen;
int tilde_dirname;
struct dirent *entry;
/* If we don't have any state, then do some initialization. */
@ -2395,7 +2507,7 @@ rl_filename_completion_function (text, state)
temp = strrchr (dirname, '/');
#if defined (__MSDOS__)
#if defined (__MSDOS__) || defined (_WIN32)
/* special hack for //X/... */
if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
temp = strrchr (dirname + 3, '/');
@ -2406,7 +2518,7 @@ rl_filename_completion_function (text, state)
strcpy (filename, ++temp);
*temp = '\0';
}
#if defined (__MSDOS__)
#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN__))
/* searches from current directory on the drive */
else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
{
@ -2429,11 +2541,13 @@ rl_filename_completion_function (text, state)
else
users_dirname = savestring (dirname);
tilde_dirname = 0;
if (*dirname == '~')
{
temp = tilde_expand (dirname);
xfree (dirname);
dirname = temp;
tilde_dirname = 1;
}
/* We have saved the possibly-dequoted version of the directory name
@ -2452,7 +2566,7 @@ rl_filename_completion_function (text, state)
xfree (users_dirname);
users_dirname = savestring (dirname);
}
else if (rl_completion_found_quote && rl_filename_dequoting_function)
else if (tilde_dirname == 0 && rl_completion_found_quote && rl_filename_dequoting_function)
{
/* delete single and double quotes */
xfree (dirname);

View file

@ -1,6 +1,6 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -69,6 +69,12 @@ static void delete_chars PARAMS((int));
static void insert_some_chars PARAMS((char *, int, int));
static void open_some_spaces PARAMS((int));
static void cr PARAMS((void));
static void redraw_prompt PARAMS((char *));
/* Values for FLAGS */
#define PMT_MULTILINE 0x01
static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *));
/* State of visible and invisible lines. */
struct line_state
@ -77,8 +83,8 @@ struct line_state
int *lbreaks;
int lbsize;
#if defined (HANDLE_MULTIBYTE)
int *wrapped_line;
int wbsize;
int *wrapped_line;
#endif
};
@ -113,6 +119,8 @@ static int _rl_col_width PARAMS((const char *, int, int, int));
buffer index in others. This macro is used when deciding whether the
current cursor position is in the middle of a prompt string containing
invisible characters. XXX - might need to take `modmark' into account. */
/* XXX - only valid when tested against _rl_last_c_pos; buffer indices need
to use prompt_last_invisible directly. */
#define PROMPT_ENDING_INDEX \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
@ -158,6 +166,16 @@ int _rl_want_redisplay = 0;
This is usually pointing to rl_prompt. */
char *rl_display_prompt = (char *)NULL;
/* Variables used to include the editing mode in the prompt. */
char *_rl_emacs_mode_str;
int _rl_emacs_modestr_len;
char *_rl_vi_ins_mode_str;
int _rl_vi_ins_modestr_len;
char *_rl_vi_cmd_mode_str;
int _rl_vi_cmd_modestr_len;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
@ -176,6 +194,8 @@ static int prompt_multibyte_chars;
/* Number of lines currently on screen minus 1. */
int _rl_vis_botlin = 0;
static int _rl_inv_botlin = 0;
/* Variables used only in this file. */
/* The last left edge of text that was displayed. This is used when
doing horizontal scrolling. It shifts in thirds of a screenwidth. */
@ -239,16 +259,30 @@ static int saved_local_length;
static int saved_invis_chars_first_line;
static int saved_physical_chars;
/* Return a character indicating the editing mode, for use in the prompt. */
static int
prompt_modechar ()
/* Return a string indicating the editing mode, for use in the prompt. */
static char *
prompt_modestr (lenp)
int *lenp;
{
if (rl_editing_mode == emacs_mode)
return '@';
{
if (lenp)
*lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN;
return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT;
}
else if (_rl_keymap == vi_insertion_keymap)
return '+'; /* vi insert mode */
{
if (lenp)
*lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN;
return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */
}
else
return ':'; /* vi command mode */
{
if (lenp)
*lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN;
return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */
}
}
/* Expand the prompt string S and return the number of visible
@ -266,26 +300,37 @@ prompt_modechar ()
the returned string; all characters except those between \001 and
\002 are assumed to be `visible'. */
/* Possible values for FLAGS:
PMT_MULTILINE caller indicates that this is part of a multiline prompt
*/
static char *
expand_prompt (pmt, lp, lip, niflp, vlp)
expand_prompt (pmt, flags, lp, lip, niflp, vlp)
char *pmt;
int flags;
int *lp, *lip, *niflp, *vlp;
{
char *r, *ret, *p, *igstart;
char *r, *ret, *p, *igstart, *nprompt, *ms;
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
int mlen;
/* We only expand the mode string for the last line of a multiline prompt
(a prompt with embedded newlines). */
ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
if (ms)
{
l = strlen (pmt);
nprompt = (char *)xmalloc (l + mlen + 1);
memcpy (nprompt, ms, mlen);
strcpy (nprompt + mlen, pmt);
}
else
nprompt = pmt;
/* Short-circuit if we can. */
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0)
{
if (pmt == rl_prompt && _rl_show_mode_in_prompt)
{
l = strlen (pmt);
r = (char *)xmalloc (l + 2);
r[0] = prompt_modechar ();
strcpy (r + 1, pmt);
}
else
r = savestring (pmt);
r = (nprompt == pmt) ? savestring (pmt) : nprompt;
if (lp)
*lp = strlen (r);
@ -298,21 +343,15 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
return r;
}
l = strlen (pmt);
r = ret = (char *)xmalloc (l + 2);
rl = physchars = 0; /* move up here so mode show can set them */
if (pmt == rl_prompt && _rl_show_mode_in_prompt)
{
*r++ = prompt_modechar ();
rl = physchars = 1;
}
l = strlen (nprompt); /* XXX */
r = ret = (char *)xmalloc (l + 1);
rl = physchars = 0; /* mode string now part of nprompt */
invfl = 0; /* invisible chars in first line of prompt */
invflset = 0; /* we only want to set invfl once */
igstart = 0;
for (ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
@ -334,8 +373,8 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
pind = p - pmt;
ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
pind = p - nprompt;
ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO);
l = ind - pind;
while (l--)
*r++ = *p++;
@ -347,7 +386,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
not be the same as the number of physical characters
on the screen in the presence of multibyte characters */
rl += ind - pind;
physchars += _rl_col_width (pmt, pind, ind, 0);
physchars += _rl_col_width (nprompt, pind, ind, 0);
}
else
ninvis += ind - pind;
@ -386,6 +425,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
*niflp = invfl;
if (vlp)
*vlp = physchars;
if (nprompt != pmt)
free (nprompt);
return ret;
}
@ -397,7 +440,7 @@ _rl_strip_prompt (pmt)
{
char *ret;
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
return ret;
}
@ -444,13 +487,13 @@ rl_expand_prompt (prompt)
return (0);
p = strrchr (prompt, '\n');
if (!p)
if (p == 0)
{
/* The prompt is only one logical line, though it might wrap. */
local_prompt = expand_prompt (prompt, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt = expand_prompt (prompt, 0, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)0;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
return (prompt_visible_length);
@ -459,14 +502,16 @@ rl_expand_prompt (prompt)
{
/* The prompt spans multiple lines. */
t = ++p;
local_prompt = expand_prompt (p, &prompt_visible_length,
local_prompt = expand_prompt (p, PMT_MULTILINE,
&prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE,
&prompt_prefix_length,
(int *)NULL,
(int *)NULL,
(int *)NULL);
@ -539,6 +584,7 @@ rl_redisplay ()
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, n0, num, prompt_lines_estimate;
char *prompt_this_line;
int mb_cur_max = MB_CUR_MAX;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
size_t wc_bytes;
@ -695,6 +741,8 @@ rl_redisplay ()
/* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0;
/* lpos is a physical cursor position, so it needs to be adjusted by the
number of invisible characters in the prompt, per line */
lpos = prompt_physical_chars + modmark;
#if defined (HANDLE_MULTIBYTE)
@ -714,7 +762,17 @@ rl_redisplay ()
contents of the command line? */
while (lpos >= _rl_screenwidth)
{
int z;
int z, p;
int nocorrect, wadjust;
nocorrect = 0;
/* Adjust depending on the invisible characters in the line. We use a
heuristic based on experience: invisible characters nearly always
appear in the first and last lines of the prompt */
wadjust = (newlines == 0)
? prompt_invis_chars_first_line
: ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line);
/* fix from Darin Johnson <darin@acuson.com> for prompt string with
invisible characters that is longer than the screen width. The
prompt_invis_chars_first_line variable could be made into an array
@ -723,20 +781,31 @@ rl_redisplay ()
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
{
nocorrect = 1;
n0 = num;
temp = local_prompt_len;
while (num < temp)
{
z = _rl_col_width (local_prompt, n0, num, 1);
/* This has to take invisible characters in the prompt into
account. */
z = _rl_col_width (local_prompt, n0, num, 1) - wadjust;
if (z > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
break;
}
else if (z == _rl_screenwidth)
break;
{
/* If we are in the middle or at the end of a multibyte
character, we want to move to the start, then find out
where it ends so we know where to insert the newline.
If this isn't a multibyte character, its the same as num++ */
p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY);
break;
}
num++;
}
temp = num;
@ -748,16 +817,18 @@ rl_redisplay ()
/* Now account for invisible characters in the current line. */
/* XXX - this assumes that the invisible characters may be split, but only
between the first and the last lines. */
temp += (newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line);
if (nocorrect == 0)
temp += wadjust;
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
lpos -= _rl_col_width (local_prompt, n0, num, 1);
/* lpos is a physical cursor position, so it needs to take the invisible
characters into account. */
if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
lpos -= _rl_col_width (local_prompt, n0, num, 1) - wadjust;
else
#endif
lpos -= _rl_screenwidth;
lpos -= _rl_screenwidth; /* all physical cursor positions */
}
prompt_last_screen_line = newlines;
@ -770,7 +841,7 @@ rl_redisplay ()
lb_linenum = 0;
#if defined (HANDLE_MULTIBYTE)
in = 0;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
memset (&ps, 0, sizeof (mbstate_t));
/* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
@ -786,7 +857,7 @@ rl_redisplay ()
c = (unsigned char)rl_line_buffer[in];
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
if (MB_INVALIDCH (wc_bytes))
{
@ -895,7 +966,7 @@ rl_redisplay ()
else
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
register int i;
@ -931,7 +1002,7 @@ rl_redisplay ()
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
in += wc_bytes;
/* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
@ -949,7 +1020,7 @@ rl_redisplay ()
lb_linenum = newlines;
}
inv_botlin = lb_botlin = newlines;
inv_botlin = lb_botlin = _rl_inv_botlin = newlines;
CHECK_INV_LBREAKS ();
inv_lbreaks[newlines+1] = out;
cursor_linenum = lb_linenum;
@ -979,9 +1050,11 @@ rl_redisplay ()
not the first. */
if (out >= _rl_screenchars)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
else
#endif
out = _rl_screenchars - 1;
}
@ -1027,15 +1100,15 @@ rl_redisplay ()
time update_line is called, then we can assume in our
calculations that o_cpos does not need to be adjusted by
wrap_offset. */
if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
(MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
(mb_cur_max > 1 && rl_byte_oriented == 0) &&
cpos_adjusted == 0 &&
_rl_last_c_pos != o_cpos &&
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
this only if there is not more than one new line (which
@ -1047,7 +1120,7 @@ rl_redisplay ()
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
nleft = _rl_screenwidth - _rl_last_c_pos;
else
nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
@ -1099,7 +1172,7 @@ rl_redisplay ()
the physical cursor position on the screen stays the same,
but the buffer position needs to be adjusted to account
for invisible characters. */
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
_rl_last_c_pos += wrap_offset;
}
@ -1126,7 +1199,7 @@ rl_redisplay ()
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
else
_rl_last_c_pos = nleft + modmark;
@ -1150,7 +1223,7 @@ rl_redisplay ()
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
{
/* TX == new physical cursor position in multibyte locale. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
else
tx = nleft;
@ -1165,7 +1238,7 @@ rl_redisplay ()
_rl_last_c_pos as an absolute cursor position, but moving to a
point specified by a buffer position (NLEFT) that doesn't take
invisible characters into account. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_move_cursor_relative (nleft, &invisible_line[pos]);
else if (nleft != _rl_last_c_pos)
_rl_move_cursor_relative (nleft, &invisible_line[pos]);
@ -1246,7 +1319,7 @@ rl_redisplay ()
_rl_screenwidth + (lmargin ? 0 : wrap_offset),
0);
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
displaying_prompt_first_line && OLD_CPOS_IN_PROMPT())
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
@ -1318,6 +1391,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
int current_invis_chars;
int col_lendiff, col_temp;
int bytes_to_insert;
int mb_cur_max = MB_CUR_MAX;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps_new, ps_old;
int new_offset, old_offset;
@ -1328,7 +1402,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
the exact cursor position and cut-and-paste with certain terminal
emulators. In this calculation, TEMP is the physical screen
position of the cursor. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
temp = _rl_last_c_pos;
else
temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
@ -1336,7 +1410,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
&& _rl_last_v_pos == current_line - 1)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
wchar_t wc;
mbstate_t ps;
@ -1350,7 +1424,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
memset (&ps, 0, sizeof (mbstate_t));
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
ret = mbrtowc (&wc, new, mb_cur_max, &ps);
if (MB_INVALIDCH (ret))
{
tempwidth = 1;
@ -1370,7 +1444,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_last_c_pos = tempwidth;
_rl_last_v_pos++;
memset (&ps, 0, sizeof (mbstate_t));
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
ret = mbrtowc (&wc, old, mb_cur_max, &ps);
if (ret != 0 && bytes != 0)
{
if (MB_INVALIDCH (ret))
@ -1409,7 +1483,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* Find first difference. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
/* See if the old line is a subset of the new line, so that the
only change is adding characters. */
@ -1466,7 +1540,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
return;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
if (mb_cur_max > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
{
wchar_t wc;
mbstate_t ps = { 0 };
@ -1475,7 +1549,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* If the first character in the difference is a zero-width character,
assume it's a combining character and back one up so the two base
characters no longer compare equivalently. */
t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps);
t = mbrtowc (&wc, ofd, mb_cur_max, &ps);
if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0)
{
old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
@ -1489,7 +1563,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
wsatend = 1; /* flag for trailing whitespace */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
@ -1547,14 +1621,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
if (*ols) /* don't step past the NUL */
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
else
ols++;
}
if (*nls)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
else
nls++;
@ -1566,7 +1640,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (_rl_last_v_pos != current_line)
{
_rl_move_vert (current_line);
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
/* We have moved up to a new screen line. This line may or may not have
invisible characters on it, but we do our best to recalculate
visible_wrap_offset based on what we know. */
if (current_line == 0)
visible_wrap_offset = prompt_invis_chars_first_line; /* XXX */
if ((mb_cur_max == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
_rl_last_c_pos += visible_wrap_offset;
}
@ -1577,16 +1656,31 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
string, then redraw the entire prompt string. We can only do this
reliably if the terminal supports a `cr' capability.
This can also happen if the prompt string has changed, and the first
difference in the line is in the middle of the prompt string, after a
sequence of invisible characters (worst case) and before the end of
the prompt. In this case, we have to redraw the entire prompt string
so that the entire sequence of invisible characters is drawn. We need
to handle the worst case, when the difference is after (or in the middle
of) a sequence of invisible characters that changes the text color and
before the sequence that restores the text color to normal. Then we have
to make sure that the lines still differ -- if they don't, we can
return immediately.
This is not an efficiency hack -- there is a problem with redrawing
portions of the prompt string if they contain terminal escape
sequences (like drawing the `unbold' sequence without a corresponding
`bold') that manifests itself on certain terminals. */
lendiff = local_prompt_len;
if (lendiff > nmax)
lendiff = nmax;
od = ofd - old; /* index of first difference in visible line */
nd = nfd - new; /* nd, od are buffer indexes */
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
_rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
(((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) ||
((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX)))
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
@ -1596,7 +1690,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (modmark)
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, lendiff);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
@ -1605,6 +1699,43 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
}
else
_rl_last_c_pos = lendiff + modmark;
/* Now if we have printed the prompt string because the first difference
was within the prompt, see if we need to recompute where the lines
differ. Check whether where we are now is past the last place where
the old and new lines are the same and short-circuit now if we are. */
if ((od <= prompt_last_invisible || nd <= prompt_last_invisible) &&
omax == nmax &&
lendiff > (ols-old) && lendiff > (nls-new))
return;
/* XXX - we need to fix up our calculations if we are now past the
old ofd/nfd and the prompt length (or line length) has changed.
We punt on the problem and do a dumb update. We'd like to be able
to just output the prompt from the beginning of the line up to the
first difference, but you don't know the number of invisible
characters in that case.
This needs a lot of work to be efficient. */
if ((od <= prompt_last_invisible || nd <= prompt_last_invisible))
{
nfd = new + lendiff; /* number of characters we output above */
nd = lendiff;
/* Do a dumb update and return */
temp = ne - nfd;
if (temp > 0)
{
_rl_output_some_chars (nfd, temp);
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1);
else
_rl_last_c_pos += temp;
}
if (nmax < omax)
goto clear_rest_of_line; /* XXX */
else
return;
}
}
o_cpos = _rl_last_c_pos;
@ -1618,7 +1749,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* We need to indicate that the cursor position is correct in the presence of
invisible characters in the prompt string. Let's see if setting this when
we make sure we're at the end of the drawn prompt string works. */
if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
if (current_line == 0 && mb_cur_max > 1 && rl_byte_oriented == 0 &&
(_rl_last_c_pos > 0 || o_cpos > 0) &&
_rl_last_c_pos == prompt_physical_chars)
cpos_adjusted = 1;
@ -1629,7 +1760,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
col_lendiff == difference on screen (columns)
When not using multibyte characters, these are equal */
lendiff = (nls - nfd) - (ols - ofd);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
else
col_lendiff = lendiff;
@ -1640,7 +1771,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
current_invis_chars != visible_wrap_offset)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
lendiff += visible_wrap_offset - current_invis_chars;
col_lendiff += visible_wrap_offset - current_invis_chars;
@ -1658,7 +1789,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
and writes TEMP bytes. */
/* Insert (diff (len (old), len (new)) ch. */
temp = ne - nfd;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
else
col_temp = temp;
@ -1709,7 +1840,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_last_c_pos == 0 &&
lendiff > prompt_visible_length &&
current_invis_chars > 0) == 0) &&
(((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
(((mb_cur_max > 1 && rl_byte_oriented == 0) &&
current_line == 0 && wrap_offset &&
((nfd - new) <= prompt_last_invisible) &&
(col_lendiff < prompt_visible_length)) == 0) &&
@ -1717,12 +1848,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
open_some_spaces (col_lendiff);
_rl_output_some_chars (nfd, bytes_to_insert);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
else
_rl_last_c_pos += bytes_to_insert;
}
else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
else if ((mb_cur_max == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
{
/* At the end of a line the characters do not have to
be "inserted". They can just be placed on the screen. */
@ -1737,7 +1868,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
@ -1750,7 +1881,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
@ -1766,11 +1897,15 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
char in the current line (which implies we just output some invisible
characters) we need to adjust _rl_last_c_pos, since it represents
a physical character position. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
/* The current_line*rl_screenwidth+prompt_invis_chars_first_line is a
crude attempt to compute how far into the new line buffer we are.
It doesn't work well in the face of multibyte characters and needs
to be rethought. XXX */
if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
current_line == prompt_last_screen_line && wrap_offset &&
displaying_prompt_first_line &&
wrap_offset != prompt_invis_chars_first_line &&
((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth+prompt_invis_chars_first_line))))
{
_rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
cpos_adjusted = 1;
@ -1810,7 +1945,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
in a multibyte locale to account for the wrap offset and
set cpos_adjusted accordingly. */
_rl_output_some_chars (nfd, bytes_to_insert);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
if (current_line == 0 && wrap_offset &&
@ -1845,7 +1980,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
set cpos_adjusted accordingly. */
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp; /* XXX */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
if (current_line == 0 && wrap_offset &&
displaying_prompt_first_line &&
@ -1859,7 +1994,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
}
clear_rest_of_line:
lendiff = (oe - old) - (ne - new);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
else
col_lendiff = lendiff;
@ -1869,7 +2004,7 @@ clear_rest_of_line:
space_to_eol will insert too many spaces. XXX - maybe we should
adjust col_lendiff based on the difference between _rl_last_c_pos
and _rl_screenwidth */
if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
if (col_lendiff && ((mb_cur_max == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
{
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (col_lendiff);
@ -1895,6 +2030,34 @@ rl_on_new_line ()
return 0;
}
/* Clear all screen lines occupied by the current readline line buffer
(visible line) */
int
rl_clear_visible_line ()
{
int curr_line;
/* Make sure we move to column 0 so we clear the entire line */
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
/* Move to the last screen line of the current visible line */
_rl_move_vert (_rl_vis_botlin);
/* And erase screen lines going up to line 0 (first visible line) */
for (curr_line = _rl_last_v_pos; curr_line >= 0; curr_line--)
{
_rl_move_vert (curr_line);
_rl_clear_to_eol (0);
}
return 0;
}
/* Tell the update routines that we have moved onto a new line with the
prompt already displayed. Code originally from the version of readline
distributed with CLISP. rl_expand_prompt must have already been called
@ -1972,11 +2135,25 @@ rl_forced_update_display ()
return 0;
}
/* Redraw only the last line of a multi-line prompt. */
void
rl_redraw_prompt_last_line ()
{
char *t;
t = strrchr (rl_display_prompt, '\n');
if (t)
redraw_prompt (++t);
else
rl_forced_update_display ();
}
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
(Well, when we don't have multibyte characters, _rl_last_c_pos is a
buffer index.)
DATA is the contents of the screen line of interest; i.e., where
the movement is being done. */
the movement is being done.
DATA is always the visible line or the invisible line */
void
_rl_move_cursor_relative (new, data)
int new;
@ -1986,6 +2163,8 @@ _rl_move_cursor_relative (new, data)
int woff; /* number of invisible chars on current line */
int cpos, dpos; /* current and desired cursor positions */
int adjust;
int in_invisline;
int mb_cur_max = MB_CUR_MAX;
woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
cpos = _rl_last_c_pos;
@ -1999,7 +2178,7 @@ _rl_move_cursor_relative (new, data)
this case, NEW's display position is not obvious and must be
calculated. We need to account for invisible characters in this line,
as long as we are past them and they are counted by _rl_col_width. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
adjust = 1;
/* Try to short-circuit common cases and eliminate a bunch of multibyte
@ -2024,14 +2203,28 @@ _rl_move_cursor_relative (new, data)
if (displaying_prompt_first_line == 0)
adjust = 0;
/* yet another special case: printing the last line of a prompt with
multibyte characters and invisible characters whose printable length
exceeds the screen width with the last invisible character
(prompt_last_invisible) in the last line. IN_INVISLINE is the
offset of DATA in invisible_line */
in_invisline = 0;
if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1])
in_invisline = data - invisible_line;
/* Use NEW when comparing against the last invisible character in the
prompt string, since they're both buffer indices and DPOS is a
desired display position. */
/* NEW is relative to the current displayed line, while
PROMPT_LAST_INVISIBLE is relative to the entire (wrapped) line.
Need a way to reconcile these two variables by turning NEW into a
buffer position relative to the start of the line */
if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
(prompt_physical_chars >= _rl_screenwidth &&
(new+in_invisline > prompt_last_invisible) || /* invisible line */
(prompt_physical_chars >= _rl_screenwidth && /* visible line */
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset >= woff && dpos >= woff &&
new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
new > (prompt_last_invisible-(vis_lbreaks[_rl_last_v_pos])-wrap_offset))))
/* XXX last comparison might need to be >= */
{
dpos -= woff;
@ -2053,7 +2246,7 @@ _rl_move_cursor_relative (new, data)
of moving backwards. */
/* i == current physical cursor position. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
i = _rl_last_c_pos;
else
#endif
@ -2088,7 +2281,7 @@ _rl_move_cursor_relative (new, data)
in the buffer and we have to go back to the beginning of the screen
line. In this case, we can use the terminal sequence to move forward
if it's available. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
if (_rl_term_forward_char)
{
@ -2246,7 +2439,7 @@ rl_message (va_alist)
msg_buf = xmalloc (msg_bufsiz = 128);
#if defined (HAVE_VSNPRINTF)
bneed = vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
bneed = vsnprintf (msg_buf, msg_bufsiz, format, args);
if (bneed >= msg_bufsiz - 1)
{
msg_bufsiz = bneed + 1;
@ -2279,10 +2472,10 @@ rl_message (va_alist)
local_prompt = (char *)NULL;
}
rl_display_prompt = msg_buf;
local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
(*rl_redisplay_function) ();
@ -2312,10 +2505,10 @@ rl_message (format, arg1, arg2)
FREE (local_prompt_prefix);
local_prompt = (char *)NULL;
}
local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
(*rl_redisplay_function) ();
@ -2502,7 +2695,7 @@ static void
open_some_spaces (col)
int col;
{
#if !defined (__MSDOS__) && !defined (__MINGW32__)
#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
char *buffer;
register int i;
@ -2531,7 +2724,7 @@ open_some_spaces (col)
for (i = col; i--; )
tputs (_rl_term_ic, 1, _rl_output_character_function);
}
#endif /* !__MSDOS__ && !__MINGW32__ */
#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
}
/* Delete COUNT characters from the display line. */
@ -2542,7 +2735,7 @@ delete_chars (count)
if (count > _rl_screenwidth) /* XXX */
return;
#if !defined (__MSDOS__) && !defined (__MINGW32__)
#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
if (_rl_term_DC && *_rl_term_DC)
{
char *buffer;
@ -2555,7 +2748,7 @@ delete_chars (count)
while (count--)
tputs (_rl_term_dc, 1, _rl_output_character_function);
}
#endif /* !__MSDOS__ && !__MINGW32__ */
#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
}
void
@ -2618,7 +2811,8 @@ redraw_prompt (t)
rl_save_prompt ();
rl_display_prompt = t;
local_prompt = expand_prompt (t, &prompt_visible_length,
local_prompt = expand_prompt (t, PMT_MULTILINE,
&prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
@ -2699,6 +2893,12 @@ _rl_erase_entire_line ()
fflush (rl_outstream);
}
void
_rl_ttyflush ()
{
fflush (rl_outstream);
}
/* return the `current display line' of the cursor -- the number of lines to
move up to get to the first screen line of the current readline line. */
int

View file

@ -12,7 +12,7 @@ This document describes the GNU History library
a programming tool that provides a consistent user interface for
recalling lines of previously typed input.
Copyright @copyright{} 1988--2014 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document

View file

@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@ -242,6 +242,7 @@ is greater than the history length, return a @code{NULL} pointer.
@deftypefun time_t history_get_time (HIST_ENTRY *entry)
Return the time stamp associated with the history entry @var{entry}.
If the timestamp is missing or invalid, return 0.
@end deftypefun
@deftypefun int history_total_bytes (void)
@ -270,9 +271,11 @@ a @code{NULL} pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} next_history (void)
Move the current history offset forward to the next history entry, and
return the a pointer to that entry. If there is no next entry, return
a @code{NULL} pointer.
If the current history offset refers to a valid history entry,
increment the current history offset.
If the possibly-incremented history offset refers to a valid history
entry, return a pointer to that entry;
otherwise, return a @code{BNULL} pointer.
@end deftypefun
@node Searching the History List
@ -467,8 +470,8 @@ carriage return, and @samp{=}.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, single-quoted words are not scanned for the history expansion
character. The default value is 0.
If non-zero, double-quoted words are not scanned for the history expansion
character or the history comment character. The default value is 0.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function

View file

@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988--2014 Free Software Foundation, Inc.
Copyright (C) 1988--2016 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@ -102,7 +102,7 @@ associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
as timestamps for the following history entry.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
@ -202,9 +202,9 @@ Delete the history entry at position @var{offset}.
displayed.
@item -a
Append the new
history lines (history lines entered since the beginning of the
current Bash session) to the history file.
Append the new history lines to the history file.
These are history lines entered since the beginning of the current
Bash session, but not already appended to the history file.
@item -n
Append the history lines not already read from the history file
@ -249,6 +249,11 @@ the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
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.
@end ifset
History expansion takes place in two parts. The first is to determine
which line from the history list should be used during substitution.
The second is to select portions of that line for inclusion into the
@ -262,7 +267,9 @@ History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
@ifset BashFeatures
Only @samp{\} and @samp{'} may be used to escape the history expansion
character.
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
@ifset BashFeatures

View file

@ -13,7 +13,7 @@ This manual describes the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2014 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document

View file

@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
Copyright (C) 1988--2014 Free Software Foundation, Inc.
Copyright (C) 1988--2016 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@ -282,7 +282,7 @@ At the very least, it should be aware that it can be passed a
negative argument.
A command function should return 0 if its action completes successfully,
and a non-zero value if some error occurs.
and a value greater than zero if some error occurs.
This is the convention obeyed by all of the builtin Readline bindable
command functions.
@ -963,6 +963,10 @@ redisplay.
It should be used after setting @var{rl_already_prompted}.
@end deftypefun
@deftypefun int rl_clear_visible_line (void)
Clear the screen lines corresponding to the current line's contents.
@end deftypefun
@deftypefun int rl_reset_line_state (void)
Reset the display state to a clean state and redisplay the current line
starting on a new line.
@ -1020,7 +1024,7 @@ It returns the number of visible characters on the last line of the
Applications may indicate that the prompt contains characters that take
up no physical screen space when displayed by bracketing a sequence of
such characters with the special markers @code{RL_PROMPT_START_IGNORE}
and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}. This may
and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}). This may
be used to embed terminal-specific escape sequences in prompts.
@end deftypefun
@ -1136,6 +1140,14 @@ that the terminal editing characters are bound to @code{rl_insert}.
The bindings are performed in @var{kmap}.
@end deftypefun
@deftypefun int rl_tty_set_echoing (int value)
Set Readline's idea of whether or not it is echoing output to its output
stream (@var{rl_outstream}). If @var{value} is 0, Readline does not display
output to @var{rl_outstream}; any other value enables output. The initial
value is set when Readline initializes the terminal settings.
This function returns the previous value.
@end deftypefun
@deftypefun int rl_reset_terminal (const char *terminal_name)
Reinitialize Readline's idea of the terminal settings using
@var{terminal_name} as the terminal type (e.g., @code{vt100}).
@ -1307,6 +1319,8 @@ expanded value of @var{prompt}. Save the value of @var{lhandler} to
use as a handler function to call when a complete line of input has been
entered.
The handler function receives the text of the line as an argument.
As with @code{readline()}, the handler function should @code{free} the
line when it it finished with it.
@end deftypefun
@deftypefun void rl_callback_read_char (void)
@ -1326,9 +1340,17 @@ the terminal settings are modified for Readline's use again.
@code{NULL} line.
@end deftypefun
@deftypefun void rl_callback_sigcleanup (void)
Clean up any internal state the callback interface uses to maintain state
between calls to rl_callback_read_char (e.g., the state of any active
incremental searches). This is intended to be used by applications that
wish to perform their own signal handling; Readline's internal signal handler
calls this when appropriate.
@end deftypefun
@deftypefun void rl_callback_handler_remove (void)
Restore the terminal to its initial state and remove the line handler.
This may be called from within a callback as well as independently.
You may call this function from within a callback as well as independently.
If the @var{lhandler} installed by @code{rl_callback_handler_install}
does not exit the program, either this function or the function referred
to by the value of @code{rl_deprep_term_function} should be called before
@ -1413,12 +1435,16 @@ It understands the EOF character or "exit" to exit the program.
@example
/* Standard include files. stdio.h is required. */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
/* Used for select(2) */
#include <sys/types.h>
#include <sys/select.h>
#include <signal.h>
#include <stdio.h>
/* Standard readline include files. */
@ -1426,10 +1452,20 @@ It understands the EOF character or "exit" to exit the program.
#include <readline/history.h>
static void cb_linehandler (char *);
static void sighandler (int);
int running;
int sigwinch_received;
const char *prompt = "rltest$ ";
/* Handle SIGWINCH and window size changes when readline is not active and
reading a character. */
static void
sighandler (int sig)
@{
sigwinch_received = 1;
@}
/* Callback function called for each line when accept-line executed, EOF
seen, or EOF character read. This sets a flag and returns; it could
also call exit(3). */
@ -1464,6 +1500,13 @@ main (int c, char **v)
fd_set fds;
int r;
/* Set the default locale values according to environment variables. */
setlocale (LC_ALL, "");
/* Handle window size changes when readline is not active and reading
characters. */
signal (SIGWINCH, sighandler);
/* Install the line handler. */
rl_callback_handler_install (prompt, cb_linehandler);
@ -1478,12 +1521,19 @@ main (int c, char **v)
FD_SET (fileno (rl_instream), &fds);
r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
if (r < 0)
if (r < 0 && errno != EINTR)
@{
perror ("rltest: select");
rl_callback_handler_remove ();
break;
@}
if (sigwinch_received)
@{
rl_resize_terminal ();
sigwinch_received = 0;
@}
if (r < 0)
continue;
if (FD_ISSET (fileno (rl_instream), &fds))
rl_callback_read_char ();
@ -1532,7 +1582,30 @@ resetting the terminal to its original state. If the application's signal
handler does more than update its idea of the terminal size and return (for
example, a @code{longjmp} back to a main processing loop), it @emph{must}
call @code{rl_cleanup_after_signal()} (described below), to restore the
terminal state.
terminal state.
When an application is using the callback interface
(@pxref{Alternate Interface}), Readline installs signal handlers only for
the duration of the call to @code{rl_callback_read_char}. Applications
using the callback interface should be prepared to clean up Readline's
state if they wish to handle the signal before the line handler completes
and restores the terminal state.
If an application using the callback interface wishes to have Readline
install its signal handlers at the time the application calls
@code{rl_callback_handler_install} and remove them only when a complete
line of input has been read, it should set the
@code{rl_persistent_signal_handlers} variable to a non-zero value.
This allows an application to defer all of the handling of the signals
Readline catches to Readline.
Applications should use this variable with care; it can result in Readline
catching signals and not acting on them (or allowing the application to react
to them) until the application calls @code{rl_callback_read_char}. This
can result in an application becoming less responsive to keyboard signals
like SIGINT.
If an application does not want or need to perform any signal handling, or
does not need to do any processing between calls to @code{rl_callback_read_char},
setting this variable may be desirable.
Readline provides two variables that allow application writers to
control whether or not it will catch certain signals and act on them
@ -1555,6 +1628,15 @@ Readline will install a signal handler for @code{SIGWINCH}.
The default value of @code{rl_catch_sigwinch} is 1.
@end deftypevar
@deftypevar int rl_persistent_signal_handlers
If an application using the callback interface wishes Readline's signal
handlers to be installed and active during the set of calls to
@code{rl_callback_read_char} that constitutes an entire single line,
it should set this variable to a non-zero value.
The default value of @code{rl_persistent_signal_handlers} is 0.
@end deftypevar
@deftypevar int rl_change_environment
If this variable is set to a non-zero value,
and Readline is handling @code{SIGWINCH}, Readline will modify the
@ -1570,6 +1652,11 @@ for example),
Readline provides convenience functions to do the necessary terminal
and internal state cleanup upon receipt of a signal.
@deftypefun int rl_pending_signal (void)
Return the signal number of the most recent signal Readline received but
has not yet handled, or 0 if there is no pending signal.
@end deftypefun
@deftypefun void rl_cleanup_after_signal (void)
This function will reset the state of the terminal to what it was before
@code{readline()} was called, and remove the Readline signal handlers for
@ -1942,8 +2029,8 @@ where @var{matches} is the array of matching strings,
@var{num_matches} is the number of strings in that array, and
@var{max_length} is the length of the longest string in that array.
Readline provides a convenience function, @code{rl_display_match_list},
that takes care of doing the display to Readline's output stream. That
function may be called from this hook.
that takes care of doing the display to Readline's output stream.
You may call that function from this hook.
@end deftypevar
@deftypevar {const char *} rl_basic_word_break_characters

View file

@ -9,7 +9,7 @@ use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the
GNU Readline Library.
Copyright (C) 1988--2014 Free Software Foundation, Inc.
Copyright (C) 1988--2016 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
@ -423,9 +423,23 @@ the terminal's bell.
@item bind-tty-special-chars
@vindex bind-tty-special-chars
If set to @samp{on}, Readline attempts to bind the control characters
treated specially by the kernel's terminal driver to their Readline
equivalents.
If set to @samp{on} (the default), Readline attempts to bind the control
characters treated specially by the kernel's terminal driver to their
Readline equivalents.
@item blink-matching-paren
@vindex blink-matching-paren
If set to @samp{on}, Readline attempts to briefly move the cursor to an
opening parenthesis when a closing parenthesis is inserted. The default
is @samp{off}.
@item colored-completion-prefix
@vindex colored-completion-prefix
If set to @samp{on}, when listing completions, Readline displays the
common prefix of the set of possible completions using a different color.
The color definitions are taken from the value of the @env{LS_COLORS}
environment variable.
The default is @samp{off}.
@item colored-stats
@vindex colored-stats
@ -485,7 +499,9 @@ The default limit is @code{100}.
If set to @samp{on}, Readline will convert characters with the
eighth bit set to an @sc{ascii} key sequence by stripping the eighth
bit and prefixing an @key{ESC} character, converting them to a
meta-prefixed key sequence. The default value is @samp{on}.
meta-prefixed key sequence. The default value is @samp{on}, but
will be set to @samp{off} if the locale is one that contains
eight-bit characters.
@item disable-completion
@vindex disable-completion
@ -493,6 +509,12 @@ If set to @samp{On}, Readline will inhibit word completion.
Completion characters will be inserted into the line as if they had
been mapped to @code{self-insert}. The default is @samp{off}.
@item echo-control-characters
@vindex echo-control-characters
When set to @samp{on}, on operating systems that indicate they support it,
readline echoes a character corresponding to a signal generated from the
keyboard. The default is @samp{on}.
@item editing-mode
@vindex editing-mode
The @code{editing-mode} variable controls which default set of
@ -500,10 +522,24 @@ key bindings is used. By default, Readline starts up in Emacs editing
mode, where the keystrokes are most similar to Emacs. This variable can be
set to either @samp{emacs} or @samp{vi}.
@item echo-control-characters
When set to @samp{on}, on operating systems that indicate they support it,
readline echoes a character corresponding to a signal generated from the
keyboard. The default is @samp{on}.
@item emacs-mode-string
@vindex emacs-mode-string
This string is displayed immediately before the last line of the primary
prompt when emacs editing mode is active. The value is expanded like a
key binding, so the standard set of meta- and control prefixes and
backslash escape sequences is available.
Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of
non-printing characters, which can be used to embed a terminal control
sequence into the mode string.
The default is @samp{@@}.
@item enable-bracketed-paste
@vindex enable-bracketed-paste
When set to @samp{On}, Readline will configure the terminal in a way
that will enable it to insert each paste into the editing buffer as a
single string of characters, instead of treating each character as if
it had been read from the keyboard. This can prevent pasted characters
from being interpreted as editing commands. The default is @samp{off}.
@item enable-keypad
@vindex enable-keypad
@ -537,6 +573,8 @@ are saved.
If set to a value less than zero, the number of history entries is not
limited.
By default, the number of history entries is not limited.
If an attempt is made to set @var{history-size} to a non-numeric value,
the maximum number of history entries will be set to 500.
@item horizontal-scroll-mode
@vindex horizontal-scroll-mode
@ -552,8 +590,9 @@ this variable is set to @samp{off}.
If set to @samp{on}, Readline will enable eight-bit input (it
will not clear the eighth bit in the characters it reads),
regardless of what the terminal claims it can support. The
default value is @samp{off}. The name @code{meta-flag} is a
synonym for this variable.
default value is @samp{off}, but Readline will set it to @samp{on} if the
locale contains eight-bit characters.
The name @code{meta-flag} is a synonym for this variable.
@item isearch-terminators
@vindex isearch-terminators
@ -574,8 +613,9 @@ Acceptable @code{keymap} names are
@code{vi-move},
@code{vi-command}, and
@code{vi-insert}.
@code{vi} is equivalent to @code{vi-command}; @code{emacs} is
equivalent to @code{emacs-standard}. The default value is @code{emacs}.
@code{vi} is equivalent to @code{vi-command} (@code{vi-move} is also a
synonym); @code{emacs} is equivalent to @code{emacs-standard}.
The default value is @code{emacs}.
The value of the @code{editing-mode} variable also affects the
default keymap.
@ -631,7 +671,9 @@ the list. The default is @samp{off}.
@vindex output-meta
If set to @samp{on}, Readline will display characters with the
eighth bit set directly rather than as a meta-prefixed escape
sequence. The default is @samp{off}.
sequence.
The default is @samp{off}, but Readline will set it to @samp{on} if the
locale contains eight-bit characters.
@item page-completions
@vindex page-completions
@ -673,8 +715,8 @@ The default value is @samp{off}.
@item show-mode-in-prompt
@vindex show-mode-in-prompt
If set to @samp{on}, add a character to the beginning of the prompt
indicating the editing mode: emacs (@samp{@@}), vi command (@samp{:}),
or vi insertion (@samp{+}).
indicating the editing mode: emacs, vi command, or vi insertion.
The mode strings are user-settable.
The default value is @samp{off}.
@item skip-completed-text
@ -691,6 +733,30 @@ rather than @samp{Makefilefile}, assuming there is a single possible
completion.
The default value is @samp{off}.
@item vi-cmd-mode-string
@vindex vi-cmd-mode-string
This string is displayed immediately before the last line of the primary
prompt when vi editing mode is active and in command mode.
The value is expanded like a
key binding, so the standard set of meta- and control prefixes and
backslash escape sequences is available.
Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of
non-printing characters, which can be used to embed a terminal control
sequence into the mode string.
The default is @samp{(cmd)}.
@item vi-ins-mode-string
@vindex vi-ins-mode-string
This string is displayed immediately before the last line of the primary
prompt when vi editing mode is active and in insertion mode.
The value is expanded like a
key binding, so the standard set of meta- and control prefixes and
backslash escape sequences is available.
Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of
non-printing characters, which can be used to embed a terminal control
sequence into the mode string.
The default is @samp{(ins)}.
@item visible-stats
@vindex visible-stats
If set to @samp{on}, a character denoting a file's type
@ -1122,17 +1188,19 @@ the history as necessary. This is an incremental search.
@item forward-search-history (C-s)
Search forward starting at the current line and moving `down' through
the the history as necessary. This is an incremental search.
the history as necessary. This is an incremental search.
@item non-incremental-reverse-search-history (M-p)
Search backward starting at the current line and moving `up'
through the history as necessary using a non-incremental search
for a string supplied by the user.
The search string may match anywhere in a history line.
@item non-incremental-forward-search-history (M-n)
Search forward starting at the current line and moving `down'
through the the history as necessary using a non-incremental search
through the history as necessary using a non-incremental search
for a string supplied by the user.
The search string may match anywhere in a history line.
@item history-search-forward ()
Search forward through the history for the string of characters
@ -1224,6 +1292,14 @@ Insert a tab character.
@item self-insert (a, b, A, 1, !, @dots{})
Insert yourself.
@item bracketed-paste-begin ()
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
executing any editing commands.
@item transpose-chars (C-t)
Drag the character before the cursor forward over
the character at the cursor, moving the
@ -1275,7 +1351,7 @@ By default, this command is unbound.
Kill the text from point to the end of the line.
@item backward-kill-line (C-x Rubout)
Kill backward to the beginning of the line.
Kill backward from the cursor to the beginning of the current line.
@item unix-line-discard (C-u)
Kill backward from the cursor to the beginning of the current line.
@ -1357,7 +1433,7 @@ leading minus sign, those digits define the argument.
If the command is followed by digits, executing @code{universal-argument}
again ends the numeric argument, but is otherwise ignored.
As a special case, if this command is immediately followed by a
character that is neither a digit or minus sign, the argument count
character that is neither a digit nor minus sign, the argument count
for the next command is multiplied by four.
The argument count is initially one, so executing this function the
first time makes the argument count four, a second time makes the
@ -1788,6 +1864,10 @@ is removed before attempting a match.
Any completion that matches the pattern will be removed from the list.
A leading @samp{!} negates the pattern; in this case any completion
not matching the pattern will be removed.
If the @code{nocasematch} shell option
(see the description of @code{shopt} in @ref{The Shopt Builtin})
is enabled, the match is performed without regard to the case
of alphabetic characters.
Finally, any prefix and suffix specified with the @option{-P} and @option{-S}
options are added to each member of the completion list, and the result is
@ -1941,6 +2021,9 @@ with @option{-F}.
Tell Readline not to quote the completed words if they are filenames
(quoting filenames is the default).
@item nosort
Tell Readline not to sort the list of possible completions alphabetically.
@item nospace
Tell Readline not to append a space (the default) to words completed at
the end of the line.

View file

@ -12,7 +12,7 @@ This manual describes the end user interface of the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2014 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document

View file

@ -1,10 +1,10 @@
@ignore
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 Free Software Foundation, Inc.
@end ignore
@set EDITION 6.3
@set VERSION 6.3
@set UPDATED 6 January 2014
@set UPDATED-MONTH January 2014
@set EDITION 7.0
@set VERSION 7.0
@set UPDATED 16 July 2016
@set UPDATED-MONTH July 2016
@set LASTCHANGE Mon Jan 6 16:26:51 EST 2014
@set LASTCHANGE Sat Jul 16 13:43:15 EDT 2016

View file

@ -63,6 +63,12 @@
extern char *xmalloc PARAMS((size_t));
void initialize_readline PARAMS((void));
void too_dangerous PARAMS((char *));
int execute_line PARAMS((char *));
int valid_argument PARAMS((char *, char *));
/* The names of functions that actually do the manipulation. */
int com_list PARAMS((char *));
int com_view PARAMS((char *));
@ -119,6 +125,7 @@ dupstr (s)
return (r);
}
int
main (argc, argv)
int argc;
char **argv;
@ -241,6 +248,7 @@ char **fileman_completion PARAMS((const char *, int, int));
/* Tell the GNU Readline library how to complete. We want to try to complete
on command names if this is the first word in the line, or on filenames
if not. */
void
initialize_readline ()
{
/* Allow conditional parsing of the ~/.inputrc file. */
@ -317,6 +325,7 @@ command_generator (text, state)
static char syscom[1024];
/* List the file(s) named in arg. */
int
com_list (arg)
char *arg;
{
@ -327,6 +336,7 @@ com_list (arg)
return (system (syscom));
}
int
com_view (arg)
char *arg;
{
@ -342,6 +352,7 @@ com_view (arg)
return (system (syscom));
}
int
com_rename (arg)
char *arg;
{
@ -349,6 +360,7 @@ com_rename (arg)
return (1);
}
int
com_stat (arg)
char *arg;
{
@ -377,6 +389,7 @@ com_stat (arg)
return (0);
}
int
com_delete (arg)
char *arg;
{
@ -386,6 +399,7 @@ com_delete (arg)
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int
com_help (arg)
char *arg;
{
@ -425,6 +439,7 @@ com_help (arg)
}
/* Change to the directory ARG. */
int
com_cd (arg)
char *arg;
{
@ -439,6 +454,7 @@ com_cd (arg)
}
/* Print out the current working directory. */
int
com_pwd (ignore)
char *ignore;
{
@ -456,6 +472,7 @@ com_pwd (ignore)
}
/* The user wishes to quit using this program. Just set DONE non-zero. */
int
com_quit (arg)
char *arg;
{
@ -464,6 +481,7 @@ com_quit (arg)
}
/* Function which tells you that you can't do this. */
void
too_dangerous (caller)
char *caller;
{

View file

@ -1,16 +1,25 @@
/* Standard include files. stdio.h is required. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* Used for select(2) */
#include <sys/types.h>
#include <sys/select.h>
#include <errno.h>
#include <stdio.h>
/* Standard readline include files. */
#include <readline/readline.h>
#include <readline/history.h>
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int errno;
static void cb_linehandler (char *);
@ -65,7 +74,7 @@ main (int c, char **v)
FD_SET (fileno (rl_instream), &fds);
r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
if (r < 0)
if (r < 0 && errno != EINTR)
{
perror ("rltest: select");
rl_callback_handler_remove ();

View file

@ -28,6 +28,7 @@
# include <config.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

View file

@ -1,6 +1,6 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -68,6 +68,7 @@ static const FUNMAP default_funmap[] = {
{ "backward-word", rl_backward_word },
{ "beginning-of-history", rl_beginning_of_history },
{ "beginning-of-line", rl_beg_of_line },
{ "bracketed-paste-begin", rl_bracketed_paste_begin },
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
{ "capitalize-word", rl_capitalize_word },
{ "character-search", rl_char_search },
@ -115,7 +116,7 @@ static const FUNMAP default_funmap[] = {
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
{ "old-menu-complete", rl_old_menu_complete },
{ "overwrite-mode", rl_overwrite_mode },
#ifdef __CYGWIN__
#if defined (_WIN32)
{ "paste-from-clipboard", rl_paste_from_clipboard },
#endif
{ "possible-completions", rl_possible_completions },
@ -177,7 +178,7 @@ static const FUNMAP default_funmap[] = {
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
{ "vi-insertion-mode", rl_vi_insertion_mode },
{ "vi-insertion-mode", rl_vi_insert_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
@ -193,7 +194,9 @@ static const FUNMAP default_funmap[] = {
{ "vi-set-mark", rl_vi_set_mark },
{ "vi-subst", rl_vi_subst },
{ "vi-tilde-expand", rl_vi_tilde_expand },
{ "vi-unix-word-rubout", rl_vi_unix_word_rubout },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-yank-pop", rl_vi_yank_pop },
{ "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */

View file

@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989-2012 Free Software Foundation, Inc.
/* Copyright (C) 1989-2015 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@ -44,12 +44,14 @@
#include "history.h"
#include "histlib.h"
#include "chardefs.h"
#include "rlshell.h"
#include "xmalloc.h"
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`"
#define HISTORY_EVENT_DELIMITERS "^$*%-"
#define slashify_in_quotes "\\`\"$"
@ -62,6 +64,10 @@ static char *subst_rhs;
static int subst_lhs_len;
static int subst_rhs_len;
/* Characters that delimit history event specifications and separate event
specifications from word designators. Static for now */
static char *history_event_delimiter_chars = HISTORY_EVENT_DELIMITERS;
static char *get_history_word_specifier PARAMS((char *, char *, int *));
static int history_tokenize_word PARAMS((const char *, int));
static char **history_tokenize_internal PARAMS((const char *, int, int *));
@ -112,7 +118,6 @@ rl_linebuf_func_t *history_inhibit_expansion_function;
/* The last string searched for by a !?string? search. */
static char *search_string;
/* The last string matched by a !?string? search. */
static char *search_match;
@ -225,6 +230,7 @@ get_history_event (string, caller_index, delimiting_quote)
#endif /* HANDLE_MULTIBYTE */
if ((!substring_okay && (whitespace (c) || c == ':' ||
(history_event_delimiter_chars && member (c, history_event_delimiter_chars)) ||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
string[i] == delimiting_quote)) ||
string[i] == '\n' ||
@ -873,7 +879,7 @@ history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_l
1) If expansions did take place
2) If the `p' modifier was given and the caller should print the result
If an error ocurred in expansion, then OUTPUT contains a descriptive
If an error occurred in expansion, then OUTPUT contains a descriptive
error message. */
#define ADD_STRING(s) \
@ -991,6 +997,7 @@ history_expand (hstring, output)
history expansion performed on it.
Skip the rest of the line and break out of the loop. */
if (history_comment_char && string[i] == history_comment_char &&
dquote == 0 &&
(i == 0 || member (string[i - 1], history_word_delimiters)))
{
while (string[i])
@ -1149,7 +1156,8 @@ history_expand (hstring, output)
}
case -2: /* history_comment_char */
if (i == 0 || member (string[i - 1], history_word_delimiters))
if ((dquote == 0 || history_quotes_inhibit_expansion == 0) &&
(i == 0 || member (string[i - 1], history_word_delimiters)))
{
temp = (char *)xmalloc (l - i + 1);
strcpy (temp, string + i);
@ -1213,7 +1221,7 @@ history_expand (hstring, output)
ADD_STRING (temp);
xfree (temp);
}
only_printing = r == 1;
only_printing += r == 1;
i = eindex;
}
break;
@ -1414,7 +1422,7 @@ history_tokenize_word (string, ind)
const char *string;
int ind;
{
register int i;
register int i, j;
int delimiter, nestdelim, delimopen;
i = ind;
@ -1426,6 +1434,22 @@ history_tokenize_word (string, ind)
return i;
}
if (ISDIGIT (string[i]))
{
j = i;
while (string[j] && ISDIGIT (string[j]))
j++;
if (string[j] == 0)
return (j);
if (string[j] == '<' || string[j] == '>')
i = j; /* digit sequence is a file descriptor */
else
{
i = j;
goto get_word; /* digit sequence is part of a word */
}
}
if (member (string[i], "<>;&|$"))
{
int peek = string[i + 1];
@ -1439,8 +1463,16 @@ history_tokenize_word (string, ind)
i += 2;
return i;
}
else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
(peek == '>' && string[i] == '&'))
else if (peek == '&' && (string[i] == '>' || string[i] == '<'))
{
j = i + 2;
while (string[j] && ISDIGIT (string[j])) /* file descriptor */
j++;
if (string[j] =='-') /* <&[digits]-, >&[digits]- */
j++;
return j;
}
else if ((peek == '>' && string[i] == '&') || (peek == '|' && string[i] == '>'))
{
i += 2;
return i;

View file

@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
/* Copyright (C) 1989-2016 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@ -35,6 +35,10 @@
#include <stdio.h>
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#include <sys/types.h>
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
@ -99,12 +103,41 @@ extern int errno;
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (PATH_MAX)
# define PATH_MAX 1024 /* default */
#endif
extern void _hs_append_history_line PARAMS((int, const char *));
/* history file version; currently unused */
int history_file_version = 1;
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* If non-zero, we assume that a history file that starts with a timestamp
uses timestamp-delimited entries and can include multi-line history
entries. Used by read_history_range */
int history_multiline_entries = 0;
/* Immediately after a call to read_history() or read_history_range(), this
will return the number of lines just read from the history file in that
call. */
int history_lines_read_from_file = 0;
/* Immediately after a call to write_history() or history_do_write(), this
will return the number of lines just written to the history file in that
call. This also works with history_truncate_file. */
int history_lines_written_to_file = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) )
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) )
static char *history_backupfile PARAMS((const char *));
static char *history_tempfile PARAMS((const char *));
static int histfile_backup PARAMS((const char *, const char *));
static int histfile_restore PARAMS((const char *, const char *));
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
@ -123,6 +156,10 @@ history_filename (filename)
return (return_val);
home = sh_get_env_value ("HOME");
#if defined (_WIN32)
if (home == 0)
home = sh_get_env_value ("APPDATA");
#endif
if (home == 0)
return (NULL);
@ -145,17 +182,71 @@ static char *
history_backupfile (filename)
const char *filename;
{
char *ret;
const char *fn;
char *ret, linkbuf[PATH_MAX+1];
size_t len;
ssize_t n;
struct stat fs;
len = strlen (filename);
fn = filename;
#if defined (HAVE_READLINK)
/* Follow symlink to avoid backing up symlink itself; call will fail if
not a symlink */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
fn = linkbuf;
}
#endif
len = strlen (fn);
ret = xmalloc (len + 2);
strcpy (ret, filename);
strcpy (ret, fn);
ret[len] = '-';
ret[len+1] = '\0';
return ret;
}
static char *
history_tempfile (filename)
const char *filename;
{
const char *fn;
char *ret, linkbuf[PATH_MAX+1];
size_t len;
ssize_t n;
struct stat fs;
int pid;
fn = filename;
#if defined (HAVE_READLINK)
/* Follow symlink so tempfile created in the same directory as any symlinked
history file; call will fail if not a symlink */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
fn = linkbuf;
}
#endif
len = strlen (fn);
ret = xmalloc (len + 11);
strcpy (ret, fn);
pid = (int)getpid ();
/* filename-PID.tmp */
ret[len] = '-';
ret[len+1] = (pid / 10000 % 10) + '0';
ret[len+2] = (pid / 1000 % 10) + '0';
ret[len+3] = (pid / 100 % 10) + '0';
ret[len+4] = (pid / 10 % 10) + '0';
ret[len+5] = (pid % 10) + '0';
strcpy (ret + len + 6, ".tmp");
return ret;
}
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
@ -178,7 +269,7 @@ read_history_range (filename, from, to)
{
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read;
int file, current_line, chars_read, has_timestamps, reset_comment_char;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
@ -189,6 +280,8 @@ read_history_range (filename, from, to)
int overflow_errno = EIO;
#endif
history_lines_read_from_file = 0;
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
@ -253,6 +346,19 @@ read_history_range (filename, from, to)
bufend = buffer + chars_read;
current_line = 0;
/* Heuristic: the history comment character rarely changes, so assume we
have timestamps if the buffer starts with `#[:digit:]' and temporarily
set history_comment_char so timestamp parsing works right */
reset_comment_char = 0;
if (history_comment_char == '\0' && buffer[0] == '#' && isdigit ((unsigned char)buffer[1]))
{
history_comment_char = '#';
reset_comment_char = 1;
}
has_timestamps = HIST_TIMESTAMP_START (buffer);
history_multiline_entries += has_timestamps && history_write_timestamps;
/* Skip lines until we are at FROM. */
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
@ -279,7 +385,10 @@ read_history_range (filename, from, to)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts == NULL && history_multiline_entries)
_hs_append_history_line (history_length - 1, line_start);
else
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
@ -301,6 +410,10 @@ read_history_range (filename, from, to)
line_start = line_end + 1;
}
history_lines_read_from_file = current_line;
if (reset_comment_char)
history_comment_char = '\0';
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
@ -311,23 +424,68 @@ read_history_range (filename, from, to)
return (0);
}
/* Save FILENAME to BACK, handling case where FILENAME is a symlink
(e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
static int
histfile_backup (filename, back)
const char *filename;
const char *back;
{
#if defined (HAVE_READLINK)
char linkbuf[PATH_MAX+1];
ssize_t n;
/* Follow to target of symlink to avoid renaming symlink itself */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
return (rename (linkbuf, back));
}
#endif
return (rename (filename, back));
}
/* Restore ORIG from BACKUP handling case where ORIG is a symlink
(e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
static int
histfile_restore (backup, orig)
const char *backup;
const char *orig;
{
#if defined (HAVE_READLINK)
char linkbuf[PATH_MAX+1];
ssize_t n;
/* Follow to target of symlink to avoid renaming symlink itself */
if ((n = readlink (orig, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
return (rename (backup, linkbuf));
}
#endif
return (rename (backup, orig));
}
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
on failure. */
If FNAME is NULL, then use ~/.history. Writes a new file and renames
it to the original name. Returns 0 on success, errno on failure. */
int
history_truncate_file (fname, lines)
const char *fname;
int lines;
{
char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv;
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv, orig_lines, exists, r;
struct stat finfo;
size_t file_size;
history_lines_written_to_file = 0;
buffer = (char *)NULL;
filename = history_filename (fname);
tempname = 0;
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = 0;
rv = exists = 0;
/* Don't try to truncate non-regular files. */
if (file == -1 || fstat (file, &finfo) == -1)
@ -337,6 +495,7 @@ history_truncate_file (fname, lines)
close (file);
goto truncate_exit;
}
exists = 1;
if (S_ISREG (finfo.st_mode) == 0)
{
@ -368,6 +527,7 @@ history_truncate_file (fname, lines)
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
rv = errno;
close (file);
goto truncate_exit;
}
@ -381,6 +541,7 @@ history_truncate_file (fname, lines)
goto truncate_exit;
}
orig_lines = lines;
/* Count backwards from the end of buffer until we have passed
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
@ -409,29 +570,56 @@ history_truncate_file (fname, lines)
/* Write only if there are more lines in the file than we want to
truncate to. */
if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
if (bp <= buffer)
{
rv = 0;
/* No-op if LINES == 0 at this point */
history_lines_written_to_file = orig_lines - lines;
goto truncate_exit;
}
tempname = history_tempfile (filename);
if ((file = open (tempname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1)
{
if (write (file, bp, chars_read - (bp - buffer)) < 0)
rv = errno;
#if defined (__BEOS__)
/* BeOS ignores O_TRUNC. */
ftruncate (file, chars_read - (bp - buffer));
#endif
if (close (file) < 0 && rv == 0)
rv = errno;
}
else
rv = errno;
truncate_exit:
FREE (buffer);
history_lines_written_to_file = orig_lines - lines;
if (rv == 0 && filename && tempname)
rv = histfile_restore (tempname, filename);
if (rv != 0)
{
if (tempname)
unlink (tempname);
history_lines_written_to_file = 0;
}
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists)
r = chown (filename, finfo.st_uid, finfo.st_gid);
xfree (filename);
FREE (tempname);
return rv;
}
/* Workhorse function for writing history. Writes NELEMENT entries
/* Workhorse function for writing history. Writes the last NELEMENT entries
from the history list to FILENAME. OVERWRITE is non-zero if you
wish to replace FILENAME with the entries. */
static int
@ -440,20 +628,23 @@ history_do_write (filename, nelements, overwrite)
int nelements, overwrite;
{
register int i;
char *output, *bakname;
int file, mode, rv;
char *output, *tempname, *histname;
int file, mode, rv, exists;
struct stat finfo;
#ifdef HISTORY_USE_MMAP
size_t cursize;
history_lines_written_to_file = 0;
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename);
bakname = (overwrite && output) ? history_backupfile (output) : 0;
histname = history_filename (filename);
exists = histname ? (stat (histname, &finfo) == 0) : 0;
if (output && bakname)
rename (output, bakname);
tempname = (overwrite && exists && S_ISREG (finfo.st_mode)) ? history_tempfile (histname) : 0;
output = tempname ? tempname : histname;
file = output ? open (output, mode, 0600) : -1;
rv = 0;
@ -461,10 +652,8 @@ history_do_write (filename, nelements, overwrite)
if (file == -1)
{
rv = errno;
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
FREE (histname);
FREE (tempname);
return (rv);
}
@ -506,10 +695,10 @@ history_do_write (filename, nelements, overwrite)
mmap_error:
rv = errno;
close (file);
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
if (tempname)
unlink (tempname);
FREE (histname);
FREE (tempname);
return rv;
}
#else
@ -518,10 +707,10 @@ mmap_error:
{
rv = errno;
close (file);
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
if (tempname)
unlink (tempname);
FREE (histname);
FREE (tempname);
return rv;
}
#endif
@ -540,7 +729,7 @@ mmap_error:
}
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else
if (write (file, buffer, buffer_size) < 0)
@ -549,16 +738,30 @@ mmap_error:
#endif
}
history_lines_written_to_file = nelements;
if (close (file) < 0 && rv == 0)
rv = errno;
if (rv != 0 && output && bakname)
rename (bakname, output);
else if (rv == 0 && bakname)
unlink (bakname);
if (rv == 0 && histname && tempname)
rv = histfile_restore (tempname, histname);
FREE (output);
FREE (bakname);
if (rv != 0)
{
if (tempname)
unlink (tempname);
history_lines_written_to_file = 0;
}
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists)
mode = chown (histname, finfo.st_uid, finfo.st_gid);
FREE (histname);
FREE (tempname);
return (rv);
}

View file

@ -76,7 +76,4 @@ extern char *strchr ();
#define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1
/* Some variable definitions shared across history source files. */
extern int history_offset;
#endif /* !_HISTLIB_H_ */

View file

@ -1,6 +1,6 @@
/* history.c -- standalone history library */
/* Copyright (C) 1989-2011 Free Software Foundation, Inc.
/* Copyright (C) 1989-2015 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@ -43,11 +43,20 @@
# include <unistd.h>
#endif
#include <errno.h>
#include "history.h"
#include "histlib.h"
#include "xmalloc.h"
#if !defined (errno)
extern int errno;
#endif
/* How big to make the_history when we first allocate it. */
#define DEFAULT_HISTORY_INITIAL_SIZE 502
/* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50
@ -236,7 +245,10 @@ history_get_time (hist)
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
errno = 0;
t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
if (errno == ERANGE)
return (time_t)0;
return t;
}
@ -279,9 +291,14 @@ add_history (string)
if (the_history[0])
(void) free_history_entry (the_history[0]);
/* Copy the rest of the entries, moving down one slot. */
/* Copy the rest of the entries, moving down one slot. Copy includes
trailing NULL. */
#if 0
for (i = 0; i < history_length; i++)
the_history[i] = the_history[i + 1];
#else
memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
#endif
history_base++;
}
@ -289,7 +306,10 @@ add_history (string)
{
if (history_size == 0)
{
history_size = DEFAULT_HISTORY_GROW_SIZE;
if (history_stifled && history_max_entries > 0)
history_size = history_max_entries + 2;
else
history_size = DEFAULT_HISTORY_INITIAL_SIZE;
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
history_length = 1;
}
@ -305,7 +325,7 @@ add_history (string)
}
}
temp = alloc_history_entry (string, hist_inittime ());
temp = alloc_history_entry ((char *)string, hist_inittime ());
the_history[history_length] = (HIST_ENTRY *)NULL;
the_history[history_length - 1] = temp;
@ -387,6 +407,30 @@ replace_history_entry (which, line, data)
return (old_value);
}
/* Append LINE to the history line at offset WHICH, adding a newline to the
end of the current line first. This can be used to construct multi-line
history entries while reading lines from the history file. */
void
_hs_append_history_line (which, line)
int which;
const char *line;
{
HIST_ENTRY *hent;
size_t newlen, curlen;
char *newline;
hent = the_history[which];
curlen = strlen (hent->line);
newlen = curlen + strlen (line) + 2;
newline = realloc (hent->line, newlen);
if (newline)
{
hent->line = newline;
hent->line[curlen++] = '\n';
strcpy (hent->line + curlen, line);
}
}
/* Replace the DATA in the specified history entries, replacing OLD with
NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
all of the history entries where entry->data == OLD; WHICH == -2 means
@ -394,7 +438,7 @@ replace_history_entry (which, line, data)
WHICH >= 0 means to replace that particular history entry's data, as
long as it matches OLD. */
void
replace_history_data (which, old, new)
_hs_replace_history_data (which, old, new)
int which;
histdata_t *old, *new;
{

View file

@ -1,6 +1,6 @@
/* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2015 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@ -91,6 +91,13 @@ extern void add_history_time PARAMS((const char *));
elements are numbered from 0. */
extern HIST_ENTRY *remove_history PARAMS((int));
/* Allocate a history entry consisting of STRING and TIMESTAMP and return
a pointer to it. */
extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *));
/* Copy the history entry H, but not the (opaque) data pointer */
extern HIST_ENTRY *copy_history_entry PARAMS((HIST_ENTRY *));
/* Free the history entry H and return any application-specific data
associated with it. */
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
@ -241,6 +248,11 @@ extern char **history_tokenize PARAMS((const char *));
extern int history_base;
extern int history_length;
extern int history_max_entries;
extern int history_offset;
extern int history_lines_read_from_file;
extern int history_lines_written_to_file;
extern char history_expansion_char;
extern char history_subst_char;
extern char *history_word_delimiters;
@ -251,6 +263,10 @@ extern int history_quotes_inhibit_expansion;
extern int history_write_timestamps;
/* These two are undocumented; the second is reserved for future use */
extern int history_multiline_entries;
extern int history_file_version;
/* Backwards compatibility */
extern int max_input_history;

View file

@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2013 Free Software Foundation, Inc.
/* Copyright (C) 1994-2015 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.
@ -95,6 +95,22 @@ static int ibuffer_space PARAMS((void));
static int rl_get_char PARAMS((int *));
static int rl_gather_tyi PARAMS((void));
/* Windows isatty returns true for every character device, including the null
device, so we need to perform additional checks. */
#if defined (_WIN32) && !defined (__CYGWIN__)
#include <io.h>
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
int
win32_isatty (int fd)
{
return (_isatty (fd) ? ((((long) (HANDLE) _get_osfhandle (fd)) & 3) == 3) : 0);
}
#define isatty(x) win32_isatty(x)
#endif
/* **************************************************************** */
/* */
/* Character Input Buffering */
@ -185,6 +201,7 @@ rl_gather_tyi ()
#endif
chars_avail = 0;
input = 0;
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
@ -199,11 +216,13 @@ rl_gather_tyi ()
#endif
result = -1;
#if defined (FIONREAD)
errno = 0;
#if defined (FIONREAD)
result = ioctl (tty, FIONREAD, &chars_avail);
if (result == -1 && errno == EIO)
return -1;
if (result == -1)
chars_avail = 0;
#endif
#if defined (O_NDELAY)
@ -217,6 +236,8 @@ rl_gather_tyi ()
fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN)
return 0;
if (chars_avail == -1 && errno == EIO)
return -1;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
@ -445,7 +466,7 @@ rl_read_key ()
if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
return (errno == EIO ? (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF) : '\n');
}
else if (r > 0) /* read something */
continue;
@ -474,6 +495,10 @@ rl_getc (stream)
{
int result;
unsigned char c;
#if defined (HAVE_PSELECT)
sigset_t empty_set;
fd_set readfds;
#endif
while (1)
{
@ -483,9 +508,17 @@ rl_getc (stream)
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (getch ());
return (_getch ()); /* "There is no error return." */
#endif
result = read (fileno (stream), &c, sizeof (unsigned char));
result = 0;
#if defined (HAVE_PSELECT)
sigemptyset (&empty_set);
FD_ZERO (&readfds);
FD_SET (fileno (stream), &readfds);
result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set);
#endif
if (result >= 0)
result = read (fileno (stream), &c, sizeof (unsigned char));
if (result == sizeof (unsigned char))
return (c);
@ -524,26 +557,42 @@ rl_getc (stream)
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
handle_error:
/* If the error that we received was EINTR, then try again,
this is simply an interrupted system call to read (). We allow
the read to be interrupted if we caught SIGHUP or SIGTERM (but
not SIGINT; let the signal handler deal with that), but if the
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
of the other signals readline treats specially. If the
application sets an event hook, call it for other signals.
Otherwise (not EINTR), some error occurred, also signifying EOF. */
if (errno != EINTR)
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* fatal signals of interest */
#if defined (SIGHUP)
else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
#else
else if (_rl_caught_signal == SIGTERM)
#endif
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
/* keyboard-generated signals of interest */
#if defined (SIGQUIT)
else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
#else
else if (_rl_caught_signal == SIGINT)
#endif
RL_CHECK_SIGNALS ();
/* non-keyboard-generated signals of interest */
#if defined (SIGWINCH)
else if (_rl_caught_signal == SIGWINCH)
RL_CHECK_SIGNALS ();
#endif /* SIGWINCH */
#if defined (SIGALRM)
else if (_rl_caught_signal == SIGALRM
#if defined (SIGVTALRM)
# if defined (SIGVTALRM)
|| _rl_caught_signal == SIGVTALRM
#endif
# endif
)
RL_CHECK_SIGNALS ();
#endif /* SIGALRM */
if (rl_signal_event_hook)
(*rl_signal_event_hook) ();

View file

@ -6,7 +6,7 @@
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -66,7 +66,6 @@ static int rl_search_history PARAMS((int, int));
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. Now part of isearch context. */
@ -553,8 +552,20 @@ add_character:
do until we have a real isearch-undo. */
if (cxt->search_string_index == 0)
rl_ding ();
else
else if (MB_CUR_MAX == 1 || rl_byte_oriented)
cxt->search_string[--cxt->search_string_index] = '\0';
else
{
wstart = _rl_find_prev_mbchar (cxt->search_string, cxt->search_string_index, MB_FIND_NONZERO);
if (wstart >= 0)
cxt->search_string[cxt->search_string_index = wstart] = '\0';
else
cxt->search_string[cxt->search_string_index = 0] = '\0';
}
if (cxt->search_string_index == 0)
rl_ding ();
break;
case -4: /* C-G, abort */
@ -647,6 +658,12 @@ add_character:
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
if (cxt->search_string_index == 0)
{
cxt->sflags |= SF_FAILED;
break;
}
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
@ -716,7 +733,7 @@ add_character:
return 1;
}
static int
int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;

View file

@ -1,6 +1,6 @@
/* kill.c -- kill ring management. */
/* Copyright (C) 1994 Free Software Foundation, Inc.
/* Copyright (C) 1994-2015 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.
@ -97,7 +97,7 @@ _rl_copy_to_kill_ring (text, append)
int slot;
/* First, find the slot to work with. */
if (_rl_last_command_was_kill == 0)
if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0)
{
/* Get a new slot. */
if (rl_kill_ring == 0)
@ -278,7 +278,7 @@ rl_backward_kill_line (direction, ignore)
return (rl_kill_line (1, ignore));
else
{
if (!rl_point)
if (rl_point == 0)
rl_ding ();
else
{
@ -506,7 +506,7 @@ rl_yank (count, ignore)
if (rl_kill_ring == 0)
{
_rl_abort_internal ();
return -1;
return 1;
}
_rl_set_mark_at_pos (rl_point);
@ -528,7 +528,7 @@ rl_yank_pop (count, key)
!rl_kill_ring)
{
_rl_abort_internal ();
return -1;
return 1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
@ -546,10 +546,44 @@ rl_yank_pop (count, key)
else
{
_rl_abort_internal ();
return -1;
return 1;
}
}
#if defined (VI_MODE)
int
rl_vi_yank_pop (count, key)
int count, key;
{
int l, n;
if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return 1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
n = rl_point - l;
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
rl_delete_text (n, rl_point);
rl_point = n;
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_vi_put (1, 'p');
return 0;
}
else
{
_rl_abort_internal ();
return 1;
}
}
#endif /* VI_MODE */
/* Yank the COUNTh argument from the previous history line, skipping
HISTORY_SKIP lines before looking for the `previous line'. */
static int
@ -575,7 +609,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
if (entry == 0)
{
rl_ding ();
return -1;
return 1;
}
arg = history_arg_extract (count, count, entry->line);
@ -583,7 +617,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
{
rl_ding ();
FREE (arg);
return -1;
return 1;
}
rl_begin_undo_group ();
@ -656,8 +690,58 @@ rl_yank_last_arg (count, key)
return retval;
}
/* A special paste command for users of Cygnus's cygwin32. */
#if defined (__CYGWIN__)
/* Having read the special escape sequence denoting the beginning of a
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and insert the pasted text as a single unit without
interpretation. */
int
rl_bracketed_paste_begin (count, key)
int count, key;
{
int retval, c;
size_t len, cap;
char *buf;
retval = 1;
len = 0;
buf = xmalloc (cap = 64);
RL_SETSTATE (RL_STATE_MOREINPUT);
while ((c = rl_read_key ()) >= 0)
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
_rl_add_macro_char (c);
if (c == '\r') /* XXX */
c = '\n';
if (len == cap)
buf = xrealloc (buf, cap *= 2);
buf[len++] = c;
if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST &&
STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN))
{
len -= BRACK_PASTE_SLEN;
break;
}
}
RL_UNSETSTATE (RL_STATE_MOREINPUT);
if (c >= 0)
{
if (len == cap)
buf = xrealloc (buf, cap + 1);
buf[len] = '\0';
retval = rl_insert_text (buf);
}
xfree (buf);
return (retval);
}
/* A special paste command for Windows users.. */
#if defined (_WIN32)
#include <windows.h>
int
@ -691,4 +775,4 @@ rl_paste_from_clipboard (count, key)
}
return (0);
}
#endif /* __CYGWIN__ */
#endif /* _WIN32 */

View file

@ -219,7 +219,7 @@ rl_start_kbd_macro (ignore1, ignore2)
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
_rl_abort_internal ();
return -1;
return 1;
}
if (rl_explicit_arg)
@ -244,7 +244,7 @@ rl_end_kbd_macro (count, ignore)
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
_rl_abort_internal ();
return -1;
return 1;
}
current_macro_index -= rl_key_sequence_length;

View file

@ -1,6 +1,6 @@
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
/* Copyright (C) 2001-2015 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.
@ -145,7 +145,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
return point;
}
static int
/*static*/ int
_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
char *string;
int seed, find_non_zero;

View file

@ -1,6 +1,6 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -56,8 +56,6 @@
static int rl_digit_loop PARAMS((void));
static void _rl_history_set_point PARAMS((void));
extern int history_offset;
/* Forward declarations used in this file */
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
@ -128,7 +126,7 @@ _rl_arg_dispatch (cxt, c)
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if ((cxt & NUM_SAWDIGITS) == 0)
{
@ -268,6 +266,8 @@ _rl_arg_callback (cxt)
int c, r;
c = _rl_arg_getchar ();
if (c < 0)
return (1); /* EOF */
if (_rl_argcxt & NUM_READONE)
{

View file

@ -1,6 +1,6 @@
/* parens.c -- implementation of matching parentheses feature. */
/* Copyright (C) 1987, 1989, 1992-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987, 1989, 1992-2015 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.
@ -57,11 +57,7 @@ static int find_matching_open PARAMS((char *, int, int));
/* Non-zero means try to blink the matching open parenthesis when the
close parenthesis is inserted. */
#if defined (HAVE_SELECT)
int rl_blink_matching_paren = 1;
#else /* !HAVE_SELECT */
int rl_blink_matching_paren = 0;
#endif /* !HAVE_SELECT */
static int _paren_blink_usec = 500000;
@ -72,16 +68,32 @@ _rl_enable_paren_matching (on_or_off)
int on_or_off;
{
if (on_or_off)
{ /* ([{ */
{
/* ([{ */
rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
#if defined (VI_MODE)
/* ([{ */
rl_bind_key_in_map (')', rl_insert_close, vi_insertion_keymap);
rl_bind_key_in_map (']', rl_insert_close, vi_insertion_keymap);
rl_bind_key_in_map ('}', rl_insert_close, vi_insertion_keymap);
#endif
}
else
{ /* ([{ */
{
/* ([{ */
rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
#if defined (VI_MODE)
/* ([{ */
rl_bind_key_in_map (')', rl_insert, vi_insertion_keymap);
rl_bind_key_in_map (']', rl_insert, vi_insertion_keymap);
rl_bind_key_in_map ('}', rl_insert, vi_insertion_keymap);
#endif
}
}
@ -117,7 +129,7 @@ rl_insert_close (count, invoking_key)
/* Emacs might message or ring the bell here, but I don't. */
if (match_point < 0)
return -1;
return 1;
FD_ZERO (&readfds);
FD_SET (fileno (rl_instream), &readfds);

View file

@ -1,6 +1,6 @@
/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -27,16 +27,20 @@
#if defined (HAVE_POSIX_SIGSETJMP)
# define procenv_t sigjmp_buf
# if !defined (__OPENNT)
# undef setjmp
# define setjmp(x) sigsetjmp((x), 1)
# define setjmp_nosigs(x) sigsetjmp((x), 0)
# undef longjmp
# define longjmp(x, n) siglongjmp((x), (n))
# endif /* !__OPENNT */
# define setjmp_nosigs(x) sigsetjmp((x), 0)
# define setjmp_sigs(x) sigsetjmp((x), 1)
# define _rl_longjmp(x, n) siglongjmp((x), (n))
# define sh_longjmp(x, n) siglongjmp((x), (n))
#else
# define procenv_t jmp_buf
# define setjmp_nosigs setjmp
# define setjmp_nosigs setjmp
# define setjmp_sigs setjmp
# define _rl_longjmp(x, n) longjmp((x), (n))
# define sh_longjmp(x, n) longjmp((x), (n))
#endif
#endif /* _POSIXJMP_H_ */

View file

@ -1,7 +1,7 @@
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -94,6 +94,8 @@ static void readline_initialize_everything PARAMS((void));
static void bind_arrow_keys_internal PARAMS((Keymap));
static void bind_arrow_keys PARAMS((void));
static void bind_bracketed_paste_prefix PARAMS((void));
static void readline_default_bindings PARAMS((void));
static void reset_default_bindings PARAMS((void));
@ -149,7 +151,7 @@ static int running_in_emacs;
#endif
/* Flags word encapsulating the current readline state. */
int rl_readline_state = RL_STATE_NONE;
unsigned long rl_readline_state = RL_STATE_NONE;
/* The current offset in the current input line. */
int rl_point;
@ -306,6 +308,11 @@ int _rl_echo_control_chars = 1;
the editing mode: @ for emacs, : for vi-command, + for vi-insert. */
int _rl_show_mode_in_prompt = 0;
/* Non-zero means to attempt to put the terminal in `bracketed paste mode',
where it will prefix pasted text with an escape sequence and send
another to mark the end of the paste. */
int _rl_enable_bracketed_paste = 0;
/* **************************************************************** */
/* */
/* Top Level Functions */
@ -379,7 +386,7 @@ readline (prompt)
RL_SETSTATE (RL_STATE_CALLBACK);
#endif
#if HAVE_DECL_AUDIT_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT)
#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT)
if (value)
_rl_audit_tty (value);
#endif
@ -525,10 +532,10 @@ readline_internal_charloop ()
static int lastc, eof_found;
int c, code, lk;
lastc = -1;
eof_found = 0;
lastc = EOF;
#if !defined (READLINE_CALLBACKS)
eof_found = 0;
while (rl_done == 0)
{
#endif
@ -556,8 +563,7 @@ readline_internal_charloop ()
{
/* Then initialize the argument and number of keys read. */
_rl_reset_argument ();
rl_key_sequence_length = 0;
rl_executing_keyseq[0] = 0;
rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
}
RL_SETSTATE(RL_STATE_READCMD);
@ -579,15 +585,36 @@ readline_internal_charloop ()
#endif
}
/* EOF typed to a non-blank line is a <NL>. If we want to change this,
to force any existing line to be ignored when read(2) reads EOF,
for example, this is the place to change. */
/* EOF typed to a non-blank line is ^D the first time, EOF the second
time in a row. This won't return any partial line read from the tty.
If we want to change this, to force any existing line to be returned
when read(2) reads EOF, for example, this is the place to change. */
if (c == EOF && rl_end)
c = NEWLINE;
{
if (RL_SIG_RECEIVED ())
{
RL_CHECK_SIGNALS ();
if (rl_signal_event_hook)
(*rl_signal_event_hook) (); /* XXX */
}
/* XXX - reading two consecutive EOFs returns EOF */
if (RL_ISSTATE (RL_STATE_TERMPREPPED))
{
if (lastc == _rl_eof_char || lastc == EOF)
rl_end = 0;
else
c = _rl_eof_char;
}
else
c = NEWLINE;
}
/* The character _rl_eof_char typed to blank line, and not as the
previous character is interpreted as EOF. */
if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
previous character is interpreted as EOF. This doesn't work when
READLINE_CALLBACKS is defined, so hitting a series of ^Ds will
erase all the chars on the line and then return EOF. */
if (((c == _rl_eof_char && lastc != c) || c == EOF) && rl_end == 0)
{
#if defined (READLINE_CALLBACKS)
RL_SETSTATE(RL_STATE_DONE);
@ -818,7 +845,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
/* Special case rl_do_lowercase_version (). */
if (func == rl_do_lowercase_version)
/* Should we do anything special if key == ANYOTHERKEY? */
return (_rl_dispatch (_rl_to_lower (key), map));
return (_rl_dispatch (_rl_to_lower ((unsigned char)key), map));
rl_executing_keymap = map;
rl_executing_key = key;
@ -888,8 +915,10 @@ _rl_dispatch_subseq (key, map, got_subseq)
default) or a timeout determined by the value of `keyseq-timeout' */
/* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
takes microseconds, so multiply by 1000 */
if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap
&& _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0)
if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap &&
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
_rl_pushed_input_available () == 0 &&
_rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0)
return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
#endif
@ -900,6 +929,16 @@ _rl_dispatch_subseq (key, map, got_subseq)
/* Allocate new context here. Use linked contexts (linked through
cxt->ocxt) to simulate recursion */
#if defined (READLINE_CALLBACKS)
# if defined (VI_MODE)
/* If we're redoing a vi mode command and we know there is a shadowed
function corresponding to this key, just call it -- all the redoable
vi mode commands already have all the input they need, and rl_vi_redo
assumes that one call to rl_dispatch is sufficient to complete the
command. */
if (_rl_vi_redoing && RL_ISSTATE (RL_STATE_CALLBACK) &&
map[ANYOTHERKEY].function != 0)
return (_rl_subseq_result (-2, map, key, got_subseq));
# endif
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* Return 0 only the first time, to indicate success to
@ -947,7 +986,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
}
else
{
_rl_abort_internal ();
_rl_abort_internal (); /* XXX */
return -1;
}
break;
@ -962,6 +1001,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
}
break;
}
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
key != ANYOTHERKEY &&
@ -994,22 +1034,27 @@ _rl_subseq_result (r, map, key, got_subseq)
type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
else if (type == ISFUNC && func == rl_insert)
r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map);
else if (type == ISFUNC)
{
/* If the function that was shadowed was self-insert, we
somehow need a keymap with map[key].func == self-insert.
Let's use this one. */
/* If we shadowed a function, whatever it is, we somehow need a
keymap with map[key].func == shadowed-function.
Let's use this one. Then we can dispatch using the original
key, since there are commands (e.g., in vi mode) for which it
matters. */
nt = m[key].type;
nf = m[key].function;
m[key].type = type;
m[key].function = func;
r = _rl_dispatch (key, m);
/* Don't change _rl_dispatching_keymap, set it here */
_rl_dispatching_keymap = map; /* previous map */
r = _rl_dispatch_subseq (key, m, 0);
m[key].type = nt;
m[key].function = nf;
}
else
/* We probably shadowed a keymap, so keep going. */
r = _rl_dispatch (ANYOTHERKEY, m);
}
else if (r && map[ANYOTHERKEY].function)
@ -1179,13 +1224,17 @@ readline_initialize_everything ()
/* Try to bind a common arrow key prefix, if not already bound. */
bind_arrow_keys ();
/* Bind the bracketed paste prefix assuming that the user will enable
it on terminals that support it. */
bind_bracketed_paste_prefix ();
/* If the completion parser's default word break characters haven't
been set yet, then do so now. */
if (rl_completer_word_break_characters == (char *)NULL)
rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
#if defined (COLOR_SUPPORT)
if (_rl_colored_stats)
if (_rl_colored_stats || _rl_colored_completion_prefix)
_rl_parse_colors ();
#endif
@ -1289,6 +1338,22 @@ bind_arrow_keys ()
#endif
}
static void
bind_bracketed_paste_prefix ()
{
Keymap xkeymap;
xkeymap = _rl_keymap;
_rl_keymap = emacs_standard_keymap;
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
_rl_keymap = vi_insertion_keymap;
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
_rl_keymap = xkeymap;
}
/* **************************************************************** */
/* */
/* Saving and Restoring Readline's state */
@ -1317,6 +1382,7 @@ rl_save_state (sp)
sp->lastfunc = rl_last_func;
sp->insmode = rl_insert_mode;
sp->edmode = rl_editing_mode;
sp->kseq = rl_executing_keyseq;
sp->kseqlen = rl_key_sequence_length;
sp->inf = rl_instream;
sp->outf = rl_outstream;
@ -1326,6 +1392,12 @@ rl_save_state (sp)
sp->catchsigs = rl_catch_signals;
sp->catchsigwinch = rl_catch_sigwinch;
sp->entryfunc = rl_completion_entry_function;
sp->menuentryfunc = rl_menu_completion_entry_function;
sp->ignorefunc = rl_ignore_some_completions_function;
sp->attemptfunc = rl_attempted_completion_function;
sp->wordbreakchars = rl_completer_word_break_characters;
return (0);
}
@ -1351,6 +1423,7 @@ rl_restore_state (sp)
rl_last_func = sp->lastfunc;
rl_insert_mode = sp->insmode;
rl_editing_mode = sp->edmode;
rl_executing_keyseq = sp->kseq;
rl_key_sequence_length = sp->kseqlen;
rl_instream = sp->inf;
rl_outstream = sp->outf;
@ -1360,5 +1433,11 @@ rl_restore_state (sp)
rl_catch_signals = sp->catchsigs;
rl_catch_sigwinch = sp->catchsigwinch;
rl_completion_entry_function = sp->entryfunc;
rl_menu_completion_entry_function = sp->menuentryfunc;
rl_ignore_some_completions_function = sp->ignorefunc;
rl_attempted_completion_function = sp->attemptfunc;
rl_completer_word_break_characters = sp->wordbreakchars;
return (0);
}

View file

@ -1,6 +1,6 @@
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -39,9 +39,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0603 /* Readline 6.3 */
#define RL_VERSION_MAJOR 6
#define RL_VERSION_MINOR 3
#define RL_READLINE_VERSION 0x0700 /* Readline 7.0 */
#define RL_VERSION_MAJOR 7
#define RL_VERSION_MINOR 0
/* Readline data structures. */
@ -172,8 +172,9 @@ extern int rl_yank PARAMS((int, int));
extern int rl_yank_pop PARAMS((int, int));
extern int rl_yank_nth_arg PARAMS((int, int));
extern int rl_yank_last_arg PARAMS((int, int));
/* Not available unless __CYGWIN__ is defined. */
#ifdef __CYGWIN__
extern int rl_bracketed_paste_begin PARAMS((int, int));
/* Not available unless _WIN32 is defined. */
#if defined (_WIN32)
extern int rl_paste_from_clipboard PARAMS((int, int));
#endif
@ -219,6 +220,7 @@ extern int rl_insert_close PARAMS((int, int));
extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
extern void rl_callback_read_char PARAMS((void));
extern void rl_callback_handler_remove PARAMS((void));
extern void rl_callback_sigcleanup PARAMS((void));
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */
@ -247,9 +249,11 @@ extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_yank_pop PARAMS((int, int));
extern int rl_vi_rubout PARAMS((int, int));
extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_unix_word_rubout PARAMS((int, int));
extern int rl_vi_first_print PARAMS((int, int));
extern int rl_vi_char_search PARAMS((int, int));
extern int rl_vi_match PARAMS((int, int));
@ -375,6 +379,7 @@ extern void rl_redisplay PARAMS((void));
extern int rl_on_new_line PARAMS((void));
extern int rl_on_new_line_with_prompt PARAMS((void));
extern int rl_forced_update_display PARAMS((void));
extern int rl_clear_visible_line PARAMS((void));
extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
@ -389,6 +394,7 @@ extern int rl_show_char PARAMS((int));
/* Undocumented in texinfo manual. */
extern int rl_character_len PARAMS((int, int));
extern void rl_redraw_prompt_last_line PARAMS((void));
/* Save and restore internal prompt redisplay information. */
extern void rl_save_prompt PARAMS((void));
@ -436,6 +442,8 @@ extern void rl_cleanup_after_signal PARAMS((void));
extern void rl_reset_after_signal PARAMS((void));
extern void rl_free_line_state PARAMS((void));
extern int rl_pending_signal PARAMS((void));
extern void rl_echo_signal_char PARAMS((int));
extern int rl_set_paren_blink_timeout PARAMS((int));
@ -489,7 +497,7 @@ extern int rl_readline_version; /* e.g., 0x0402 */
extern int rl_gnu_readline_p;
/* Flags word encapsulating the current readline state. */
extern int rl_readline_state;
extern unsigned long rl_readline_state;
/* Says which editing mode readline is currently using. 1 means emacs mode;
0 means vi mode. */
@ -634,7 +642,7 @@ extern rl_compentry_func_t *rl_completion_entry_function;
/* Optional generator for menu completion. Default is
rl_completion_entry_function (rl_filename_completion_function). */
extern rl_compentry_func_t *rl_menu_completion_entry_function;
extern rl_compentry_func_t *rl_menu_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been
@ -826,6 +834,14 @@ extern int rl_ignore_completion_duplicates;
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
/* Applications can set this to non-zero to have readline's signal handlers
installed during the entire duration of reading a complete line, as in
readline-6.2. This should be used with care, because it can result in
readline receiving signals and not handling them until it's called again
via rl_callback_read_char, thereby stealing them from the application.
By default, signal handlers are only active while readline is active. */
extern int rl_persistent_signal_handlers;
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
@ -866,9 +882,10 @@ extern int rl_inhibit_completion;
#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */
#define RL_STATE_REDISPLAYING 0x0800000 /* updating terminal display */
#define RL_STATE_CHARSEARCH 0x0800000 /* vi mode char search */
#define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */
#define RL_STATE_DONE 0x1000000 /* done; accepted line */
#define RL_STATE_DONE 0x2000000 /* done; accepted line */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
@ -879,8 +896,8 @@ struct readline_state {
int point;
int end;
int mark;
char *buffer;
int buflen;
char *buffer;
UNDO_LIST *ul;
char *prompt;
@ -893,10 +910,12 @@ struct readline_state {
rl_command_func_t *lastfunc;
int insmode;
int edmode;
char *kseq;
int kseqlen;
int pendingin;
FILE *inf;
FILE *outf;
int pendingin;
char *macro;
/* signal state */
@ -906,9 +925,16 @@ struct readline_state {
/* search state */
/* completion state */
rl_compentry_func_t *entryfunc;
rl_compentry_func_t *menuentryfunc;
rl_compignore_func_t *ignorefunc;
rl_completion_func_t *attemptfunc;
char *wordbreakchars;
/* options state */
/* hook state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};

View file

@ -1,6 +1,6 @@
/* rlconf.h -- readline configuration definitions */
/* Copyright (C) 1992-2012 Free Software Foundation, Inc.
/* Copyright (C) 1992-2015 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.
@ -64,6 +64,16 @@
/* Define this if you want to enable code that talks to the Linux kernel
tty auditing system. */
#define ENABLE_TTY_AUDIT_SUPPORT
/* #define ENABLE_TTY_AUDIT_SUPPORT */
/* Defaults for the various editing mode indicators, inserted at the beginning
of the last (maybe only) line of the prompt if show-mode-in-prompt is on */
#define RL_EMACS_MODESTR_DEFAULT "@"
#define RL_EMACS_MODESTR_DEFLEN 1
#define RL_VI_INS_MODESTR_DEFAULT "(ins)"
#define RL_VI_INS_MODESTR_DEFLEN 5
#define RL_VI_CMD_MODESTR_DEFAULT "(cmd)"
#define RL_VI_CMD_MODESTR_DEFLEN 5
#endif /* _RLCONF_H_ */

View file

@ -1,6 +1,6 @@
/* rlmbutil.h -- utility functions for multibyte characters. */
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
/* Copyright (C) 2001-2015 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.
@ -123,13 +123,53 @@ extern int _rl_walphabetic PARAMS((wchar_t));
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
/* Try and shortcut the printable ascii characters to cut down the number of
calls to a libc wcwidth() */
static inline int
_rl_wcwidth (wc)
wchar_t wc;
{
switch (wc)
{
case ' ': case '!': case '"': case '#': case '%':
case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':': case ';': case '<': case '=': case '>':
case '?':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '[': case '\\': case ']': case '^': case '_':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z': case '{': case '|': case '}': case '~':
return 1;
default:
return wcwidth (wc);
}
}
/* Unicode combining characters range from U+0300 to U+036F */
#define UNICODE_COMBINING_CHAR(x) ((x) >= 768 && (x) <= 879)
#if defined (WCWIDTH_BROKEN)
# define WCWIDTH(wc) ((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : wcwidth(wc))
# define WCWIDTH(wc) ((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : _rl_wcwidth(wc))
#else
# define WCWIDTH(wc) wcwidth(wc)
# define WCWIDTH(wc) _rl_wcwidth(wc)
#endif
#if defined (WCWIDTH_BROKEN)
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0 && iswcntrl(x) == 0)
#else
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0)
#endif
#else /* !HANDLE_MULTIBYTE */

View file

@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2012 Free Software Foundation, Inc.
/* Copyright (C) 1999-2015 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.
@ -44,6 +44,7 @@
#define RL_SIG_RECEIVED() (_rl_caught_signal != 0)
#define RL_SIGINT_RECEIVED() (_rl_caught_signal == SIGINT)
#define RL_SIGWINCH_RECEIVED() (_rl_caught_signal == SIGWINCH)
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
@ -124,10 +125,11 @@ typedef struct __rl_keyseq_context
int flags;
int subseq_arg;
int subseq_retval; /* XXX */
Keymap dmap;
Keymap oldmap;
int okey;
Keymap dmap;
Keymap oldmap;
struct __rl_keyseq_context *ocxt;
int childval;
} _rl_keyseq_cxt;
@ -185,6 +187,7 @@ extern int rl_visible_stats;
#endif /* VISIBLE_STATS */
#if defined (COLOR_SUPPORT)
extern int _rl_colored_stats;
extern int _rl_colored_completion_prefix;
#endif
/* readline.c */
@ -290,9 +293,20 @@ extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
extern int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* kill.c */
#define BRACK_PASTE_PREF "\033[200~"
#define BRACK_PASTE_SUFF "\033[201~"
#define BRACK_PASTE_LAST '~'
#define BRACK_PASTE_SLEN 6
#define BRACK_PASTE_INIT "\033[?2004h"
#define BRACK_PASTE_FINI "\033[?2004l"
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_next_macro_key PARAMS((void));
@ -334,6 +348,7 @@ extern int _rl_restore_tty_signals PARAMS((void));
/* search.c */
extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
extern int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
/* signals.c */
extern void _rl_signal_handler PARAMS((int));
@ -410,8 +425,10 @@ extern void _rl_vi_initialize_line PARAMS((void));
extern void _rl_vi_reset_last PARAMS((void));
extern void _rl_vi_set_last PARAMS((int, int, int));
extern int _rl_vi_textmod_command PARAMS((int));
extern int _rl_vi_motion_command PARAMS((int));
extern void _rl_vi_done_inserting PARAMS((void));
extern int _rl_vi_domove_callback PARAMS((_rl_vimotion_cxt *));
extern int _rl_vi_domove_motion_cleanup PARAMS((int, _rl_vimotion_cxt *));
/*************************************************************************
* Undocumented private variables *
@ -446,6 +463,13 @@ extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
extern char *_rl_emacs_mode_str;
extern int _rl_emacs_modestr_len;
extern char *_rl_vi_ins_mode_str;
extern int _rl_vi_ins_modestr_len;
extern char *_rl_vi_cmd_mode_str;
extern int _rl_vi_cmd_modestr_len;
/* isearch.c */
extern char *_rl_isearch_terminators;
@ -475,6 +499,7 @@ extern int _rl_bind_stty_chars;
extern int _rl_revert_all_at_newline;
extern int _rl_echo_control_chars;
extern int _rl_show_mode_in_prompt;
extern int _rl_enable_bracketed_paste;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
@ -524,12 +549,16 @@ extern int _rl_screenchars;
extern int _rl_terminal_can_insert;
extern int _rl_term_autowrap;
/* text.c */
extern int _rl_optimize_typeahead;
/* undo.c */
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
extern int _rl_vi_redoing;
extern _rl_vimotion_cxt *_rl_vimvcxt;
#endif /* _RL_PRIVATE_H_ */

View file

@ -1,10 +1,10 @@
/* rltty.c -- functions to prepare and restore the terminal for readline's
use. */
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
/* Copyright (C) 1992-2016 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.
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,11 +37,11 @@
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
#include "rltty.h"
#if defined (HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h> /* include for declaration of ioctl */
#endif
#include "readline.h"
#include "rlprivate.h"
@ -60,7 +60,13 @@ static void set_winsize PARAMS((int));
/* */
/* **************************************************************** */
/* Non-zero means that the terminal is in a prepped state. */
/* Non-zero means that the terminal is in a prepped state. There are several
flags that are OR'd in to denote whether or not we have sent various
init strings to the terminal. */
#define TPX_PREPPED 0x01
#define TPX_BRACKPASTE 0x02
#define TPX_METAKEY 0x04
static int terminal_prepped;
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
@ -595,7 +601,7 @@ void
rl_prep_terminal (meta_flag)
int meta_flag;
{
int tty;
int tty, nprep;
TIOTYPE tio;
if (terminal_prepped)
@ -642,7 +648,7 @@ rl_prep_terminal (meta_flag)
/* If editing in vi mode, make sure we set the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
else
#endif
_rl_bind_tty_special_chars (_rl_keymap, tio);
@ -659,8 +665,16 @@ rl_prep_terminal (meta_flag)
if (_rl_enable_keypad)
_rl_control_keypad (1);
nprep = TPX_PREPPED;
if (_rl_enable_bracketed_paste)
{
fprintf (rl_outstream, BRACK_PASTE_INIT);
nprep |= TPX_BRACKPASTE;
}
fflush (rl_outstream);
terminal_prepped = 1;
terminal_prepped = nprep;
RL_SETSTATE(RL_STATE_TERMPREPPED);
_rl_release_sigint ();
@ -672,7 +686,7 @@ rl_deprep_terminal ()
{
int tty;
if (!terminal_prepped)
if (terminal_prepped == 0)
return;
/* Try to keep this function from being interrupted. */
@ -680,6 +694,9 @@ rl_deprep_terminal ()
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (terminal_prepped & TPX_BRACKPASTE)
fprintf (rl_outstream, BRACK_PASTE_FINI);
if (_rl_enable_keypad)
_rl_control_keypad (0);
@ -697,6 +714,19 @@ rl_deprep_terminal ()
_rl_release_sigint ();
}
#endif /* !NO_TTY_DRIVER */
/* Set readline's idea of whether or not it is echoing output to the terminal,
returning the old value. */
int
rl_tty_set_echoing (u)
int u;
{
int o;
o = _rl_echoing_p;
_rl_echoing_p = u;
return o;
}
/* **************************************************************** */
/* */
@ -859,6 +889,11 @@ _rl_bind_tty_special_chars (kmap, ttybuff)
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
# if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
SET_SPECIAL (VWERASE, rl_vi_unix_word_rubout);
else
# endif
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}

View file

@ -26,6 +26,25 @@
extern "C" {
#endif
/* Old-style, attempt to mark as deprecated in some way people will notice. */
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
#if defined(__GNUC__) || defined(__clang__)
typedef int Function () __attribute__ ((deprecated));
typedef void VFunction () __attribute__ ((deprecated));
typedef char *CPFunction () __attribute__ ((deprecated));
typedef char **CPPFunction () __attribute__ ((deprecated));
#else
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif
#endif /* _FUNCTION_DEF */
/* New style. */
#if !defined (_RL_FUNCTION_TYPEDEF)

View file

@ -1,6 +1,6 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992-2013 Free Software Foundation, Inc.
/* Copyright (C) 1992-2015 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.
@ -58,7 +58,7 @@ _rl_search_cxt *_rl_nscxt = 0;
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Functions imported from the rest of the library. */
extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos;
@ -80,7 +80,6 @@ static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((int));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
@ -224,7 +223,7 @@ _rl_nsearch_init (dir, pchar)
return cxt;
}
static int
int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
@ -411,7 +410,7 @@ rl_noninc_forward_search_again (count, key)
if (!noninc_search_string)
{
rl_ding ();
return (-1);
return (1);
}
r = noninc_dosearch (noninc_search_string, 1);
return (r != 1);
@ -428,7 +427,7 @@ rl_noninc_reverse_search_again (count, key)
if (!noninc_search_string)
{
rl_ding ();
return (-1);
return (1);
}
r = noninc_dosearch (noninc_search_string, -1);
return (r != 1);

View file

@ -1,6 +1,6 @@
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -213,15 +213,31 @@ _rl_handle_signal (sig)
case SIGINT:
_rl_reset_completion_state ();
rl_free_line_state ();
#if defined (READLINE_CALLBACKS)
rl_callback_sigcleanup ();
#endif
/* FALLTHROUGH */
case SIGTERM:
case SIGHUP:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
# if defined (HAVE_POSIX_SIGNALS)
/* Block SIGTTOU so we can restore the terminal settings to something
sane without stopping on SIGTTOU if we have been placed into the
background. Even trying to get the current terminal pgrp with
tcgetpgrp() will generate SIGTTOU, so we don't bother. Don't bother
doing this if we've been stopped on SIGTTOU; it's aready too late. */
sigemptyset (&set);
sigaddset (&set, SIGTTOU);
sigprocmask (SIG_BLOCK, &set, (sigset_t *)NULL);
# endif
case SIGTTOU:
#endif /* SIGTSTP */
case SIGTERM:
#if defined (SIGHUP)
case SIGHUP:
#endif
#if defined (SIGALRM)
case SIGALRM:
#endif
@ -232,6 +248,10 @@ _rl_handle_signal (sig)
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
/* Unblock SIGTTOU blocked above */
if (sig == SIGTTIN || sig == SIGTSTP)
sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL);
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
@ -397,7 +417,9 @@ rl_set_signals ()
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGTERM);
#if defined (SIGHUP)
sigaddset (&bset, SIGHUP);
#endif
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
@ -426,7 +448,9 @@ rl_set_signals ()
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGHUP)
rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
#endif
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
@ -491,7 +515,9 @@ rl_clear_signals ()
overhead */
rl_maybe_restore_sighandler (SIGINT, &old_int);
rl_maybe_restore_sighandler (SIGTERM, &old_term);
#if defined (SIGHUP)
rl_maybe_restore_sighandler (SIGHUP, &old_hup);
#endif
#if defined (SIGQUIT)
rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
#endif
@ -567,6 +593,11 @@ rl_free_line_state ()
_rl_reset_argument ();
}
int
rl_pending_signal ()
{
return (_rl_caught_signal);
}
#endif /* HANDLE_SIGNALS */
/* **************************************************************** */

View file

@ -1,6 +1,6 @@
/* tcap.h -- termcap library functions and variables. */
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
/* Copyright (C) 1996-2015 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.
@ -31,6 +31,8 @@
# include "rltty.h"
# endif
# include <termcap.h>
#elif defined (HAVE_NCURSES_TERMCAP_H)
# include <ncurses/termcap.h>
#else
/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.

View file

@ -1,6 +1,6 @@
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
/* Copyright (C) 1996-2015 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.
@ -51,15 +51,14 @@
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
#ifdef __MSDOS__
# include <pc.h>
#endif
#include "rltty.h"
#if defined (HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h> /* include for declaration of ioctl */
#endif
#include "tcap.h"
/* Some standard library routines. */

View file

@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -71,6 +71,8 @@ static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
rl_insert_text. Text blocks larger than this are divided. */
#define TEXT_COUNT_MAX 1024
int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */
/* **************************************************************** */
/* */
/* Insert and Delete */
@ -570,7 +572,7 @@ rl_refresh_line (ignore1, ignore2)
_rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
rl_forced_update_display ();
rl_redraw_prompt_last_line ();
rl_display_fixed = 1;
return 0;
@ -608,7 +610,7 @@ rl_skip_csi_sequence (count, key)
while (ch >= 0x20 && ch < 0x40);
RL_UNSETSTATE (RL_STATE_MOREINPUT);
return 0;
return (ch < 0);
}
int
@ -620,6 +622,8 @@ rl_arrow_keys (count, c)
RL_SETSTATE(RL_STATE_MOREINPUT);
ch = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (ch < 0)
return (1);
switch (_rl_to_upper (ch))
{
@ -890,8 +894,49 @@ int
rl_insert (count, c)
int count, c;
{
return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
: _rl_overwrite_char (count, c));
int r, n, x;
r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (count, c) : _rl_overwrite_char (count, c);
/* XXX -- attempt to batch-insert pending input that maps to self-insert */
x = 0;
n = (unsigned short)-2;
while (_rl_optimize_typeahead &&
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
_rl_pushed_input_available () == 0 &&
_rl_input_queued (0) &&
(n = rl_read_key ()) > 0 &&
_rl_keymap[(unsigned char)n].type == ISFUNC &&
_rl_keymap[(unsigned char)n].function == rl_insert)
{
r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (1, n) : _rl_overwrite_char (1, n);
/* _rl_insert_char keeps its own set of pending characters to compose a
complete multibyte character, and only returns 1 if it sees a character
that's part of a multibyte character but too short to complete one. We
can try to read another character in the hopes that we will get the
next one or just punt. Right now we try to read another character.
We don't want to call rl_insert_next if _rl_insert_char has already
stored the character in the pending_bytes array because that will
result in doubled input. */
n = (unsigned short)-2;
x++; /* count of bytes of typeahead read, currently unused */
if (r == 1) /* read partial multibyte character */
continue;
if (rl_done || r != 0)
break;
}
if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */
{
/* setting rl_pending_input inhibits setting rl_last_func so we do it
ourselves here */
rl_last_func = rl_insert;
_rl_reset_argument ();
rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
r = rl_execute_next (n);
}
return r;
}
/* Insert the next typed character verbatim. */
@ -906,7 +951,7 @@ _rl_insert_next (count)
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
return -1;
return 1;
if (RL_ISSTATE (RL_STATE_MACRODEF))
_rl_add_macro_char (c);
@ -1066,7 +1111,7 @@ rl_rubout (count, key)
if (!rl_point)
{
rl_ding ();
return -1;
return 1;
}
if (rl_insert_mode == RL_IM_OVERWRITE)
@ -1089,7 +1134,7 @@ _rl_rubout_char (count, key)
if (rl_point == 0)
{
rl_ding ();
return -1;
return 1;
}
orig_point = rl_point;
@ -1103,7 +1148,7 @@ _rl_rubout_char (count, key)
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, orig_point);
/* The erase-at-end-of-line hack is of questionable merit now. */
if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
{
int l;
l = rl_character_len (c, rl_point);
@ -1133,7 +1178,7 @@ rl_delete (count, key)
if (rl_point == rl_end)
{
rl_ding ();
return -1;
return 1;
}
if (count > 1 || rl_explicit_arg)
@ -1303,7 +1348,7 @@ rl_change_case (count, op)
if (op != UpCase && op != DownCase && op != CapCase)
{
rl_ding ();
return -1;
return 1;
}
if (count < 0)
@ -1337,7 +1382,7 @@ rl_change_case (count, op)
}
else
nop = op;
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c))
{
nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
rl_line_buffer[start] = nc;
@ -1403,7 +1448,7 @@ rl_transpose_words (count, key)
{
rl_ding ();
rl_point = orig_point;
return -1;
return 1;
}
/* Get the text of the words. */
@ -1456,7 +1501,7 @@ rl_transpose_chars (count, key)
if (!rl_point || rl_end < 2)
{
rl_ding ();
return -1;
return 1;
}
rl_begin_undo_group ();
@ -1519,7 +1564,7 @@ _rl_char_search_internal (count, dir, schar)
#endif
if (dir == 0)
return -1;
return 1;
pos = rl_point;
inc = (dir < 0) ? -1 : 1;
@ -1528,7 +1573,7 @@ _rl_char_search_internal (count, dir, schar)
if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
{
rl_ding ();
return -1;
return 1;
}
#if defined (HANDLE_MULTIBYTE)
@ -1583,7 +1628,7 @@ _rl_char_search (count, fdir, bdir)
mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
if (mb_len <= 0)
return -1;
return 1;
if (count < 0)
return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
@ -1602,7 +1647,7 @@ _rl_char_search (count, fdir, bdir)
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
return -1;
return 1;
if (count < 0)
return (_rl_char_search_internal (-count, bdir, c));
@ -1671,7 +1716,7 @@ _rl_set_mark_at_pos (position)
int position;
{
if (position > rl_end)
return -1;
return 1;
rl_mark = position;
return 0;
@ -1696,7 +1741,7 @@ rl_exchange_point_and_mark (count, key)
if (rl_mark == -1)
{
rl_ding ();
return -1;
return 1;
}
else
SWAP (rl_point, rl_mark);

View file

@ -236,7 +236,11 @@ tilde_expand (string)
string += end;
expansion = tilde_expand_word (tilde_word);
xfree (tilde_word);
if (expansion == 0)
expansion = tilde_word;
else
xfree (tilde_word);
len = strlen (expansion);
#ifdef __CYGWIN__
@ -360,6 +364,10 @@ tilde_expand_word (filename)
{
/* Prefix $HOME to the rest of the string. */
expansion = sh_get_env_value ("HOME");
#if defined (_WIN32)
if (expansion == 0)
expansion = sh_get_env_value ("APPDATA");
#endif
/* If there is no HOME variable, look up the directory in
the password database. */

View file

@ -1,7 +1,6 @@
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* undo.c - manage list of changes to lines, offering opportunity to undo them */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -50,7 +49,7 @@
#include "rlprivate.h"
#include "xmalloc.h"
extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *));
extern void _hs_replace_history_data PARAMS((int, histdata_t *, histdata_t *));
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */
@ -129,7 +128,7 @@ rl_free_undo_list ()
orig_list = rl_undo_list;
_rl_free_undo_list (rl_undo_list);
rl_undo_list = (UNDO_LIST *)NULL;
replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
_hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
}
UNDO_LIST *
@ -245,7 +244,7 @@ rl_do_undo ()
xfree (temp);
}
replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
_hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
xfree (release);
}

View file

@ -1,6 +1,6 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 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.
@ -55,6 +55,7 @@
#include "rlprivate.h"
#include "xmalloc.h"
#include "rlshell.h"
/* **************************************************************** */
/* */
@ -107,12 +108,11 @@ _rl_abort_internal ()
while (rl_executing_macro)
_rl_pop_executing_macro ();
RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */
rl_last_func = (rl_command_func_t *)NULL;
#if defined (HAVE_POSIX_SIGSETJMP)
siglongjmp (_rl_top_level, 1);
#else
longjmp (_rl_top_level, 1);
#endif
_rl_longjmp (_rl_top_level, 1);
return (0);
}
@ -198,12 +198,14 @@ rl_tilde_expand (ignore, key)
xfree (homedir);
return (0);
}
else if (rl_line_buffer[start] != '~')
else if (start >= 0 && rl_line_buffer[start] != '~')
{
for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
;
start++;
}
else if (start < 0)
start = 0;
end = start;
do
@ -476,6 +478,7 @@ _rl_savestring (s)
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
}
#if defined (DEBUG)
#if defined (USE_VARARGS)
static FILE *_rl_tracefp;
@ -511,11 +514,18 @@ _rl_trace (va_alist)
int
_rl_tropen ()
{
char fnbuf[128];
char fnbuf[128], *x;
if (_rl_tracefp)
fclose (_rl_tracefp);
sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid());
#if defined (_WIN32) && !defined (__CYGWIN__)
x = sh_get_env_value ("TEMP");
if (x == 0)
x = ".";
#else
x = "/var/tmp";
#endif
sprintf (fnbuf, "%s/rltrace.%ld", x, (long)getpid());
unlink(fnbuf);
_rl_tracefp = fopen (fnbuf, "w+");
return _rl_tracefp != 0;
@ -538,10 +548,12 @@ _rl_settracefp (fp)
_rl_tracefp = fp;
}
#endif
#endif /* DEBUG */
#if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT)
#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT)
#include <sys/socket.h>
#include <libaudit.h>
#include <linux/audit.h>
#include <linux/netlink.h>
@ -550,42 +562,33 @@ void
_rl_audit_tty (string)
char *string;
{
struct audit_message req;
struct sockaddr_nl addr;
struct msghdr msg;
struct nlmsghdr nlm;
struct iovec iov[2];
size_t size;
int fd;
fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
if (fd < 0)
return;
size = strlen (string) + 1;
nlm.nlmsg_len = NLMSG_LENGTH (size);
nlm.nlmsg_type = AUDIT_USER_TTY;
nlm.nlmsg_flags = NLM_F_REQUEST;
nlm.nlmsg_seq = 0;
nlm.nlmsg_pid = 0;
if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH)
return;
iov[0].iov_base = &nlm;
iov[0].iov_len = sizeof (nlm);
iov[1].iov_base = string;
iov[1].iov_len = size;
memset (&req, 0, sizeof(req));
req.nlh.nlmsg_len = NLMSG_SPACE (size);
req.nlh.nlmsg_type = AUDIT_USER_TTY;
req.nlh.nlmsg_flags = NLM_F_REQUEST;
req.nlh.nlmsg_seq = 0;
if (size && string)
memcpy (NLMSG_DATA(&req.nlh), string, size);
memset (&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_pid = 0;
addr.nl_groups = 0;
msg.msg_name = &addr;
msg.msg_namelen = sizeof (addr);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
(void)sendmsg (fd, &msg, 0);
sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
close (fd);
}
#endif

View file

@ -1,6 +1,6 @@
/* vi_keymap.c -- the keymap for vi_mode in readline (). */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -55,7 +55,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISFUNC, rl_vi_unix_word_rubout }, /* Control-w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
@ -334,7 +334,7 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISFUNC, rl_vi_unix_word_rubout }, /* Control-w */
{ ISFUNC, rl_insert }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, rl_insert }, /* Control-z */

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-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 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.
@ -67,6 +67,9 @@ int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
_rl_vimotion_cxt *_rl_vimvcxt = 0;
/* Non-zero indicates we are redoing a vi-mode command with `.' */
int _rl_vi_redoing;
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@ -100,8 +103,6 @@ static int _rl_vi_last_replacement;
static int _rl_vi_last_key_before_insert;
static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
@ -192,6 +193,13 @@ _rl_vi_textmod_command (c)
return (member (c, vi_textmod));
}
int
_rl_vi_motion_command (c)
int c;
{
return (member (c, vi_motion));
}
static void
_rl_vi_replace_insert (count)
int count;
@ -234,7 +242,7 @@ rl_vi_redo (count, c)
}
r = 0;
vi_redoing = 1;
_rl_vi_redoing = 1;
/* If we're redoing an insert with `i', stuff in the inserted text
and do not go into insertion mode. */
if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
@ -280,7 +288,8 @@ rl_vi_redo (count, c)
}
else
r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
vi_redoing = 0;
_rl_vi_redoing = 0;
return (r);
}
@ -464,7 +473,7 @@ rl_vi_end_word (count, key)
if (count < 0)
{
rl_ding ();
return -1;
return 1;
}
if (_rl_uppercase_p (key))
@ -1089,28 +1098,55 @@ static int
rl_domove_motion_callback (m)
_rl_vimotion_cxt *m;
{
int c, save, r;
int old_end;
int c;
_rl_vi_last_motion = c = m->motion;
/* Append a blank character temporarily so that the motion routines
work right at the end of the line. */
old_end = rl_end;
work right at the end of the line. Original value of rl_end is saved
as m->end. */
rl_line_buffer[rl_end++] = ' ';
rl_line_buffer[rl_end] = '\0';
_rl_dispatch (c, _rl_keymap);
/* Remove the blank that we added. */
rl_end = old_end;
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* Messy case where char search can be vi motion command; see rest of
details in callback.c. vi_char_search and callback_char_search just
set and unset the CHARSEARCH state. This is where any vi motion
command that needs to set its own state should be handled, with any
corresponding code to manage that state in callback.c */
if (RL_ISSTATE (RL_STATE_CHARSEARCH))
return 0;
else
return (_rl_vi_domove_motion_cleanup (c, m));
}
#endif
return (_rl_vi_domove_motion_cleanup (c, m));
}
int
_rl_vi_domove_motion_cleanup (c, m)
int c;
_rl_vimotion_cxt *m;
{
int r;
/* Remove the blank that we added in rl_domove_motion_callback. */
rl_end = m->end;
rl_line_buffer[rl_end] = '\0';
if (rl_point > rl_end)
rl_point = rl_end;
/* No change in position means the command failed. */
if (rl_mark == rl_point)
return (-1);
{
RL_UNSETSTATE (RL_STATE_VIMOTION);
return (-1);
}
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
word. If we are not at the end of the line, and we are on a
@ -1244,8 +1280,8 @@ _rl_vi_domove_callback (m)
int c, r;
m->motion = c = rl_vi_domove_getchar (m);
/* XXX - what to do if this returns -1? Should we return 1 for eof to
callback code? */
if (c < 0)
return 1; /* EOF */
r = rl_domove_read_callback (m);
return ((r == 0) ? r : 1); /* normalize return values */
@ -1301,12 +1337,12 @@ rl_vi_delete_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing && _rl_vi_last_motion != 'd') /* `dd' is special */
else if (_rl_vi_redoing && _rl_vi_last_motion != 'd') /* `dd' is special */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing) /* handle redoing `dd' here */
else if (_rl_vi_redoing) /* handle redoing `dd' here */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
rl_mark = rl_end;
@ -1351,7 +1387,7 @@ vi_change_dispatch (m)
if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
rl_point = m->start;
if (vi_redoing)
if (_rl_vi_redoing)
{
if (vi_insert_buffer && *vi_insert_buffer)
rl_begin_undo_group ();
@ -1391,12 +1427,12 @@ rl_vi_change_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing && _rl_vi_last_motion != 'c') /* `cc' is special */
else if (_rl_vi_redoing && _rl_vi_last_motion != 'c') /* `cc' is special */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing) /* handle redoing `cc' here */
else if (_rl_vi_redoing) /* handle redoing `cc' here */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
rl_mark = rl_end;
@ -1460,12 +1496,12 @@ rl_vi_yank_to (count, key)
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing && _rl_vi_last_motion != 'y') /* `yy' is special */
else if (_rl_vi_redoing && _rl_vi_last_motion != 'y') /* `yy' is special */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing) /* handle redoing `yy' here */
else if (_rl_vi_redoing) /* handle redoing `yy' here */
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
rl_mark = rl_end;
@ -1534,7 +1570,7 @@ rl_vi_rubout (count, key)
if (rl_point == 0)
{
rl_ding ();
return -1;
return 1;
}
opoint = rl_point;
@ -1565,7 +1601,7 @@ rl_vi_delete (count, key)
if (rl_end == 0)
{
rl_ding ();
return -1;
return 1;
}
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@ -1584,6 +1620,62 @@ rl_vi_delete (count, key)
return (0);
}
/* This does what Posix specifies vi-mode C-w to do: using whitespace and
punctuation characters as the word boundaries. */
#define vi_unix_word_boundary(c) (whitespace(c) || ispunct(c))
int
rl_vi_unix_word_rubout (count, key)
int count, key;
{
int orig_point;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
/* This isn't quite what ksh93 does but it seems to match what the
Posix description of sh specifies, with a few accommodations
for sequences of whitespace characters between words and at
the end of the line. */
/* Skip over whitespace at the end of the line as a special case */
if (rl_point > 0 && (rl_line_buffer[rl_point] == 0) &&
whitespace (rl_line_buffer[rl_point - 1]))
while (--rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
;
/* If we're at the start of a word, move back to word boundary so we
move back to the `preceding' word */
if (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) &&
vi_unix_word_boundary (rl_line_buffer[rl_point - 1]))
rl_point--;
/* If we are at a word boundary (whitespace/punct), move backward
past a sequence of word boundary characters. If we are at the
end of a word (non-word boundary), move back to a word boundary */
if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]))
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--;
}
rl_kill_text (orig_point, rl_point);
}
return 0;
}
int
rl_vi_back_to_indent (count, key)
int count, key;
@ -1618,7 +1710,10 @@ _rl_vi_callback_char_search (data)
#endif
if (c <= 0)
return -1;
{
RL_UNSETSTATE (RL_STATE_CHARSEARCH);
return -1;
}
#if !defined (HANDLE_MULTIBYTE)
_rl_vi_last_search_char = c;
@ -1626,6 +1721,7 @@ _rl_vi_callback_char_search (data)
_rl_callback_func = 0;
_rl_want_redisplay = 1;
RL_UNSETSTATE (RL_STATE_CHARSEARCH);
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
@ -1650,13 +1746,13 @@ rl_vi_char_search (count, key)
if (key == ';' || key == ',')
{
if (_rl_cs_orig_dir == 0)
return -1;
return 1;
#if defined (HANDLE_MULTIBYTE)
if (_rl_vi_last_search_mblen == 0)
return -1;
return 1;
#else
if (_rl_vi_last_search_char == 0)
return -1;
return 1;
#endif
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
}
@ -1681,7 +1777,7 @@ rl_vi_char_search (count, key)
break;
}
if (vi_redoing)
if (_rl_vi_redoing)
{
/* set target and tlen below */
}
@ -1690,7 +1786,9 @@ rl_vi_char_search (count, key)
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
_rl_callback_data->i2 = key;
_rl_callback_func = _rl_vi_callback_char_search;
RL_SETSTATE (RL_STATE_CHARSEARCH);
return (0);
}
#endif
@ -1755,7 +1853,7 @@ rl_vi_match (ignore, key)
{
rl_point = pos;
rl_ding ();
return -1;
return 1;
}
}
@ -1785,7 +1883,7 @@ rl_vi_match (ignore, key)
else
{
rl_ding ();
return -1;
return 1;
}
}
}
@ -1809,7 +1907,7 @@ rl_vi_match (ignore, key)
else
{
rl_ding ();
return -1;
return 1;
}
}
}
@ -1915,7 +2013,7 @@ rl_vi_change_char (count, key)
int c;
char mb[MB_LEN_MAX];
if (vi_redoing)
if (_rl_vi_redoing)
{
c = _rl_vi_last_replacement;
mb[0] = c;
@ -1943,7 +2041,7 @@ rl_vi_subst (count, key)
int count, key;
{
/* If we are redoing, rl_vi_change_to will stuff the last motion char */
if (vi_redoing == 0)
if (_rl_vi_redoing == 0)
rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
return (rl_vi_change_to (count, 'c'));
@ -2083,7 +2181,7 @@ _rl_vi_set_mark ()
if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
{
rl_ding ();
return -1;
return 1;
}
ch -= 'a';
vi_mark_chars[ch] = rl_point;
@ -2135,14 +2233,14 @@ _rl_vi_goto_mark ()
else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
{
rl_ding ();
return -1;
return 1;
}
ch -= 'a';
if (vi_mark_chars[ch] == -1)
{
rl_ding ();
return -1;
return 1;
}
rl_point = vi_mark_chars[ch];
return 0;