mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-06 10:12:38 +02:00
Imported from ../bash-2.05b.tar.gz.
This commit is contained in:
@@ -73,20 +73,22 @@ CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
|
||||
$(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \
|
||||
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
|
||||
$(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \
|
||||
$(srcdir)/compat.c
|
||||
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
|
||||
$(srcdir)/mbutil.c
|
||||
|
||||
# The header files for this library.
|
||||
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
|
||||
posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \
|
||||
ansi_stdlib.h rlstdc.h tcap.h xmalloc.h rlprivate.h rlshell.h \
|
||||
rltypedefs.h
|
||||
rltypedefs.h rlmbutil.h
|
||||
|
||||
HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o
|
||||
HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o \
|
||||
mbutil.o
|
||||
TILDEOBJ = tilde.o
|
||||
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
|
||||
rltty.o complete.o bind.o isearch.o display.o signals.o \
|
||||
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
|
||||
nls.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o compat.o
|
||||
text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o compat.o
|
||||
|
||||
# The texinfo files which document this library.
|
||||
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
|
||||
@@ -203,6 +205,11 @@ macro.o: ansi_stdlib.h
|
||||
macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
|
||||
macro.o: history.h rlstdc.h
|
||||
mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h rlmbutil.h
|
||||
mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h
|
||||
misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
|
||||
misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
misc.o: history.h rlstdc.h ansi_stdlib.h
|
||||
nls.o: ansi_stdlib.h
|
||||
nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
|
||||
@@ -228,6 +235,10 @@ terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
terminal.o: tcap.h
|
||||
terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
|
||||
terminal.o: history.h rlstdc.h
|
||||
text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
|
||||
text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
text.o: history.h rlstdc.h ansi_stdlib.h
|
||||
rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
|
||||
tilde.o: ansi_stdlib.h
|
||||
tilde.o: ${BUILD_DIR}/config.h
|
||||
tilde.o: tilde.h
|
||||
@@ -259,6 +270,8 @@ input.o: rlprivate.h
|
||||
isearch.o: rlprivate.h
|
||||
kill.o: rlprivate.h
|
||||
macro.o: rlprivate.h
|
||||
mbutil.o: rlprivate.h
|
||||
misc.o: rlprivate.h
|
||||
nls.o: rlprivate.h
|
||||
parens.o: rlprivate.h
|
||||
readline.o: rlprivate.h
|
||||
@@ -266,6 +279,7 @@ rltty.o: rlprivate.h
|
||||
search.o: rlprivate.h
|
||||
signals.o: rlprivate.h
|
||||
terminal.o: rlprivate.h
|
||||
text.o: rlprivate.h
|
||||
undo.o: rlprivate.h
|
||||
util.o: rlprivate.h
|
||||
vi_mode.o: rlprivate.h
|
||||
@@ -282,14 +296,31 @@ isearch.o: xmalloc.h
|
||||
keymaps.o: xmalloc.h
|
||||
kill.o: xmalloc.h
|
||||
macro.o: xmalloc.h
|
||||
mbutil.o: xmalloc.h
|
||||
misc.o: xmalloc.h
|
||||
readline.o: xmalloc.h
|
||||
savestring.o: xmalloc.h
|
||||
search.o: xmalloc.h
|
||||
shell.o: xmalloc.h
|
||||
tilde.o: xmalloc.h
|
||||
terminal.o: xmalloc.h
|
||||
text.o: xmalloc.h
|
||||
tilde.o: xmalloc.h
|
||||
undo.o: xmalloc.h
|
||||
util.o: xmalloc.h
|
||||
vi_mode.o: xmalloc.h
|
||||
xmalloc.o: xmalloc.h
|
||||
|
||||
complete.o: rlmbutil.h
|
||||
display.o: rlmbutil.h
|
||||
histexpand.o: rlmbutil.h
|
||||
input.o: rlmbutil.h
|
||||
isearch.o: rlmbutil.h
|
||||
mbutil.o: rlmbutil.h
|
||||
misc.o: rlmbutil.h
|
||||
readline.o: rlmbutil.h
|
||||
search.o: rlmbutil.h
|
||||
text.o: rlmbutil.h
|
||||
vi_mode.o: rlmbutil.h
|
||||
|
||||
# Rules for deficient makes, like SunOS and Solaris
|
||||
bind.o: bind.c
|
||||
@@ -298,15 +329,13 @@ compat.o: compat.c
|
||||
complete.o: complete.c
|
||||
display.o: display.c
|
||||
funmap.o: funmap.c
|
||||
histexpand.o: histexpand.c
|
||||
histfile.o: histfile.c
|
||||
history.o: history.c
|
||||
histsearch.o: histsearch.c
|
||||
input.o: input.c
|
||||
isearch.o: isearch.c
|
||||
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c
|
||||
kill.o: kill.c
|
||||
macro.o: macro.c
|
||||
mbutil.o: mbutil.c
|
||||
misc.o: misc.c
|
||||
nls.o: nls.c
|
||||
parens.o: parens.c
|
||||
readline.o: readline.c
|
||||
@@ -316,8 +345,14 @@ search.o: search.c
|
||||
shell.o: shell.c
|
||||
signals.o: signals.c
|
||||
terminal.o: terminal.c
|
||||
text.o: terminal.c
|
||||
tilde.o: tilde.c
|
||||
undo.o: undo.c
|
||||
util.o: util.c
|
||||
vi_mode.o: vi_mode.c
|
||||
xmalloc.o: xmalloc.c
|
||||
|
||||
histexpand.o: histexpand.c
|
||||
histfile.o: histfile.c
|
||||
history.o: history.c
|
||||
histsearch.o: histsearch.c
|
||||
|
||||
+73
-41
@@ -68,6 +68,8 @@ extern char *strchr (), *strrchr ();
|
||||
/* Variables exported by this file. */
|
||||
Keymap rl_binding_keymap;
|
||||
|
||||
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 *));
|
||||
static int substring_member_of_array PARAMS((char *, const char **));
|
||||
@@ -246,6 +248,9 @@ rl_generic_bind (type, keyseq, data, map)
|
||||
char *keys;
|
||||
int keys_len;
|
||||
register int i;
|
||||
KEYMAP_ENTRY k;
|
||||
|
||||
k.function = 0;
|
||||
|
||||
/* If no keys to bind to, exit right away. */
|
||||
if (!keyseq || !*keyseq)
|
||||
@@ -269,7 +274,12 @@ rl_generic_bind (type, keyseq, data, map)
|
||||
/* Bind keys, making new keymaps as necessary. */
|
||||
for (i = 0; i < keys_len; i++)
|
||||
{
|
||||
unsigned char ic = keys[i];
|
||||
unsigned char uc = keys[i];
|
||||
int ic;
|
||||
|
||||
ic = uc;
|
||||
if (ic < 0 || ic >= KEYMAP_SIZE)
|
||||
return -1;
|
||||
|
||||
if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
|
||||
{
|
||||
@@ -282,18 +292,40 @@ rl_generic_bind (type, keyseq, data, map)
|
||||
{
|
||||
if (map[ic].type != ISKMAP)
|
||||
{
|
||||
if (map[ic].type == ISMACR)
|
||||
free ((char *)map[ic].function);
|
||||
/* We allow subsequences of keys. If a keymap is being
|
||||
created that will `shadow' an existing function or macro
|
||||
key binding, we save that keybinding into the ANYOTHERKEY
|
||||
index in the new map. The dispatch code will look there
|
||||
to find the function to execute if the subsequence is not
|
||||
matched. ANYOTHERKEY was chosen to be greater than
|
||||
UCHAR_MAX. */
|
||||
k = map[ic];
|
||||
|
||||
map[ic].type = ISKMAP;
|
||||
map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
|
||||
}
|
||||
map = FUNCTION_TO_KEYMAP (map, ic);
|
||||
/* The dispatch code will return this function if no matching
|
||||
key sequence is found in the keymap. This (with a little
|
||||
help from the dispatch code in readline.c) allows `a' to be
|
||||
mapped to something, `abc' to be mapped to something else,
|
||||
and the function bound to `a' to be executed when the user
|
||||
types `abx', leaving `bx' in the input queue. */
|
||||
if (k.function /* && k.type == ISFUNC */)
|
||||
{
|
||||
map[ANYOTHERKEY] = k;
|
||||
k.function = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (map[ic].type == ISMACR)
|
||||
free ((char *)map[ic].function);
|
||||
else if (map[ic].type == ISKMAP)
|
||||
{
|
||||
map = FUNCTION_TO_KEYMAP (map, ic);
|
||||
ic = ANYOTHERKEY;
|
||||
}
|
||||
|
||||
map[ic].function = KEYMAP_TO_FUNCTION (data);
|
||||
map[ic].type = type;
|
||||
@@ -331,7 +363,7 @@ rl_translate_keyseq (seq, array, len)
|
||||
/* Handle special case of backwards define. */
|
||||
if (strncmp (&seq[i], "C-\\M-", 5) == 0)
|
||||
{
|
||||
array[l++] = ESC;
|
||||
array[l++] = ESC; /* ESC is meta-prefix */
|
||||
i += 5;
|
||||
array[l++] = CTRL (_rl_to_upper (seq[i]));
|
||||
if (seq[i] == '\0')
|
||||
@@ -340,7 +372,7 @@ rl_translate_keyseq (seq, array, len)
|
||||
else if (c == 'M')
|
||||
{
|
||||
i++;
|
||||
array[l++] = ESC; /* XXX */
|
||||
array[l++] = ESC; /* ESC is meta-prefix */
|
||||
}
|
||||
else if (c == 'C')
|
||||
{
|
||||
@@ -632,25 +664,15 @@ _rl_read_file (filename, sizep)
|
||||
i = read (file, buffer, file_size);
|
||||
close (file);
|
||||
|
||||
#if 0
|
||||
if (i < file_size)
|
||||
#else
|
||||
if (i < 0)
|
||||
#endif
|
||||
{
|
||||
free (buffer);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
buffer[file_size] = '\0';
|
||||
if (sizep)
|
||||
*sizep = file_size;
|
||||
#else
|
||||
buffer[i] = '\0';
|
||||
if (sizep)
|
||||
*sizep = i;
|
||||
#endif
|
||||
|
||||
return (buffer);
|
||||
}
|
||||
@@ -767,7 +789,7 @@ _rl_read_init_file (filename, include_level)
|
||||
|
||||
static void
|
||||
_rl_init_file_error (msg)
|
||||
char *msg;
|
||||
const char *msg;
|
||||
{
|
||||
if (currently_reading_init_file)
|
||||
fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file,
|
||||
@@ -1075,7 +1097,7 @@ rl_parse_and_bind (string)
|
||||
/* Make VAR point to start of variable name. */
|
||||
while (*var && whitespace (*var)) var++;
|
||||
|
||||
/* Make value point to start of value string. */
|
||||
/* Make VALUE point to start of value string. */
|
||||
value = var;
|
||||
while (*value && !whitespace (*value)) value++;
|
||||
if (*value)
|
||||
@@ -1240,6 +1262,7 @@ static struct {
|
||||
int flags;
|
||||
} boolean_varlist [] = {
|
||||
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
|
||||
{ "byte-oriented", &rl_byte_oriented, 0 },
|
||||
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
|
||||
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
|
||||
{ "disable-completion", &rl_inhibit_completion, 0 },
|
||||
@@ -1250,9 +1273,11 @@ static struct {
|
||||
{ "input-meta", &_rl_meta_flag, 0 },
|
||||
{ "mark-directories", &_rl_complete_mark_directories, 0 },
|
||||
{ "mark-modified-lines", &_rl_mark_modified_lines, 0 },
|
||||
{ "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
|
||||
{ "match-hidden-files", &_rl_match_hidden_files, 0 },
|
||||
{ "meta-flag", &_rl_meta_flag, 0 },
|
||||
{ "output-meta", &_rl_output_meta_chars, 0 },
|
||||
{ "page-completions", &_rl_page_completions, 0 },
|
||||
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
|
||||
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
|
||||
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
|
||||
@@ -1264,7 +1289,7 @@ static struct {
|
||||
|
||||
static int
|
||||
find_boolean_var (name)
|
||||
char *name;
|
||||
const char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1333,7 +1358,7 @@ static struct {
|
||||
|
||||
static int
|
||||
find_string_var (name)
|
||||
char *name;
|
||||
const char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1659,17 +1684,18 @@ _rl_get_keyname (key)
|
||||
pairs for possible inclusion in an inputrc file, we don't want to
|
||||
do any special meta processing on KEY. */
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* XXX - Experimental */
|
||||
/* We might want to do this, but the old version of the code did not. */
|
||||
|
||||
/* If this is an escape character, we don't want to do any more processing.
|
||||
Just add the special ESC key sequence and return. */
|
||||
if (c == ESC)
|
||||
{
|
||||
keyseq[0] = '\\';
|
||||
keyseq[1] = 'e';
|
||||
keyseq[2] = '\0';
|
||||
return keyseq;
|
||||
keyname[0] = '\\';
|
||||
keyname[1] = 'e';
|
||||
keyname[2] = '\0';
|
||||
return keyname;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1780,7 +1806,12 @@ rl_invoking_keyseqs_in_map (function, map)
|
||||
char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
|
||||
|
||||
if (key == ESC)
|
||||
#if 0
|
||||
sprintf (keyname, "\\e");
|
||||
#else
|
||||
/* XXX - experimental */
|
||||
sprintf (keyname, "\\M-");
|
||||
#endif
|
||||
else if (CTRL_CHAR (key))
|
||||
sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
|
||||
else if (key == RUBOUT)
|
||||
@@ -1927,11 +1958,8 @@ _rl_macro_dumper_internal (print_readably, map, prefix)
|
||||
{
|
||||
case ISMACR:
|
||||
keyname = _rl_get_keyname (key);
|
||||
#if 0
|
||||
out = (char *)map[key].function;
|
||||
#else
|
||||
out = _rl_untranslate_macro_value ((char *)map[key].function);
|
||||
#endif
|
||||
|
||||
if (print_readably)
|
||||
fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
|
||||
keyname,
|
||||
@@ -1941,9 +1969,7 @@ _rl_macro_dumper_internal (print_readably, map, prefix)
|
||||
keyname,
|
||||
out ? out : "");
|
||||
free (keyname);
|
||||
#if 1
|
||||
free (out);
|
||||
#endif
|
||||
break;
|
||||
case ISFUNC:
|
||||
break;
|
||||
@@ -2033,7 +2059,7 @@ rl_variable_dumper (print_readably)
|
||||
if (print_readably)
|
||||
fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
|
||||
else
|
||||
fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : "");
|
||||
fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
|
||||
|
||||
/* completion-query-items */
|
||||
if (print_readably)
|
||||
@@ -2047,15 +2073,6 @@ rl_variable_dumper (print_readably)
|
||||
else
|
||||
fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
|
||||
|
||||
/* keymap */
|
||||
kname = rl_get_keymap_name (_rl_keymap);
|
||||
if (kname == 0)
|
||||
kname = rl_get_keymap_name_from_edit_mode ();
|
||||
if (print_readably)
|
||||
fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
|
||||
else
|
||||
fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
|
||||
|
||||
/* isearch-terminators */
|
||||
if (_rl_isearch_terminators)
|
||||
{
|
||||
@@ -2070,6 +2087,15 @@ rl_variable_dumper (print_readably)
|
||||
|
||||
free (disp);
|
||||
}
|
||||
|
||||
/* keymap */
|
||||
kname = rl_get_keymap_name (_rl_keymap);
|
||||
if (kname == 0)
|
||||
kname = rl_get_keymap_name_from_edit_mode ();
|
||||
if (print_readably)
|
||||
fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
|
||||
else
|
||||
fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
|
||||
}
|
||||
|
||||
/* Print all of the current variables and their values to
|
||||
@@ -2086,7 +2112,9 @@ rl_dump_variables (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. */
|
||||
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
|
||||
now, this is always used to attempt to bind the arrow keys, hence the
|
||||
check for rl_vi_movement_mode. */
|
||||
void
|
||||
_rl_bind_if_unbound (keyseq, default_func)
|
||||
const char *keyseq;
|
||||
@@ -2097,7 +2125,11 @@ _rl_bind_if_unbound (keyseq, default_func)
|
||||
if (keyseq)
|
||||
{
|
||||
func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
|
||||
#if defined (VI_MODE)
|
||||
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
|
||||
#else
|
||||
if (!func || func == rl_do_lowercase_version)
|
||||
#endif
|
||||
rl_set_key (keyseq, default_func, _rl_keymap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef CTRL
|
||||
#undef CTRL
|
||||
# undef CTRL
|
||||
#endif
|
||||
#ifdef UNCTRL
|
||||
# undef UNCTRL
|
||||
#endif
|
||||
|
||||
/* Some character stuff. */
|
||||
@@ -76,6 +79,9 @@
|
||||
|
||||
#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
|
||||
|
||||
/* Some systems define these; we want our definitions. */
|
||||
#undef ISPRINT
|
||||
|
||||
#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))
|
||||
|
||||
+218
-36
@@ -55,6 +55,7 @@ extern int errno;
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
@@ -100,10 +101,11 @@ static int stat_char PARAMS((char *));
|
||||
|
||||
static char *rl_quote_filename PARAMS((char *, int, char *));
|
||||
|
||||
static int get_y_or_n PARAMS((void));
|
||||
static void set_completion_defaults PARAMS((int));
|
||||
static int get_y_or_n PARAMS((int));
|
||||
static int _rl_internal_pager PARAMS((int));
|
||||
static char *printable_part PARAMS((char *));
|
||||
static int print_filename PARAMS((char *, char *));
|
||||
static char find_completion_word PARAMS((int *, int *));
|
||||
|
||||
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
|
||||
|
||||
@@ -116,7 +118,6 @@ static int compute_lcd_of_matches PARAMS((char **, int, const char *));
|
||||
static int postprocess_matches PARAMS((char ***, int));
|
||||
|
||||
static char *make_quoted_replacement PARAMS((char *, int, char *));
|
||||
static void free_match_list PARAMS((char **));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -132,6 +133,12 @@ int _rl_complete_show_all = 0;
|
||||
/* If non-zero, completed directory names have a slash appended. */
|
||||
int _rl_complete_mark_directories = 1;
|
||||
|
||||
/* If non-zero, the symlinked directory completion behavior introduced in
|
||||
readline-4.2a is disabled, and symlinks that point to directories have
|
||||
a slash appended (subject to the value of _rl_complete_mark_directories).
|
||||
This is user-settable via the mark-symlinked-directories variable. */
|
||||
int _rl_complete_mark_symlink_dirs = 0;
|
||||
|
||||
/* If non-zero, completions are printed horizontally in alphabetical order,
|
||||
like `ls -x'. */
|
||||
int _rl_print_completions_horizontally;
|
||||
@@ -194,10 +201,12 @@ int rl_completion_type = 0;
|
||||
she is sure she wants to see them all. */
|
||||
int rl_completion_query_items = 100;
|
||||
|
||||
int _rl_page_completions = 1;
|
||||
|
||||
/* The basic list of characters that signal a break between words for the
|
||||
completer routine. The contents of this variable is what breaks words
|
||||
in the shell, i.e. " \t\n\"\\'`@$><=" */
|
||||
const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
|
||||
const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
|
||||
|
||||
/* List of basic quoting characters. */
|
||||
const char *rl_basic_quote_characters = "\"'";
|
||||
@@ -264,10 +273,26 @@ rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
|
||||
completer. */
|
||||
rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
|
||||
|
||||
/* If non-zero, the completion functions don't append anything except a
|
||||
possible closing quote. This is set to 0 by rl_complete_internal and
|
||||
may be changed by an application-specific completion function. */
|
||||
int rl_completion_suppress_append = 0;
|
||||
|
||||
/* Character appended to completed words when at the end of the line. The
|
||||
default is a space. */
|
||||
int rl_completion_append_character = ' ';
|
||||
|
||||
/* If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
mark-directories variable (which is user-settable). This exists so
|
||||
that application completion functions can override the user's preference
|
||||
(set via the mark-symlinked-directories variable) if appropriate.
|
||||
It's set to the value of _rl_complete_mark_symlink_dirs in
|
||||
rl_complete_internal before any application-specific completion
|
||||
function is called, so without that function doing anything, the user's
|
||||
preferences are honored. */
|
||||
int rl_completion_mark_symlink_dirs;
|
||||
|
||||
/* If non-zero, inhibit completion (temporarily). */
|
||||
int rl_inhibit_completion;
|
||||
|
||||
@@ -290,7 +315,7 @@ rl_complete (ignore, invoking_key)
|
||||
int ignore, invoking_key;
|
||||
{
|
||||
if (rl_inhibit_completion)
|
||||
return (rl_insert (ignore, invoking_key));
|
||||
return (_rl_insert_char (ignore, invoking_key));
|
||||
else if (rl_last_func == rl_complete && !completion_changed_buffer)
|
||||
return (rl_complete_internal ('?'));
|
||||
else if (_rl_complete_show_all)
|
||||
@@ -314,15 +339,49 @@ rl_insert_completions (ignore, invoking_key)
|
||||
return (rl_complete_internal ('*'));
|
||||
}
|
||||
|
||||
/* Return the correct value to pass to rl_complete_internal performing
|
||||
the same tests as rl_complete. This allows consecutive calls to an
|
||||
application's completion function to list possible completions and for
|
||||
an application-specific completion function to honor the
|
||||
show-all-if-ambiguous readline variable. */
|
||||
int
|
||||
rl_completion_mode (cfunc)
|
||||
rl_command_func_t *cfunc;
|
||||
{
|
||||
if (rl_last_func == cfunc && !completion_changed_buffer)
|
||||
return '?';
|
||||
else if (_rl_complete_show_all)
|
||||
return '!';
|
||||
else
|
||||
return TAB;
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* */
|
||||
/* Completion utility functions */
|
||||
/* */
|
||||
/************************************/
|
||||
|
||||
/* Set default values for readline word completion. These are the variables
|
||||
that application completion functions can change or inspect. */
|
||||
static void
|
||||
set_completion_defaults (what_to_do)
|
||||
int what_to_do;
|
||||
{
|
||||
/* Only the completion entry function can change these. */
|
||||
rl_filename_completion_desired = 0;
|
||||
rl_filename_quoting_desired = 1;
|
||||
rl_completion_type = what_to_do;
|
||||
rl_completion_suppress_append = 0;
|
||||
|
||||
/* The completion entry function may optionally change this. */
|
||||
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
|
||||
}
|
||||
|
||||
/* The user must press "y" or "n". Non-zero return means "y" pressed. */
|
||||
static int
|
||||
get_y_or_n ()
|
||||
get_y_or_n (for_pager)
|
||||
int for_pager;
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -338,10 +397,32 @@ get_y_or_n ()
|
||||
return (0);
|
||||
if (c == ABORT_CHAR)
|
||||
_rl_abort_internal ();
|
||||
if (for_pager && (c == NEWLINE || c == RETURN))
|
||||
return (2);
|
||||
if (for_pager && (c == 'q' || c == 'Q'))
|
||||
return (0);
|
||||
rl_ding ();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_rl_internal_pager (lines)
|
||||
int lines;
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (rl_outstream, "--More--");
|
||||
fflush (rl_outstream);
|
||||
i = get_y_or_n (1);
|
||||
_rl_erase_entire_line ();
|
||||
if (i == 0)
|
||||
return -1;
|
||||
else if (i == 2)
|
||||
return (lines - 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined (VISIBLE_STATS)
|
||||
/* Return the character which best describes FILENAME.
|
||||
`@' for symbolic links
|
||||
@@ -402,19 +483,41 @@ stat_char (filename)
|
||||
/* Return the portion of PATHNAME that should be output when listing
|
||||
possible completions. If we are hacking filename completion, we
|
||||
are only interested in the basename, the portion following the
|
||||
final slash. Otherwise, we return what we were passed. */
|
||||
final slash. Otherwise, we return what we were passed. Since
|
||||
printing empty strings is not very informative, if we're doing
|
||||
filename completion, and the basename is the empty string, we look
|
||||
for the previous slash and return the portion following that. If
|
||||
there's no previous slash, we just return what we were passed. */
|
||||
static char *
|
||||
printable_part (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
char *temp;
|
||||
char *temp, *x;
|
||||
|
||||
temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL;
|
||||
if (rl_filename_completion_desired == 0) /* don't need to do anything */
|
||||
return (pathname);
|
||||
|
||||
temp = strrchr (pathname, '/');
|
||||
#if defined (__MSDOS__)
|
||||
if (rl_filename_completion_desired && temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
|
||||
if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
|
||||
temp = pathname + 1;
|
||||
#endif
|
||||
return (temp ? ++temp : pathname);
|
||||
|
||||
if (temp == 0 || *temp == '\0')
|
||||
return (pathname);
|
||||
/* If the basename is NULL, we might have a pathname like '/usr/src/'.
|
||||
Look for a previous slash and, if one is found, return the portion
|
||||
following that slash. If there's no previous slash, just return the
|
||||
pathname we were passed. */
|
||||
else if (temp[1] == '\0')
|
||||
{
|
||||
for (x = temp - 1; x > pathname; x--)
|
||||
if (*x == '/')
|
||||
break;
|
||||
return ((*x == '/') ? x + 1 : pathname);
|
||||
}
|
||||
else
|
||||
return ++temp;
|
||||
}
|
||||
|
||||
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
|
||||
@@ -543,8 +646,8 @@ rl_quote_filename (s, rtype, qcp)
|
||||
quote, or backslash) anywhere in the string. DP, if non-null, is set to
|
||||
the value of the delimiter character that caused a word break. */
|
||||
|
||||
static char
|
||||
find_completion_word (fp, dp)
|
||||
char
|
||||
_rl_find_completion_word (fp, dp)
|
||||
int *fp, *dp;
|
||||
{
|
||||
int scan, end, found_quote, delimiter, pass_next, isbrk;
|
||||
@@ -599,6 +702,8 @@ find_completion_word (fp, dp)
|
||||
found_quote |= RL_QF_SINGLE_QUOTE;
|
||||
else if (quote_char == '"')
|
||||
found_quote |= RL_QF_DOUBLE_QUOTE;
|
||||
else
|
||||
found_quote |= RL_QF_OTHER_QUOTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,7 +713,11 @@ find_completion_word (fp, dp)
|
||||
/* We didn't find an unclosed quoted substring upon which to do
|
||||
completion, so use the word break characters to find the
|
||||
substring on which to complete. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY))
|
||||
#else
|
||||
while (--rl_point)
|
||||
#endif
|
||||
{
|
||||
scan = rl_line_buffer[rl_point];
|
||||
|
||||
@@ -780,6 +889,11 @@ compute_lcd_of_matches (match_list, matches, text)
|
||||
{
|
||||
register int i, c1, c2, si;
|
||||
int low; /* Count of max-matched characters. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
int v;
|
||||
mbstate_t ps1, ps2;
|
||||
wchar_t wc1, wc2;
|
||||
#endif
|
||||
|
||||
/* If only one match, just use that. Otherwise, compare each
|
||||
member of the list with the next, finding out where they
|
||||
@@ -793,12 +907,33 @@ compute_lcd_of_matches (match_list, matches, text)
|
||||
|
||||
for (i = 1, low = 100000; i < matches; i++)
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
memset (&ps1, 0, sizeof (mbstate_t));
|
||||
memset (&ps2, 0, sizeof (mbstate_t));
|
||||
}
|
||||
#endif
|
||||
if (_rl_completion_case_fold)
|
||||
{
|
||||
for (si = 0;
|
||||
(c1 = _rl_to_lower(match_list[i][si])) &&
|
||||
(c2 = _rl_to_lower(match_list[i + 1][si]));
|
||||
si++)
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
|
||||
mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
|
||||
wc1 = towlower (wc1);
|
||||
wc2 = towlower (wc2);
|
||||
if (wc1 != wc2)
|
||||
break;
|
||||
else if (v > 1)
|
||||
si += v - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c1 != c2)
|
||||
break;
|
||||
}
|
||||
@@ -808,6 +943,17 @@ compute_lcd_of_matches (match_list, matches, text)
|
||||
(c1 = match_list[i][si]) &&
|
||||
(c2 = match_list[i + 1][si]);
|
||||
si++)
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
mbstate_t ps_back = ps1;
|
||||
if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
|
||||
break;
|
||||
else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
|
||||
si += v - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c1 != c2)
|
||||
break;
|
||||
}
|
||||
@@ -828,6 +974,8 @@ compute_lcd_of_matches (match_list, matches, text)
|
||||
{
|
||||
match_list[0] = (char *)xmalloc (low + 1);
|
||||
|
||||
/* XXX - this might need changes in the presence of multibyte chars */
|
||||
|
||||
/* If we are ignoring case, try to preserve the case of the string
|
||||
the user typed in the face of multiple matches differing in case. */
|
||||
if (_rl_completion_case_fold)
|
||||
@@ -871,6 +1019,9 @@ postprocess_matches (matchesp, matching_filenames)
|
||||
|
||||
matches = *matchesp;
|
||||
|
||||
if (matches == 0)
|
||||
return 0;
|
||||
|
||||
/* It seems to me that in all the cases we handle we would like
|
||||
to ignore duplicate possiblilities. Scan for the text to
|
||||
insert being identical to the other completions. */
|
||||
@@ -923,7 +1074,7 @@ rl_display_match_list (matches, len, max)
|
||||
char **matches;
|
||||
int len, max;
|
||||
{
|
||||
int count, limit, printed_len;
|
||||
int count, limit, printed_len, lines;
|
||||
int i, j, k, l;
|
||||
char *temp;
|
||||
|
||||
@@ -951,6 +1102,7 @@ rl_display_match_list (matches, len, max)
|
||||
|
||||
rl_crlf ();
|
||||
|
||||
lines = 0;
|
||||
if (_rl_print_completions_horizontally == 0)
|
||||
{
|
||||
/* Print the sorted items, up-and-down alphabetically, like ls. */
|
||||
@@ -972,6 +1124,13 @@ rl_display_match_list (matches, len, max)
|
||||
l += count;
|
||||
}
|
||||
rl_crlf ();
|
||||
lines++;
|
||||
if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
|
||||
{
|
||||
lines = _rl_internal_pager (lines);
|
||||
if (lines < 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -985,7 +1144,16 @@ rl_display_match_list (matches, len, max)
|
||||
if (matches[i+1])
|
||||
{
|
||||
if (i && (limit > 1) && (i % limit) == 0)
|
||||
rl_crlf ();
|
||||
{
|
||||
rl_crlf ();
|
||||
lines++;
|
||||
if (_rl_page_completions && lines >= _rl_screenheight - 1)
|
||||
{
|
||||
lines = _rl_internal_pager (lines);
|
||||
if (lines < 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
for (k = 0; k < max - printed_len; k++)
|
||||
putc (' ', rl_outstream);
|
||||
@@ -1057,7 +1225,7 @@ display_matches (matches)
|
||||
rl_crlf ();
|
||||
fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
|
||||
fflush (rl_outstream);
|
||||
if (get_y_or_n () == 0)
|
||||
if (get_y_or_n (0) == 0)
|
||||
{
|
||||
rl_crlf ();
|
||||
|
||||
@@ -1155,7 +1323,11 @@ insert_match (match, start, mtype, qc)
|
||||
default trailing character is a space. Returns the number of characters
|
||||
appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
|
||||
has them) and don't add a suffix for a symlink to a directory. A
|
||||
nontrivial match is one that actually adds to the word being completed. */
|
||||
nontrivial match is one that actually adds to the word being completed.
|
||||
The variable rl_completion_mark_symlink_dirs controls this behavior
|
||||
(it's initially set to the what the user has chosen, indicated by the
|
||||
value of _rl_complete_mark_symlink_dirs, but may be modified by an
|
||||
application's completion function). */
|
||||
static int
|
||||
append_to_match (text, delimiter, quote_char, nontrivial_match)
|
||||
char *text;
|
||||
@@ -1171,7 +1343,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
|
||||
|
||||
if (delimiter)
|
||||
temp_string[temp_string_index++] = delimiter;
|
||||
else if (rl_completion_append_character)
|
||||
else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
|
||||
temp_string[temp_string_index++] = rl_completion_append_character;
|
||||
|
||||
temp_string[temp_string_index++] = '\0';
|
||||
@@ -1179,11 +1351,21 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
|
||||
if (rl_filename_completion_desired)
|
||||
{
|
||||
filename = tilde_expand (text);
|
||||
s = nontrivial_match ? LSTAT (filename, &finfo) : stat (filename, &finfo);
|
||||
s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
|
||||
? LSTAT (filename, &finfo)
|
||||
: stat (filename, &finfo);
|
||||
if (s == 0 && S_ISDIR (finfo.st_mode))
|
||||
{
|
||||
if (_rl_complete_mark_directories && rl_line_buffer[rl_point] != '/')
|
||||
rl_insert_text ("/");
|
||||
if (_rl_complete_mark_directories)
|
||||
{
|
||||
/* This is clumsy. Avoid putting in a double slash if point
|
||||
is at the end of the line and the previous character is a
|
||||
slash. */
|
||||
if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
|
||||
;
|
||||
else if (rl_line_buffer[rl_point] != '/')
|
||||
rl_insert_text ("/");
|
||||
}
|
||||
}
|
||||
#ifdef S_ISLNK
|
||||
/* Don't add anything if the filename is a symlink and resolves to a
|
||||
@@ -1194,14 +1376,14 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (rl_point == rl_end)
|
||||
if (rl_point == rl_end && temp_string_index)
|
||||
rl_insert_text (temp_string);
|
||||
}
|
||||
free (filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rl_point == rl_end)
|
||||
if (rl_point == rl_end && temp_string_index)
|
||||
rl_insert_text (temp_string);
|
||||
}
|
||||
|
||||
@@ -1247,12 +1429,15 @@ insert_all_matches (matches, point, qc)
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
|
||||
static void
|
||||
free_match_list (matches)
|
||||
void
|
||||
_rl_free_match_list (matches)
|
||||
char **matches;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (matches == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; matches[i]; i++)
|
||||
free (matches[i]);
|
||||
free (matches);
|
||||
@@ -1276,10 +1461,8 @@ rl_complete_internal (what_to_do)
|
||||
char quote_char;
|
||||
|
||||
RL_SETSTATE(RL_STATE_COMPLETING);
|
||||
/* Only the completion entry function can change these. */
|
||||
rl_filename_completion_desired = 0;
|
||||
rl_filename_quoting_desired = 1;
|
||||
rl_completion_type = what_to_do;
|
||||
|
||||
set_completion_defaults (what_to_do);
|
||||
|
||||
saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
|
||||
our_func = rl_completion_entry_function
|
||||
@@ -1294,7 +1477,7 @@ rl_complete_internal (what_to_do)
|
||||
if (rl_point)
|
||||
/* This (possibly) changes rl_point. If it returns a non-zero char,
|
||||
we know we have an open quote. */
|
||||
quote_char = find_completion_word (&found_quote, &delimiter);
|
||||
quote_char = _rl_find_completion_word (&found_quote, &delimiter);
|
||||
|
||||
start = rl_point;
|
||||
rl_point = end;
|
||||
@@ -1310,6 +1493,7 @@ rl_complete_internal (what_to_do)
|
||||
{
|
||||
rl_ding ();
|
||||
FREE (saved_line_buffer);
|
||||
completion_changed_buffer = 0;
|
||||
RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
return (0);
|
||||
}
|
||||
@@ -1375,7 +1559,7 @@ rl_complete_internal (what_to_do)
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_match_list (matches);
|
||||
_rl_free_match_list (matches);
|
||||
|
||||
/* Check to see if the line has changed through all of this manipulation. */
|
||||
if (saved_line_buffer)
|
||||
@@ -1735,15 +1919,13 @@ rl_menu_complete (count, ignore)
|
||||
/* Clean up from previous call, if any. */
|
||||
FREE (orig_text);
|
||||
if (matches)
|
||||
free_match_list (matches);
|
||||
_rl_free_match_list (matches);
|
||||
|
||||
match_list_index = match_list_size = 0;
|
||||
matches = (char **)NULL;
|
||||
|
||||
/* Only the completion entry function can change these. */
|
||||
rl_filename_completion_desired = 0;
|
||||
rl_filename_quoting_desired = 1;
|
||||
rl_completion_type = '%';
|
||||
set_completion_defaults ('%');
|
||||
|
||||
our_func = rl_completion_entry_function
|
||||
? rl_completion_entry_function
|
||||
@@ -1757,7 +1939,7 @@ rl_menu_complete (count, ignore)
|
||||
if (rl_point)
|
||||
/* This (possibly) changes rl_point. If it returns a non-zero char,
|
||||
we know we have an open quote. */
|
||||
quote_char = find_completion_word (&found_quote, &delimiter);
|
||||
quote_char = _rl_find_completion_word (&found_quote, &delimiter);
|
||||
|
||||
orig_start = rl_point;
|
||||
rl_point = orig_end;
|
||||
|
||||
+504
-54
@@ -43,6 +43,7 @@
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
/* Termcap library stuff. */
|
||||
#include "tcap.h"
|
||||
@@ -65,9 +66,16 @@ extern char *_rl_term_forward_char;
|
||||
static void update_line PARAMS((char *, char *, int, int, int, int));
|
||||
static void space_to_eol PARAMS((int));
|
||||
static void delete_chars PARAMS((int));
|
||||
static void insert_some_chars PARAMS((char *, int));
|
||||
static void insert_some_chars PARAMS((char *, int, int));
|
||||
static void cr PARAMS((void));
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int _rl_col_width PARAMS((char *, int, int));
|
||||
static int *_rl_wrapped_line;
|
||||
#else
|
||||
# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
|
||||
#endif
|
||||
|
||||
static int *inv_lbreaks, *vis_lbreaks;
|
||||
static int inv_lbsize, vis_lbsize;
|
||||
|
||||
@@ -359,6 +367,9 @@ init_line_structures (minsize)
|
||||
inv_lbsize = vis_lbsize = 256;
|
||||
inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
|
||||
vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
_rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
|
||||
#endif
|
||||
inv_lbreaks[0] = vis_lbreaks[0] = 0;
|
||||
}
|
||||
}
|
||||
@@ -372,6 +383,13 @@ rl_redisplay ()
|
||||
int c_pos, inv_botlin, lb_botlin, lb_linenum;
|
||||
int newlines, lpos, temp;
|
||||
char *prompt_this_line;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
wchar_t wc;
|
||||
size_t wc_bytes;
|
||||
int wc_width;
|
||||
mbstate_t ps;
|
||||
int _rl_wrapped_multicolumn = 0;
|
||||
#endif
|
||||
|
||||
if (!readline_echoing_p)
|
||||
return;
|
||||
@@ -472,7 +490,25 @@ rl_redisplay ()
|
||||
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
#define CHECK_LPOS() \
|
||||
do { \
|
||||
lpos++; \
|
||||
if (lpos >= _rl_screenwidth) \
|
||||
{ \
|
||||
if (newlines >= (inv_lbsize - 2)) \
|
||||
{ \
|
||||
inv_lbsize *= 2; \
|
||||
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
||||
_rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
|
||||
} \
|
||||
inv_lbreaks[++newlines] = out; \
|
||||
_rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
|
||||
lpos = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_LPOS() \
|
||||
do { \
|
||||
lpos++; \
|
||||
@@ -487,10 +523,14 @@ rl_redisplay ()
|
||||
lpos = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* inv_lbreaks[i] is where line i starts in the buffer. */
|
||||
inv_lbreaks[newlines = 0] = 0;
|
||||
lpos = out - wrap_offset;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (_rl_wrapped_line, 0, vis_lbsize);
|
||||
#endif
|
||||
|
||||
/* prompt_invis_chars_first_line is the number of invisible characters in
|
||||
the first physical line of the prompt.
|
||||
@@ -508,7 +548,11 @@ rl_redisplay ()
|
||||
probably too much work for the benefit gained. How many people have
|
||||
prompts that exceed two physical lines? */
|
||||
temp = ((newlines + 1) * _rl_screenwidth) +
|
||||
#if 0
|
||||
((newlines == 0) ? prompt_invis_chars_first_line : 0) +
|
||||
#else
|
||||
((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
|
||||
#endif
|
||||
((newlines == 1) ? wrap_offset : 0);
|
||||
|
||||
inv_lbreaks[++newlines] = temp;
|
||||
@@ -523,10 +567,44 @@ rl_redisplay ()
|
||||
It maintains an array of line breaks for display (inv_lbreaks).
|
||||
This handles expanding tabs for display and displaying meta characters. */
|
||||
lb_linenum = 0;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
in = 0;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
|
||||
}
|
||||
else
|
||||
wc_bytes = 1;
|
||||
while (in < rl_end)
|
||||
#else
|
||||
for (in = 0; in < rl_end; in++)
|
||||
#endif
|
||||
{
|
||||
c = (unsigned char)rl_line_buffer[in];
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
|
||||
{
|
||||
/* Byte sequence is invalid or shortened. Assume that the
|
||||
first byte represents a character. */
|
||||
wc_bytes = 1;
|
||||
/* Assume that a character occupies a single column. */
|
||||
wc_width = 1;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (wc_bytes == (size_t)0)
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
temp = wcwidth (wc);
|
||||
wc_width = (temp < 0) ? 1 : temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (out + 8 >= line_size) /* XXX - 8 for \t */
|
||||
{
|
||||
line_size *= 2;
|
||||
@@ -541,7 +619,11 @@ rl_redisplay ()
|
||||
lb_linenum = newlines;
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
|
||||
#else
|
||||
if (META_CHAR (c))
|
||||
#endif
|
||||
{
|
||||
if (_rl_output_meta_chars == 0)
|
||||
{
|
||||
@@ -610,9 +692,52 @@ rl_redisplay ()
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
register int i;
|
||||
|
||||
_rl_wrapped_multicolumn = 0;
|
||||
|
||||
if (_rl_screenwidth < lpos + wc_width)
|
||||
for (i = lpos; i < _rl_screenwidth; i++)
|
||||
{
|
||||
/* The space will be removed in update_line() */
|
||||
line[out++] = ' ';
|
||||
_rl_wrapped_multicolumn++;
|
||||
CHECK_LPOS();
|
||||
}
|
||||
if (in == rl_point)
|
||||
{
|
||||
c_pos = out;
|
||||
lb_linenum = newlines;
|
||||
}
|
||||
for (i = in; i < in+wc_bytes; i++)
|
||||
line[out++] = rl_line_buffer[i];
|
||||
for (i = 0; i < wc_width; i++)
|
||||
CHECK_LPOS();
|
||||
}
|
||||
else
|
||||
{
|
||||
line[out++] = c;
|
||||
CHECK_LPOS();
|
||||
}
|
||||
#else
|
||||
line[out++] = c;
|
||||
CHECK_LPOS();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
in += wc_bytes;
|
||||
wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
|
||||
}
|
||||
else
|
||||
in++;
|
||||
#endif
|
||||
|
||||
}
|
||||
line[out] = '\0';
|
||||
if (c_pos < 0)
|
||||
@@ -650,7 +775,12 @@ rl_redisplay ()
|
||||
only display a screenful. We should display the last screen,
|
||||
not the first. */
|
||||
if (out >= _rl_screenchars)
|
||||
out = _rl_screenchars - 1;
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
|
||||
else
|
||||
out = _rl_screenchars - 1;
|
||||
}
|
||||
|
||||
/* The first line is at character position 0 in the buffer. The
|
||||
second and subsequent lines start at inv_lbreaks[N], offset by
|
||||
@@ -736,7 +866,10 @@ rl_redisplay ()
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
#endif
|
||||
_rl_output_some_chars (local_prompt, nleft);
|
||||
_rl_last_c_pos = nleft;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
|
||||
else
|
||||
_rl_last_c_pos = nleft;
|
||||
}
|
||||
|
||||
/* Where on that line? And where does that line start
|
||||
@@ -752,10 +885,15 @@ rl_redisplay ()
|
||||
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
|
||||
{
|
||||
_rl_backspace (_rl_last_c_pos - nleft);
|
||||
_rl_last_c_pos = nleft;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft);
|
||||
else
|
||||
_rl_last_c_pos = nleft;
|
||||
}
|
||||
|
||||
if (nleft != _rl_last_c_pos)
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@@ -900,6 +1038,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
register char *ofd, *ols, *oe, *nfd, *nls, *ne;
|
||||
int temp, lendiff, wsatend, od, nd;
|
||||
int current_invis_chars;
|
||||
int col_lendiff, col_temp;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps_new, ps_old;
|
||||
int new_offset, old_offset, tmp;
|
||||
#endif
|
||||
|
||||
/* If we're at the right edge of a terminal that supports xn, we're
|
||||
ready to wrap around, so do so. This fixes problems with knowing
|
||||
@@ -908,19 +1051,97 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
position of the cursor. */
|
||||
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
|
||||
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
|
||||
&& _rl_last_v_pos == current_line - 1)
|
||||
&& _rl_last_v_pos == current_line - 1)
|
||||
{
|
||||
if (new[0])
|
||||
putc (new[0], rl_outstream);
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
wchar_t wc;
|
||||
mbstate_t ps;
|
||||
int tempwidth, bytes;
|
||||
size_t ret;
|
||||
|
||||
/* This fixes only double-column characters, but if the wrapped
|
||||
character comsumes more than three columns, spaces will be
|
||||
inserted in the string buffer. */
|
||||
if (_rl_wrapped_line[current_line] > 0)
|
||||
_rl_clear_to_eol (_rl_wrapped_line[current_line]);
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
|
||||
if (ret == (size_t)-1 || ret == (size_t)-2)
|
||||
{
|
||||
tempwidth = 1;
|
||||
ret = 1;
|
||||
}
|
||||
else if (ret == 0)
|
||||
tempwidth = 0;
|
||||
else
|
||||
tempwidth = wcwidth (wc);
|
||||
|
||||
if (tempwidth > 0)
|
||||
{
|
||||
int count;
|
||||
bytes = ret;
|
||||
for (count = 0; count < bytes; count++)
|
||||
putc (new[count], rl_outstream);
|
||||
_rl_last_c_pos = tempwidth;
|
||||
_rl_last_v_pos++;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
|
||||
if (ret != 0 && bytes != 0)
|
||||
{
|
||||
if (ret == (size_t)-1 || ret == (size_t)-2)
|
||||
memmove (old+bytes, old+1, strlen (old+1));
|
||||
else
|
||||
memmove (old+bytes, old+ret, strlen (old+ret));
|
||||
memcpy (old, new, bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
putc (' ', rl_outstream);
|
||||
_rl_last_c_pos = 1;
|
||||
_rl_last_v_pos++;
|
||||
if (old[0] && new[0])
|
||||
old[0] = new[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
putc (' ', rl_outstream);
|
||||
_rl_last_c_pos = 1; /* XXX */
|
||||
_rl_last_v_pos++;
|
||||
if (old[0] && new[0])
|
||||
old[0] = new[0];
|
||||
#endif
|
||||
{
|
||||
if (new[0])
|
||||
putc (new[0], rl_outstream);
|
||||
else
|
||||
putc (' ', rl_outstream);
|
||||
_rl_last_c_pos = 1; /* XXX */
|
||||
_rl_last_v_pos++;
|
||||
if (old[0] && new[0])
|
||||
old[0] = new[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Find first difference. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
memset (&ps_new, 0, sizeof(mbstate_t));
|
||||
memset (&ps_old, 0, sizeof(mbstate_t));
|
||||
|
||||
new_offset = old_offset = 0;
|
||||
for (ofd = old, nfd = new;
|
||||
(ofd - old < omax) && *ofd &&
|
||||
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
|
||||
{
|
||||
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
|
||||
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
|
||||
ofd = old + old_offset;
|
||||
nfd = new + new_offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
for (ofd = old, nfd = new;
|
||||
(ofd - old < omax) && *ofd && (*ofd == *nfd);
|
||||
ofd++, nfd++)
|
||||
@@ -937,6 +1158,33 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
return;
|
||||
|
||||
wsatend = 1; /* flag for trailing whitespace */
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
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);
|
||||
while ((ols > ofd) && (nls > nfd))
|
||||
{
|
||||
memset (&ps_old, 0, sizeof (mbstate_t));
|
||||
memset (&ps_new, 0, sizeof (mbstate_t));
|
||||
|
||||
_rl_adjust_point (old, ols - old, &ps_old);
|
||||
_rl_adjust_point (new, nls - new, &ps_new);
|
||||
|
||||
if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
|
||||
break;
|
||||
|
||||
if (*ols == ' ')
|
||||
wsatend = 0;
|
||||
|
||||
ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
|
||||
nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
ols = oe - 1; /* find last same */
|
||||
nls = ne - 1;
|
||||
while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
|
||||
@@ -946,18 +1194,38 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
ols--;
|
||||
nls--;
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wsatend)
|
||||
{
|
||||
ols = oe;
|
||||
nls = ne;
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* This may not work for stateful encoding, but who cares? To handle
|
||||
stateful encoding properly, we have to scan each string from the
|
||||
beginning and compare. */
|
||||
else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
|
||||
#else
|
||||
else if (*ols != *nls)
|
||||
#endif
|
||||
{
|
||||
if (*ols) /* don't step past the NUL */
|
||||
ols++;
|
||||
{
|
||||
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)
|
||||
nls++;
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
|
||||
else
|
||||
nls++;
|
||||
}
|
||||
}
|
||||
|
||||
/* count of invisible characters in the current invisible line. */
|
||||
@@ -993,24 +1261,50 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
#endif
|
||||
_rl_output_some_chars (local_prompt, lendiff);
|
||||
_rl_last_c_pos = lendiff;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff);
|
||||
else
|
||||
_rl_last_c_pos = lendiff;
|
||||
}
|
||||
|
||||
_rl_move_cursor_relative (od, old);
|
||||
|
||||
/* if (len (new) > len (old)) */
|
||||
/* if (len (new) > len (old))
|
||||
lendiff == difference in buffer
|
||||
col_lendiff == difference on screen
|
||||
When not using multibyte characters, these are equal */
|
||||
lendiff = (nls - nfd) - (ols - ofd);
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
|
||||
else
|
||||
col_lendiff = lendiff;
|
||||
|
||||
/* If we are changing the number of invisible characters in a line, and
|
||||
the spot of first difference is before the end of the invisible chars,
|
||||
lendiff needs to be adjusted. */
|
||||
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
|
||||
current_invis_chars != visible_wrap_offset)
|
||||
lendiff += visible_wrap_offset - current_invis_chars;
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
lendiff += visible_wrap_offset - current_invis_chars;
|
||||
col_lendiff += visible_wrap_offset - current_invis_chars;
|
||||
}
|
||||
else
|
||||
{
|
||||
lendiff += visible_wrap_offset - current_invis_chars;
|
||||
col_lendiff = lendiff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert (diff (len (old), len (new)) ch. */
|
||||
temp = ne - nfd;
|
||||
if (lendiff > 0)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
col_temp = _rl_col_width (new, nfd - new, ne - new);
|
||||
else
|
||||
col_temp = temp;
|
||||
|
||||
if (col_lendiff > 0) /* XXX - was lendiff */
|
||||
{
|
||||
/* Non-zero if we're increasing the number of lines. */
|
||||
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
|
||||
@@ -1018,7 +1312,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
use the terminal's capabilities. If we're growing the number
|
||||
of lines, make sure we actually cause the new line to wrap
|
||||
around on auto-wrapping terminals. */
|
||||
if (_rl_terminal_can_insert && ((2 * temp) >= lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
|
||||
if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
|
||||
{
|
||||
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
|
||||
_rl_horizontal_scroll_mode == 1, inserting the characters with
|
||||
@@ -1027,8 +1321,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
|
||||
lendiff <= prompt_visible_length || !current_invis_chars))
|
||||
{
|
||||
insert_some_chars (nfd, lendiff);
|
||||
_rl_last_c_pos += lendiff;
|
||||
insert_some_chars (nfd, lendiff, col_lendiff);
|
||||
_rl_last_c_pos += col_lendiff;
|
||||
}
|
||||
else if (*ols == 0)
|
||||
{
|
||||
@@ -1037,7 +1331,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
/* However, this screws up the rest of this block, which
|
||||
assumes you've done the insert because you can. */
|
||||
_rl_output_some_chars (nfd, lendiff);
|
||||
_rl_last_c_pos += lendiff;
|
||||
_rl_last_c_pos += col_lendiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1045,7 +1339,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
the end. We have invisible characters in this line. This
|
||||
is a dumb update. */
|
||||
_rl_output_some_chars (nfd, temp);
|
||||
_rl_last_c_pos += temp;
|
||||
_rl_last_c_pos += col_temp;
|
||||
return;
|
||||
}
|
||||
/* Copy (new) chars to screen from first diff to last match. */
|
||||
@@ -1053,37 +1347,41 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
if ((temp - lendiff) > 0)
|
||||
{
|
||||
_rl_output_some_chars (nfd + lendiff, temp - lendiff);
|
||||
_rl_last_c_pos += temp - lendiff;
|
||||
#if 0
|
||||
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
|
||||
#else
|
||||
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* cannot insert chars, write to EOL */
|
||||
_rl_output_some_chars (nfd, temp);
|
||||
_rl_last_c_pos += temp;
|
||||
_rl_last_c_pos += col_temp;
|
||||
}
|
||||
}
|
||||
else /* Delete characters from line. */
|
||||
{
|
||||
/* If possible and inexpensive to use terminal deletion, then do so. */
|
||||
if (_rl_term_dc && (2 * temp) >= -lendiff)
|
||||
if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
|
||||
{
|
||||
/* If all we're doing is erasing the invisible characters in the
|
||||
prompt string, don't bother. It screws up the assumptions
|
||||
about what's on the screen. */
|
||||
if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
|
||||
-lendiff == visible_wrap_offset)
|
||||
lendiff = 0;
|
||||
col_lendiff = 0;
|
||||
|
||||
if (lendiff)
|
||||
delete_chars (-lendiff); /* delete (diff) characters */
|
||||
if (col_lendiff)
|
||||
delete_chars (-col_lendiff); /* delete (diff) characters */
|
||||
|
||||
/* Copy (new) chars to screen from first diff to last match */
|
||||
temp = nls - nfd;
|
||||
if (temp > 0)
|
||||
{
|
||||
_rl_output_some_chars (nfd, temp);
|
||||
_rl_last_c_pos += temp;
|
||||
_rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
|
||||
}
|
||||
}
|
||||
/* Otherwise, print over the existing material. */
|
||||
@@ -1092,15 +1390,20 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
if (temp > 0)
|
||||
{
|
||||
_rl_output_some_chars (nfd, temp);
|
||||
_rl_last_c_pos += temp;
|
||||
_rl_last_c_pos += col_temp;
|
||||
}
|
||||
lendiff = (oe - old) - (ne - new);
|
||||
if (lendiff)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
|
||||
else
|
||||
col_lendiff = lendiff;
|
||||
|
||||
if (col_lendiff)
|
||||
{
|
||||
if (_rl_term_autowrap && current_line < inv_botlin)
|
||||
space_to_eol (lendiff);
|
||||
space_to_eol (col_lendiff);
|
||||
else
|
||||
_rl_clear_to_eol (lendiff);
|
||||
_rl_clear_to_eol (col_lendiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1449,10 @@ rl_on_new_line_with_prompt ()
|
||||
prompt_last_line = rl_prompt;
|
||||
|
||||
l = strlen (prompt_last_line);
|
||||
_rl_last_c_pos = l;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);
|
||||
else
|
||||
_rl_last_c_pos = l;
|
||||
|
||||
/* Dissect prompt_last_line into screen lines. Note that here we have
|
||||
to use the real screenwidth. Readline's notion of screenwidth might be
|
||||
@@ -1201,7 +1507,14 @@ _rl_move_cursor_relative (new, data)
|
||||
register int i;
|
||||
|
||||
/* If we don't have to do anything, then return. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* If we have multibyte characters, NEW is indexed by the buffer point in
|
||||
a multibyte string, but _rl_last_c_pos is the display position. In
|
||||
this case, NEW's display position is not obvious. */
|
||||
if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
|
||||
#else
|
||||
if (_rl_last_c_pos == new) return;
|
||||
#endif
|
||||
|
||||
/* It may be faster to output a CR, and then move forwards instead
|
||||
of moving backwards. */
|
||||
@@ -1231,19 +1544,69 @@ _rl_move_cursor_relative (new, data)
|
||||
data is underneath the cursor. */
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
if (_rl_term_forward_char)
|
||||
for (i = _rl_last_c_pos; i < new; i++)
|
||||
tputs (_rl_term_forward_char, 1, _rl_output_character_function);
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int width;
|
||||
width = _rl_col_width (data, _rl_last_c_pos, new);
|
||||
for (i = 0; i < width; i++)
|
||||
tputs (_rl_term_forward_char, 1, _rl_output_character_function);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = _rl_last_c_pos; i < new; i++)
|
||||
tputs (_rl_term_forward_char, 1, _rl_output_character_function);
|
||||
}
|
||||
}
|
||||
else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
for (i = 0; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
}
|
||||
else
|
||||
for (i = _rl_last_c_pos; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
#else
|
||||
for (i = _rl_last_c_pos; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
#endif /* HACK_TERMCAP_MOTION */
|
||||
|
||||
#else /* !HACK_TERMCAP_MOTION */
|
||||
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
for (i = 0; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
}
|
||||
else
|
||||
for (i = _rl_last_c_pos; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
|
||||
#endif /* !HACK_TERMCAP_MOTION */
|
||||
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* NEW points to the buffer point, but _rl_last_c_pos is the display point.
|
||||
The byte length of the string is probably bigger than the column width
|
||||
of the string, which means that if NEW == _rl_last_c_pos, then NEW's
|
||||
display point is less than _rl_last_c_pos. */
|
||||
else if (_rl_last_c_pos >= new)
|
||||
#else
|
||||
else if (_rl_last_c_pos > new)
|
||||
_rl_backspace (_rl_last_c_pos - new);
|
||||
_rl_last_c_pos = new;
|
||||
#endif
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
for (i = 0; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
}
|
||||
else
|
||||
_rl_backspace (_rl_last_c_pos - new);
|
||||
}
|
||||
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width (data, 0, new);
|
||||
else
|
||||
_rl_last_c_pos = new;
|
||||
}
|
||||
|
||||
/* PWP: move the cursor up or down. */
|
||||
@@ -1514,17 +1877,23 @@ _rl_clear_screen ()
|
||||
rl_crlf ();
|
||||
}
|
||||
|
||||
/* Insert COUNT characters from STRING to the output stream. */
|
||||
/* Insert COUNT characters from STRING to the output stream at column COL. */
|
||||
static void
|
||||
insert_some_chars (string, count)
|
||||
insert_some_chars (string, count, col)
|
||||
char *string;
|
||||
int count;
|
||||
int count, col;
|
||||
{
|
||||
/* DEBUGGING */
|
||||
if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
if (count != col)
|
||||
fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
|
||||
|
||||
/* If IC is defined, then we do not have to "enter" insert mode. */
|
||||
if (_rl_term_IC)
|
||||
{
|
||||
char *buffer;
|
||||
buffer = tgoto (_rl_term_IC, 0, count);
|
||||
|
||||
buffer = tgoto (_rl_term_IC, 0, col);
|
||||
tputs (buffer, 1, _rl_output_character_function);
|
||||
_rl_output_some_chars (string, count);
|
||||
}
|
||||
@@ -1540,7 +1909,7 @@ insert_some_chars (string, count)
|
||||
use that first to open up the space. */
|
||||
if (_rl_term_ic && *_rl_term_ic)
|
||||
{
|
||||
for (i = count; i--; )
|
||||
for (i = col; i--; )
|
||||
tputs (_rl_term_ic, 1, _rl_output_character_function);
|
||||
}
|
||||
|
||||
@@ -1595,11 +1964,8 @@ _rl_update_final ()
|
||||
if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
|
||||
{
|
||||
char *last_line;
|
||||
#if 0
|
||||
last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
|
||||
#else
|
||||
|
||||
last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
|
||||
#endif
|
||||
_rl_move_cursor_relative (_rl_screenwidth - 1, last_line);
|
||||
_rl_clear_to_eol (0);
|
||||
putc (last_line[_rl_screenwidth - 1], rl_outstream);
|
||||
@@ -1744,3 +2110,87 @@ _rl_current_display_line ()
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* Calculate the number of screen columns occupied by STR from START to END.
|
||||
In the case of multibyte characters with stateful encoding, we have to
|
||||
scan from the beginning of the string to take the state into account. */
|
||||
static int
|
||||
_rl_col_width (str, start, end)
|
||||
char *str;
|
||||
int start, end;
|
||||
{
|
||||
wchar_t wc;
|
||||
mbstate_t ps = {0};
|
||||
int tmp, point, width, max;
|
||||
|
||||
if (end <= start)
|
||||
return 0;
|
||||
|
||||
point = 0;
|
||||
max = end;
|
||||
|
||||
while (point < start)
|
||||
{
|
||||
tmp = mbrlen (str + point, max, &ps);
|
||||
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
|
||||
{
|
||||
/* In this case, the bytes are invalid or too short to compose a
|
||||
multibyte character, so we assume that the first byte represents
|
||||
a single character. */
|
||||
point++;
|
||||
max--;
|
||||
|
||||
/* Clear the state of the byte sequence, because in this case the
|
||||
effect of mbstate is undefined. */
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (tmp == 0)
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
point += tmp;
|
||||
max -= tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* If START is not a byte that starts a character, then POINT will be
|
||||
greater than START. In this case, assume that (POINT - START) gives
|
||||
a byte count that is the number of columns of difference. */
|
||||
width = point - start;
|
||||
|
||||
while (point < end)
|
||||
{
|
||||
tmp = mbrtowc (&wc, str + point, max, &ps);
|
||||
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
|
||||
{
|
||||
/* In this case, the bytes are invalid or too short to compose a
|
||||
multibyte character, so we assume that the first byte represents
|
||||
a single character. */
|
||||
point++;
|
||||
max--;
|
||||
|
||||
/* and assume that the byte occupies a single column. */
|
||||
width++;
|
||||
|
||||
/* Clear the state of the byte sequence, because in this case the
|
||||
effect of mbstate is undefined. */
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (tmp == 0)
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
point += tmp;
|
||||
max -= tmp;
|
||||
tmp = wcwidth(wc);
|
||||
width += (tmp >= 0) ? tmp : 1;
|
||||
}
|
||||
}
|
||||
|
||||
width += point - end;
|
||||
|
||||
return width;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
# Derived by hand from the generated readline-src/doc/Makefile
|
||||
# This makefile for Readline library documentation is in -*- text -*- mode.
|
||||
# Emacs likes it that way.
|
||||
|
||||
# Copyright (C) 1996-2002 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
topdir = .
|
||||
srcdir = .
|
||||
VPATH = .
|
||||
|
||||
@@ -18,7 +18,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 (C) 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -73,7 +73,7 @@ except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
@@ -188,8 +188,9 @@ Stifle the history list, remembering only the last @var{max} entries.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int unstifle_history (void)
|
||||
Stop stifling the history. This returns the previous amount the
|
||||
history was stifled. The value is positive if the history was
|
||||
Stop stifling the history. This returns the previously-set
|
||||
maximum number of history entries (as set by @code{stifle_history()}).
|
||||
The value is positive if the history was
|
||||
stifled, negative if it wasn't.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988-1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
@set EDITION 4.2a
|
||||
@set VERSION 4.2a
|
||||
@set UPDATED 2001 October 9
|
||||
@set UPDATE-MONTH October 2001
|
||||
@ignore
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Oct 9 15:03:34 EDT 2001
|
||||
@set EDITION 4.3
|
||||
@set VERSION 4.3
|
||||
@set UPDATED 2002 March 4
|
||||
@set UPDATE-MONTH March 2002
|
||||
|
||||
@set LASTCHANGE Mon Mar 4 12:00:16 EST 2002
|
||||
|
||||
@@ -18,7 +18,7 @@ This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -73,7 +73,7 @@ except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
|
||||
+114
-59
@@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consitency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -111,12 +111,13 @@ function, and has the advantage of no static buffer to overflow:
|
||||
/* A static variable for holding the line. */
|
||||
static char *line_read = (char *)NULL;
|
||||
|
||||
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
|
||||
/* Read a string, and return a pointer to it.
|
||||
Returns NULL on EOF. */
|
||||
char *
|
||||
rl_gets ()
|
||||
@{
|
||||
/* If the buffer has already been allocated, return the memory
|
||||
to the free pool. */
|
||||
/* If the buffer has already been allocated,
|
||||
return the memory to the free pool. */
|
||||
if (line_read)
|
||||
@{
|
||||
free (line_read);
|
||||
@@ -126,7 +127,8 @@ rl_gets ()
|
||||
/* Get a line from the user. */
|
||||
line_read = readline ("");
|
||||
|
||||
/* If the line has any text in it, save it on the history. */
|
||||
/* If the line has any text in it,
|
||||
save it on the history. */
|
||||
if (line_read && *line_read)
|
||||
add_history (line_read);
|
||||
|
||||
@@ -263,7 +265,7 @@ variables that describe the current state of the line read so far.
|
||||
The calling sequence for a command @code{foo} looks like
|
||||
|
||||
@example
|
||||
@code{foo (int count, int key)}
|
||||
@code{int foo (int count, int key)}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -280,6 +282,9 @@ to do something useful with both negative and positive arguments.
|
||||
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.
|
||||
|
||||
@node Readline Variables
|
||||
@section Readline Variables
|
||||
|
||||
@@ -385,10 +390,12 @@ The value allows conditional parsing of the inputrc file
|
||||
|
||||
@deftypevar {FILE *} rl_instream
|
||||
The stdio stream from which Readline reads input.
|
||||
If @code{NULL}, Readline defaults to @var{stdin}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {FILE *} rl_outstream
|
||||
The stdio stream to which Readline performs output.
|
||||
If @code{NULL}, Readline defaults to @var{stdout}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_command_func_t *} rl_last_func
|
||||
@@ -766,9 +773,9 @@ This is done with @code{rl_begin_undo_group()} and
|
||||
|
||||
The types of events that can be undone are:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @};
|
||||
@end example
|
||||
@end smallexample
|
||||
|
||||
Notice that @code{UNDO_DELETE} means to insert some text, and
|
||||
@code{UNDO_INSERT} means to delete some text. That is, the undo code
|
||||
@@ -901,10 +908,12 @@ to the result.
|
||||
|
||||
@deftypefun int rl_insert_text (const char *text)
|
||||
Insert @var{text} into the line at the current cursor position.
|
||||
Returns the number of characters inserted.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_delete_text (int start, int end)
|
||||
Delete the text between @var{start} and @var{end} in the current line.
|
||||
Returns the number of characters deleted.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {char *} rl_copy_text (int start, int end)
|
||||
@@ -947,7 +956,9 @@ be the keyboard.
|
||||
@deftypefun int rl_stuff_char (int c)
|
||||
Insert @var{c} into the Readline input stream. It will be "read"
|
||||
before Readline attempts to read characters from the terminal with
|
||||
@code{rl_read_key()}.
|
||||
@code{rl_read_key()}. Up to 512 characters may be pushed back.
|
||||
@code{rl_stuff_char} returns 1 if the character was successfully inserted;
|
||||
0 otherwise.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_execute_next (int c)
|
||||
@@ -1000,6 +1011,13 @@ environment variable is used.
|
||||
@node Utility Functions
|
||||
@subsection Utility Functions
|
||||
|
||||
@deftypefun void rl_replace_line (const char *text, int clear_undo)
|
||||
Replace the contents of @code{rl_line_buffer} with @var{text}.
|
||||
The point and mark are preserved, if possible.
|
||||
If @var{clear_undo} is non-zero, the undo list associated with the
|
||||
current line is cleared.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_extend_line_buffer (int len)
|
||||
Ensure that @code{rl_line_buffer} has enough space to hold @var{len}
|
||||
characters, possibly reallocating it if necessary.
|
||||
@@ -1123,16 +1141,26 @@ The function takes the text of the line as an argument.
|
||||
@deftypefun void rl_callback_read_char (void)
|
||||
Whenever an application determines that keyboard input is available, it
|
||||
should call @code{rl_callback_read_char()}, which will read the next
|
||||
character from the current input source. If that character completes the
|
||||
line, @code{rl_callback_read_char} will invoke the @var{lhandler}
|
||||
function saved by @code{rl_callback_handler_install} to process the
|
||||
line. @code{EOF} is indicated by calling @var{lhandler} with a
|
||||
character from the current input source.
|
||||
If that character completes the line, @code{rl_callback_read_char} will
|
||||
invoke the @var{lhandler} function saved by @code{rl_callback_handler_install}
|
||||
to process the line.
|
||||
Before calling the @var{lhandler} function, the terminal settings are
|
||||
reset to the values they had before calling
|
||||
@code{rl_callback_handler_install}.
|
||||
If the @var{lhandler} function returns,
|
||||
the terminal settings are modified for Readline's use again.
|
||||
@code{EOF} is indicated by calling @var{lhandler} with a
|
||||
@code{NULL} line.
|
||||
@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.
|
||||
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
|
||||
the program exits to reset the terminal settings.
|
||||
@end deftypefun
|
||||
|
||||
@node A Readline Example
|
||||
@@ -1185,8 +1213,8 @@ invert_case_line (count, key)
|
||||
end = temp;
|
||||
@}
|
||||
|
||||
/* Tell readline that we are modifying the line, so it will save
|
||||
the undo information. */
|
||||
/* Tell readline that we are modifying the line,
|
||||
so it will save the undo information. */
|
||||
rl_modifying (start, end);
|
||||
|
||||
for (i = start; i != end; i++)
|
||||
@@ -1442,6 +1470,14 @@ partially-completed word. See description of @code{rl_complete()}.
|
||||
This calls @code{rl_complete_internal()} with an argument of @samp{*}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_completion_mode (rl_command_func_t *cfunc)
|
||||
Returns the apppriate value to pass to @code{rl_complete_internal()}
|
||||
depending on whether @var{cfunc} was called twice in succession and
|
||||
the value of the @code{show-all-if-ambiguous} variable.
|
||||
Application-specific completion functions may use this function to present
|
||||
the same interface as @code{rl_complete()}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {char **} rl_completion_matches (const char *text, rl_compentry_func_t *entry_func)
|
||||
Returns an array of strings which is a list of completions for
|
||||
@var{text}. If there are no completions, returns @code{NULL}.
|
||||
@@ -1528,10 +1564,41 @@ character found in @code{rl_completer_word_break_characters} should be
|
||||
used to break words for the completer.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_query_items
|
||||
Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she is sure
|
||||
she wants to see them all. The default value is 100.
|
||||
@deftypevar {rl_compignore_func_t *} rl_ignore_some_completions_function
|
||||
This function, if defined, is called by the completer when real filename
|
||||
completion is done, after all the matching names have been generated.
|
||||
It is passed a @code{NULL} terminated array of matches.
|
||||
The first element (@code{matches[0]}) is the
|
||||
maximal substring common to all matches. This function can
|
||||
re-arrange the list of matches as required, but each element deleted
|
||||
from the array must be freed.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook
|
||||
This function, if defined, is allowed to modify the directory portion
|
||||
of filenames Readline completes. It is called with the address of a
|
||||
string (the current directory name) as an argument, and may modify that string.
|
||||
If the string is replaced with a new string, the old value should be freed.
|
||||
Any modified directory name should have a trailing slash.
|
||||
The modified value will be displayed as part of the completion, replacing
|
||||
the directory portion of the pathname the user typed.
|
||||
It returns an integer that should be non-zero if the function modifies
|
||||
its directory argument.
|
||||
It could be used to expand symbolic links or shell variables in pathnames.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook
|
||||
If non-zero, then this is the address of a function to call when
|
||||
completing a word would normally display the list of possible matches.
|
||||
This function is called in lieu of Readline displaying the list.
|
||||
It takes three arguments:
|
||||
(@code{char **}@var{matches}, @code{int} @var{num_matches}, @code{int} @var{max_length})
|
||||
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.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {const char *} rl_basic_word_break_characters
|
||||
@@ -1571,6 +1638,12 @@ For instance, Bash sets this variable to "$@@" so that it can complete
|
||||
shell variables and hostnames.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_query_items
|
||||
Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she is sure
|
||||
she wants to see them all. The default value is 100.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {int} rl_completion_append_character
|
||||
When a single completion alternative matches at the end of the command
|
||||
line, this character is appended to the inserted completion text. The
|
||||
@@ -1581,6 +1654,24 @@ provide the ``most sensible word separator character'' according to
|
||||
an application-specific command line syntax specification.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_suppress_append
|
||||
If non-zero, @var{rl_completion_append_character} is not appended to
|
||||
matches at the end of the command line, as described above. It is
|
||||
set to 0 before any application-specific completion function is called.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_mark_symlink_dirs
|
||||
If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
user-settable @var{mark-directories} variable.
|
||||
This variable exists so that application completion functions can
|
||||
override the user's global preference (set via the
|
||||
@var{mark-symlinked-directories} Readline variable) if appropriate.
|
||||
This variable is set to the user's preference before any
|
||||
application completion function is called, so unless that function
|
||||
modifies the value, the user's preferences are honored.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_ignore_completion_duplicates
|
||||
If non-zero, then duplicates in the matches are removed.
|
||||
The default is 1.
|
||||
@@ -1625,43 +1716,6 @@ If this variable is non-zero, completion is inhibited. The completion
|
||||
character will be inserted as any other bound to @code{self-insert}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_compignore_func_t *} rl_ignore_some_completions_function
|
||||
This function, if defined, is called by the completer when real filename
|
||||
completion is done, after all the matching names have been generated.
|
||||
It is passed a @code{NULL} terminated array of matches.
|
||||
The first element (@code{matches[0]}) is the
|
||||
maximal substring common to all matches. This function can
|
||||
re-arrange the list of matches as required, but each element deleted
|
||||
from the array must be freed.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook
|
||||
This function, if defined, is allowed to modify the directory portion
|
||||
of filenames Readline completes. It is called with the address of a
|
||||
string (the current directory name) as an argument, and may modify that string.
|
||||
If the string is replaced with a new string, the old value should be freed.
|
||||
Any modified directory name should have a trailing slash.
|
||||
The modified value will be displayed as part of the completion, replacing
|
||||
the directory portion of the pathname the user typed.
|
||||
It returns an integer that should be non-zero if the function modifies
|
||||
its directory argument.
|
||||
It could be used to expand symbolic links or shell variables in pathnames.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook
|
||||
If non-zero, then this is the address of a function to call when
|
||||
completing a word would normally display the list of possible matches.
|
||||
This function is called in lieu of Readline displaying the list.
|
||||
It takes three arguments:
|
||||
(@code{char **}@var{matches}, @code{int} @var{num_matches}, @code{int} @var{max_length})
|
||||
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.
|
||||
@end deftypevar
|
||||
|
||||
@node A Short Completion Example
|
||||
@subsection A Short Completion Example
|
||||
|
||||
@@ -2089,12 +2143,13 @@ too_dangerous (caller)
|
||||
char *caller;
|
||||
@{
|
||||
fprintf (stderr,
|
||||
"%s: Too dangerous for me to distribute. Write it yourself.\n",
|
||||
"%s: Too dangerous for me to distribute.\n"
|
||||
caller);
|
||||
fprintf (stderr, "Write it yourself.\n");
|
||||
@}
|
||||
|
||||
/* Return non-zero if ARG is a valid argument for CALLER, else print
|
||||
an error message and return zero. */
|
||||
/* Return non-zero if ARG is a valid argument for CALLER,
|
||||
else print an error message and return zero. */
|
||||
int
|
||||
valid_argument (caller, arg)
|
||||
char *caller, *arg;
|
||||
|
||||
@@ -10,7 +10,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-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
@@ -512,6 +512,13 @@ This variable, when set to @samp{on}, causes Readline to display an
|
||||
asterisk (@samp{*}) at the start of history lines which have been modified.
|
||||
This variable is @samp{off} by default.
|
||||
|
||||
@item mark-symlinked-directories
|
||||
@vindex mark-symlinked-directories
|
||||
If set to @samp{on}, completed names which are symbolic links
|
||||
to directories have a slash appended (subject to the value of
|
||||
@code{mark-directories}).
|
||||
The default is @samp{off}.
|
||||
|
||||
@item match-hidden-files
|
||||
@vindex match-hidden-files
|
||||
This variable, when set to @samp{on}, causes Readline to match files whose
|
||||
@@ -526,6 +533,12 @@ 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}.
|
||||
|
||||
@item page-completions
|
||||
@vindex page-completions
|
||||
If set to @samp{on}, Readline uses an internal @code{more}-like pager
|
||||
to display a screenful of possible completions at a time.
|
||||
This variable is @samp{on} by default.
|
||||
|
||||
@item print-completions-horizontally
|
||||
If set to @samp{on}, Readline will display completions with matches
|
||||
sorted horizontally in alphabetical order, rather than down the screen.
|
||||
@@ -757,14 +770,14 @@ binding, variable assignment, and conditional syntax.
|
||||
@example
|
||||
@page
|
||||
# This file controls the behaviour of line input editing for
|
||||
# programs that use the Gnu Readline library. Existing programs
|
||||
# include FTP, Bash, and Gdb.
|
||||
# programs that use the GNU Readline library. Existing
|
||||
# programs include FTP, Bash, and GDB.
|
||||
#
|
||||
# You can re-read the inputrc file with C-x C-r.
|
||||
# Lines beginning with '#' are comments.
|
||||
#
|
||||
# First, include any systemwide bindings and variable assignments from
|
||||
# /etc/Inputrc
|
||||
# First, include any systemwide bindings and variable
|
||||
# assignments from /etc/Inputrc
|
||||
$include /etc/Inputrc
|
||||
|
||||
#
|
||||
@@ -816,10 +829,12 @@ TAB: complete
|
||||
$if Bash
|
||||
# edit the path
|
||||
"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f"
|
||||
# prepare to type a quoted word -- insert open and close double quotes
|
||||
# prepare to type a quoted word --
|
||||
# insert open and close double quotes
|
||||
# and move to just after the open quote
|
||||
"\C-x\"": "\"\"\C-b"
|
||||
# insert a backslash (testing backslash escapes in sequences and macros)
|
||||
# insert a backslash (testing backslash escapes
|
||||
# in sequences and macros)
|
||||
"\C-x\\": "\\"
|
||||
# Quote the current or previous word
|
||||
"\C-xq": "\eb\"\ef\""
|
||||
@@ -835,16 +850,16 @@ set bell-style visible
|
||||
# don't strip characters to 7 bits when reading
|
||||
set input-meta on
|
||||
|
||||
# allow iso-latin1 characters to be inserted rather than converted to
|
||||
# prefix-meta sequences
|
||||
# allow iso-latin1 characters to be inserted rather
|
||||
# than converted to prefix-meta sequences
|
||||
set convert-meta off
|
||||
|
||||
# display characters with the eighth bit set directly rather than
|
||||
# as meta-prefixed characters
|
||||
# display characters with the eighth bit set directly
|
||||
# rather than as meta-prefixed characters
|
||||
set output-meta on
|
||||
|
||||
# if there are more than 150 possible completions for a word, ask the
|
||||
# user if he wants to see all of them
|
||||
# if there are more than 150 possible completions for
|
||||
# a word, ask the user if he wants to see all of them
|
||||
set completion-query-items 150
|
||||
|
||||
# For FTP
|
||||
@@ -1053,6 +1068,20 @@ lowercase the previous word, but do not move the cursor.
|
||||
Capitalize the current (or following) word. With a negative argument,
|
||||
capitalize the previous word, but do not move the cursor.
|
||||
|
||||
@item overwrite-mode ()
|
||||
Toggle overwrite mode. With an explicit positive numeric argument,
|
||||
switches to overwrite mode. With an explicit non-positive numeric
|
||||
argument, switches to insert mode. This command affects only
|
||||
@code{emacs} mode; @code{vi} mode does overwrite differently.
|
||||
Each call to @code{readline()} starts in insert mode.
|
||||
|
||||
In overwrite mode, characters bound to @code{self-insert} replace
|
||||
the text at point rather than pushing the text to the right.
|
||||
Characters bound to @code{backward-delete-char} replace the character
|
||||
before point with a space.
|
||||
|
||||
By default, this command is unbound.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Commands For Killing
|
||||
@@ -1312,12 +1341,19 @@ of that character. A negative count searches for subsequent
|
||||
occurrences.
|
||||
|
||||
@item insert-comment (M-#)
|
||||
The value of the @code{comment-begin}
|
||||
variable is inserted at the beginning of the current line,
|
||||
and the line is accepted as if a newline had been typed.
|
||||
Without a numeric argument, the value of the @code{comment-begin}
|
||||
variable is inserted at the beginning of the current line.
|
||||
If a numeric argument is supplied, this command acts as a toggle: if
|
||||
the characters at the beginning of the line do not match the value
|
||||
of @code{comment-begin}, the value is inserted, otherwise
|
||||
the characters in @code{comment-begin} are deleted from the beginning of
|
||||
the line.
|
||||
In either case, the line is accepted as if a newline had been typed.
|
||||
@ifset BashFeatures
|
||||
The default value of @code{comment-begin} causes this command
|
||||
to make the current line a shell comment.
|
||||
If a numeric argument causes the comment character to be removed, the line
|
||||
will be executed by the shell.
|
||||
@end ifset
|
||||
|
||||
@item dump-functions ()
|
||||
@@ -1339,13 +1375,22 @@ the output is formatted in such a way that it can be made part
|
||||
of an @var{inputrc} file. This command is unbound by default.
|
||||
|
||||
@ifset BashFeatures
|
||||
@item glob-complete-word (M-g)
|
||||
The word before point is treated as a pattern for pathname expansion,
|
||||
with an asterisk implicitly appended. This pattern is used to
|
||||
generate a list of matching file names for possible completions.
|
||||
|
||||
@item glob-expand-word (C-x *)
|
||||
The word before point is treated as a pattern for pathname expansion,
|
||||
and the list of matching file names is inserted, replacing the word.
|
||||
If a numeric argument is supplied, a @samp{*} is appended before
|
||||
pathname expansion.
|
||||
|
||||
@item glob-list-expansions (C-x g)
|
||||
The list of expansions that would have been generated by
|
||||
@code{glob-expand-word} is displayed, and the line is redrawn.
|
||||
If a numeric argument is supplied, a @samp{*} is appended before
|
||||
pathname expansion.
|
||||
|
||||
@item display-shell-version (C-x C-v)
|
||||
Display version information about the current instance of Bash.
|
||||
@@ -1376,13 +1421,26 @@ Accept the current line for execution and fetch the next line
|
||||
relative to the current line from the history for editing. Any
|
||||
argument is ignored.
|
||||
|
||||
@item emacs-editing-mode (C-e)
|
||||
When in @code{vi} editing mode, this causes a switch back to
|
||||
@code{emacs} editing mode, as if the command @samp{set -o emacs} had
|
||||
been executed.
|
||||
@item edit-and-execute-command (C-xC-e)
|
||||
Invoke an editor on the current command line, and execute the result as shell
|
||||
commands.
|
||||
Bash attempts to invoke
|
||||
@code{$FCEDIT}, @code{$EDITOR}, and @code{emacs}
|
||||
as the editor, in that order.
|
||||
|
||||
@end ifset
|
||||
|
||||
@ifclear BashFeatures
|
||||
@item emacs-editing-mode (C-e)
|
||||
When in @code{vi} command mode, this causes a switch to @code{emacs}
|
||||
editing mode.
|
||||
|
||||
@item vi-editing-mode (M-C-j)
|
||||
When in @code{emacs} editing mode, this causes a switch to @code{vi}
|
||||
editing mode.
|
||||
|
||||
@end ifclear
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Readline vi Mode
|
||||
@@ -1518,6 +1576,12 @@ If the @option{-o default} option was supplied to @code{complete} when the
|
||||
compspec was defined, Readline's default completion will be performed
|
||||
if the compspec generates no matches.
|
||||
|
||||
When a compspec indicates that directory name completion is desired,
|
||||
the programmable completion functions force Readline to append a slash
|
||||
to completed names which are symbolic links to directories, subject to
|
||||
the value of the @var{mark-directories} Readline variable, regardless
|
||||
of the setting of the @var{mark-symlinked-directories} Readline variable.
|
||||
|
||||
@node Programmable Completion Builtins
|
||||
@section Programmable Completion Builtins
|
||||
@cindex completion builtins
|
||||
@@ -1553,7 +1617,7 @@ matches were generated.
|
||||
@item complete
|
||||
@btindex complete
|
||||
@example
|
||||
@code{complete [-abcdefgjkvu] [-o @var{comp-option}] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}]
|
||||
@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}]
|
||||
[-P @var{prefix}] [-S @var{suffix}] [-X @var{filterpat}] [-F @var{function}]
|
||||
[-C @var{command}] @var{name} [@var{name} @dots{}]}
|
||||
@code{complete -pr [@var{name} @dots{}]}
|
||||
@@ -1586,7 +1650,8 @@ beyond the simple generation of completions.
|
||||
@table @code
|
||||
|
||||
@item default
|
||||
Use readline's default completion if the compspec generates no matches.
|
||||
Use Readline's default filename completion if the compspec generates
|
||||
no matches.
|
||||
|
||||
@item dirnames
|
||||
Perform directory name completion if the compspec generates no matches.
|
||||
@@ -1596,6 +1661,10 @@ Tell Readline that the compspec generates filenames, so it can perform any
|
||||
filename\-specific processing (like adding a slash to directory names or
|
||||
suppressing trailing spaces). This option is intended to be used with
|
||||
shell functions specified with @option{-F}.
|
||||
|
||||
@item nospace
|
||||
Tell Readline not to append a space (the default) to words completed at
|
||||
the end of the line.
|
||||
@end table
|
||||
|
||||
@item -A @var{action}
|
||||
@@ -1655,6 +1724,9 @@ Shell reserved words. May also be specified as @option{-k}.
|
||||
@item running
|
||||
Names of running jobs, if job control is active.
|
||||
|
||||
@item service
|
||||
Service names. May also be specified as @option{-s}.
|
||||
|
||||
@item setopt
|
||||
Valid arguments for the @option{-o} option to the @code{set} builtin
|
||||
(@pxref{The Set Builtin}).
|
||||
|
||||
@@ -17,7 +17,7 @@ This document describes the end user interface of the GNU Readline Library,
|
||||
a utility which aids in the consistency of user interface across discrete
|
||||
programs that need to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -72,7 +72,7 @@ except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2001 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
|
||||
@@ -35,11 +35,11 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
|
||||
/* Control keys. */
|
||||
{ ISFUNC, rl_set_mark }, /* Control-@ */
|
||||
{ ISFUNC, rl_beg_of_line }, /* Control-a */
|
||||
{ ISFUNC, rl_backward }, /* Control-b */
|
||||
{ ISFUNC, rl_backward_char }, /* Control-b */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
|
||||
{ ISFUNC, rl_delete }, /* Control-d */
|
||||
{ ISFUNC, rl_end_of_line }, /* Control-e */
|
||||
{ ISFUNC, rl_forward }, /* Control-f */
|
||||
{ ISFUNC, rl_forward_char }, /* Control-f */
|
||||
{ ISFUNC, rl_abort }, /* Control-g */
|
||||
{ ISFUNC, rl_rubout }, /* Control-h */
|
||||
{ ISFUNC, rl_complete }, /* Control-i */
|
||||
|
||||
@@ -4,6 +4,22 @@
|
||||
# on which program is running, or what terminal is active.
|
||||
#
|
||||
|
||||
# Copyright (C) 1989-2002 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
# In all programs, all terminals, make sure this is bound.
|
||||
"\C-x\C-r": re-read-init-file
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ fileman: fileman.o
|
||||
rltest: rltest.o
|
||||
$(CC) $(LDFLAGS) -o $@ rltest.o -lreadline -ltermcap
|
||||
|
||||
rlcat: rlcat.o
|
||||
$(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline -ltermcap
|
||||
|
||||
fileman.o: fileman.c
|
||||
rltest.o: rltest.c
|
||||
rl.o: rl.c
|
||||
rlcat.o: rlcat.c
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
/* fileman.c -- A tiny application which demonstrates how to use the
|
||||
GNU Readline library. This application interactively allows users
|
||||
to manipulate files and their modes. */
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef READLINE_LIBRARY
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
/* manexamp.c -- The examples which appear in the documentation are here. */
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
|
||||
|
||||
@@ -5,6 +5,26 @@
|
||||
* usage: rl [-p prompt] [-u unit] [-d default] [-n nchars]
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* rlcat - cat(1) using readline
|
||||
*
|
||||
* usage: rlcat
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "posixstat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if defined (READLINE_LIBRARY)
|
||||
# include "readline.h"
|
||||
# include "history.h"
|
||||
#else
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
static int stdcat();
|
||||
|
||||
static char *progname;
|
||||
static int vflag;
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *temp;
|
||||
int opt, Vflag, Nflag;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == 0)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
vflag = Vflag = Nflag = 0;
|
||||
while ((opt = getopt(argc, argv, "vEVN")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
case 'V':
|
||||
Vflag = 1;
|
||||
break;
|
||||
case 'E':
|
||||
Vflag = 0;
|
||||
break;
|
||||
case 'N':
|
||||
Nflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
exit (2);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (isatty(0) == 0 || argc || Nflag)
|
||||
return stdcat(argc, argv);
|
||||
|
||||
rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
|
||||
while (temp = readline (""))
|
||||
{
|
||||
if (*temp)
|
||||
add_history (temp);
|
||||
printf ("%s\n", temp);
|
||||
}
|
||||
|
||||
return (ferror (stdout));
|
||||
}
|
||||
|
||||
static int
|
||||
fcopy(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int c;
|
||||
char *x;
|
||||
|
||||
while ((c = getc(fp)) != EOF)
|
||||
{
|
||||
if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0)
|
||||
{
|
||||
x = rl_untranslate_keyseq (c);
|
||||
if (fputs (x, stdout) != 0)
|
||||
return 1;
|
||||
}
|
||||
else if (putchar (c) == EOF)
|
||||
return 1;
|
||||
}
|
||||
return (ferror (stdout));
|
||||
}
|
||||
|
||||
int
|
||||
stdcat (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int i, fd, r;
|
||||
char *s;
|
||||
FILE *fp;
|
||||
|
||||
if (argc == 0)
|
||||
return (fcopy(stdin));
|
||||
|
||||
for (i = 0, r = 1; i < argc; i++)
|
||||
{
|
||||
if (*argv[i] == '-' && argv[i][1] == 0)
|
||||
fp = stdin;
|
||||
else
|
||||
{
|
||||
fp = fopen (argv[i], "r");
|
||||
if (fp == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
r = fcopy (fp);
|
||||
if (fp != stdin)
|
||||
fclose(fp);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -4,6 +4,26 @@
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,8 @@ static FUNMAP default_funmap[] = {
|
||||
{ "abort", rl_abort },
|
||||
{ "accept-line", rl_newline },
|
||||
{ "arrow-key-prefix", rl_arrow_keys },
|
||||
{ "backward-char", rl_backward },
|
||||
{ "backward-byte", rl_backward_byte },
|
||||
{ "backward-char", rl_backward_char },
|
||||
{ "backward-delete-char", rl_rubout },
|
||||
{ "backward-kill-line", rl_backward_kill_line },
|
||||
{ "backward-kill-word", rl_backward_kill_word },
|
||||
@@ -91,7 +92,8 @@ static FUNMAP default_funmap[] = {
|
||||
{ "end-of-line", rl_end_of_line },
|
||||
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
|
||||
{ "forward-backward-delete-char", rl_rubout_or_delete },
|
||||
{ "forward-char", rl_forward },
|
||||
{ "forward-byte", rl_forward_byte },
|
||||
{ "forward-char", rl_forward_char },
|
||||
{ "forward-search-history", rl_forward_search_history },
|
||||
{ "forward-word", rl_forward_word },
|
||||
{ "history-search-backward", rl_history_search_backward },
|
||||
@@ -108,6 +110,7 @@ static FUNMAP default_funmap[] = {
|
||||
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search },
|
||||
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
|
||||
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
|
||||
{ "overwrite-mode", rl_overwrite_mode },
|
||||
#ifdef __CYGWIN__
|
||||
{ "paste-from-clipboard", rl_paste_from_clipboard },
|
||||
#endif
|
||||
|
||||
+131
-18
@@ -41,11 +41,7 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
#include "rlmbutil.h"
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
@@ -58,6 +54,8 @@
|
||||
|
||||
typedef int _hist_search_func_t PARAMS((const char *, int));
|
||||
|
||||
extern int rl_byte_oriented; /* declared in mbutil.c */
|
||||
|
||||
static char error_pointer;
|
||||
|
||||
static char *subst_lhs;
|
||||
@@ -204,12 +202,30 @@ get_history_event (string, caller_index, delimiting_quote)
|
||||
|
||||
/* Only a closing `?' or a newline delimit a substring search string. */
|
||||
for (local_index = i; c = string[i]; i++)
|
||||
if ((!substring_okay && (whitespace (c) || c == ':' ||
|
||||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
|
||||
string[i] == delimiting_quote)) ||
|
||||
string[i] == '\n' ||
|
||||
(substring_okay && string[i] == '?'))
|
||||
break;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int v;
|
||||
mbstate_t ps;
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
/* These produce warnings because we're passing a const string to a
|
||||
function that takes a non-const string. */
|
||||
_rl_adjust_point (string, i, &ps);
|
||||
if ((v = _rl_get_char_len (string + i, &ps)) > 1)
|
||||
{
|
||||
i += v - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
if ((!substring_okay && (whitespace (c) || c == ':' ||
|
||||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
|
||||
string[i] == delimiting_quote)) ||
|
||||
string[i] == '\n' ||
|
||||
(substring_okay && string[i] == '?'))
|
||||
break;
|
||||
|
||||
which = i - local_index;
|
||||
temp = (char *)xmalloc (1 + which);
|
||||
@@ -405,13 +421,33 @@ get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
|
||||
int *iptr, delimiter, is_rhs, *lenptr;
|
||||
{
|
||||
register int si, i, j, k;
|
||||
char *s = (char *) NULL;
|
||||
char *s;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps;
|
||||
#endif
|
||||
|
||||
s = (char *)NULL;
|
||||
i = *iptr;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
_rl_adjust_point (str, i, &ps);
|
||||
#endif
|
||||
|
||||
for (si = i; str[si] && str[si] != delimiter; si++)
|
||||
if (str[si] == '\\' && str[si + 1] == delimiter)
|
||||
si++;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int v;
|
||||
if ((v = _rl_get_char_len (str + si, &ps)) > 1)
|
||||
si += v - 1;
|
||||
else if (str[si] == '\\' && str[si + 1] == delimiter)
|
||||
si++;
|
||||
}
|
||||
else
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
if (str[si] == '\\' && str[si + 1] == delimiter)
|
||||
si++;
|
||||
|
||||
if (si > i || is_rhs)
|
||||
{
|
||||
@@ -484,6 +520,11 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
||||
int substitute_globally, want_quotes, print_only;
|
||||
char *event, *temp, *result, *tstr, *t, c, *word_spec;
|
||||
int result_len;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps;
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
|
||||
result = (char *)xmalloc (result_len = 128);
|
||||
|
||||
@@ -514,8 +555,21 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
||||
quote, then this expansion takes place inside of the
|
||||
quoted string. If we have to search for some text ("!foo"),
|
||||
allow the delimiter to end the search string. */
|
||||
if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
|
||||
quoted_search_delimiter = string[i - 1];
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int c, l;
|
||||
l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY);
|
||||
c = string[l];
|
||||
/* XXX - original patch had i - 1 ??? If i == 0 it would fail. */
|
||||
if (i && (c == '\'' || c == '"'))
|
||||
quoted_search_delimiter = c;
|
||||
}
|
||||
else
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
|
||||
quoted_search_delimiter = string[i - 1];
|
||||
|
||||
event = get_history_event (string, &i, quoted_search_delimiter);
|
||||
}
|
||||
|
||||
@@ -634,7 +688,20 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
||||
if (c == 's')
|
||||
{
|
||||
if (i + 2 < (int)strlen (string))
|
||||
delimiter = string[i + 2];
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
_rl_adjust_point (string, i + 2, &ps);
|
||||
if (_rl_get_char_len (string + i + 2, &ps) > 1)
|
||||
delimiter = 0;
|
||||
else
|
||||
delimiter = string[i + 2];
|
||||
}
|
||||
else
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
delimiter = string[i + 2];
|
||||
}
|
||||
else
|
||||
break; /* no search delimiter */
|
||||
|
||||
@@ -819,6 +886,11 @@ history_expand (hstring, output)
|
||||
int result_len;
|
||||
char *result;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
char mb[MB_LEN_MAX];
|
||||
mbstate_t ps;
|
||||
#endif
|
||||
|
||||
/* Used when adding the string. */
|
||||
char *temp;
|
||||
|
||||
@@ -861,6 +933,10 @@ history_expand (hstring, output)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
|
||||
string = hstring;
|
||||
/* If not quick substitution, still maybe have to do expansion. */
|
||||
|
||||
@@ -868,8 +944,21 @@ history_expand (hstring, output)
|
||||
is NOT an expansion. */
|
||||
for (i = 0; string[i]; i++)
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int v;
|
||||
v = _rl_get_char_len (string + i, &ps);
|
||||
if (v > 1)
|
||||
{
|
||||
i += v - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
cc = string[i + 1];
|
||||
/* The history_comment_char, if set, appearing that the beginning
|
||||
/* The history_comment_char, if set, appearing at the beginning
|
||||
of a word signifies that the rest of the line should not have
|
||||
history expansion performed on it.
|
||||
Skip the rest of the line and break out of the loop. */
|
||||
@@ -932,6 +1021,30 @@ history_expand (hstring, output)
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int k, c;
|
||||
|
||||
c = tchar;
|
||||
memset (mb, 0, sizeof (mb));
|
||||
for (k = 0; k < MB_LEN_MAX; k++)
|
||||
{
|
||||
mb[k] = (char)c;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
if (_rl_get_char_len (mb, &ps) == -2)
|
||||
c = string[++i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (strlen (mb) > 1)
|
||||
{
|
||||
ADD_STRING (mb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
if (tchar == history_expansion_char)
|
||||
tchar = -3;
|
||||
else if (tchar == history_comment_char)
|
||||
|
||||
+108
-38
@@ -48,12 +48,26 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
#if defined (__EMX__) || defined (__CYGWIN__)
|
||||
# undef HAVE_MMAP
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
# include <sys/mman.h>
|
||||
|
||||
# ifdef MAP_FILE
|
||||
# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
|
||||
# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
|
||||
# else
|
||||
# define MAP_RFLAGS MAP_PRIVATE
|
||||
# define MAP_WFLAGS MAP_SHARED
|
||||
# endif
|
||||
|
||||
# ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void *)-1)
|
||||
# endif
|
||||
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
|
||||
on win 95/98/nt), we want to open files with O_BINARY mode so that there
|
||||
@@ -137,8 +151,8 @@ read_history_range (filename, from, to)
|
||||
const char *filename;
|
||||
int from, to;
|
||||
{
|
||||
register int line_start, line_end;
|
||||
char *input, *buffer;
|
||||
register char *line_start, *line_end;
|
||||
char *input, *buffer, *bufend;
|
||||
int file, current_line, chars_read;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
@@ -157,23 +171,39 @@ read_history_range (filename, from, to)
|
||||
{
|
||||
#if defined (EFBIG)
|
||||
errno = EFBIG;
|
||||
#elif defined (EOVERFLOW)
|
||||
errno = EOVERFLOW;
|
||||
#endif
|
||||
goto error_and_exit;
|
||||
}
|
||||
|
||||
buffer = (char *)xmalloc (file_size + 1);
|
||||
#ifdef HAVE_MMAP
|
||||
/* We map read/write and private so we can change newlines to NULs without
|
||||
affecting the underlying object. */
|
||||
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
|
||||
if ((void *)buffer == MAP_FAILED)
|
||||
goto error_and_exit;
|
||||
chars_read = file_size;
|
||||
#else
|
||||
buffer = (char *)malloc (file_size + 1);
|
||||
if (buffer == 0)
|
||||
goto error_and_exit;
|
||||
|
||||
chars_read = read (file, buffer, file_size);
|
||||
#endif
|
||||
if (chars_read < 0)
|
||||
{
|
||||
error_and_exit:
|
||||
chars_read = errno;
|
||||
if (file >= 0)
|
||||
close (file);
|
||||
|
||||
FREE (input);
|
||||
#ifndef HAVE_MMAP
|
||||
FREE (buffer);
|
||||
#endif
|
||||
|
||||
return (errno);
|
||||
return (chars_read);
|
||||
}
|
||||
|
||||
close (file);
|
||||
@@ -183,29 +213,25 @@ read_history_range (filename, from, to)
|
||||
to = chars_read;
|
||||
|
||||
/* Start at beginning of file, work to end. */
|
||||
line_start = line_end = current_line = 0;
|
||||
bufend = buffer + chars_read;
|
||||
current_line = 0;
|
||||
|
||||
/* Skip lines until we are at FROM. */
|
||||
while (line_start < chars_read && current_line < from)
|
||||
{
|
||||
for (line_end = line_start; line_end < chars_read; line_end++)
|
||||
if (buffer[line_end] == '\n')
|
||||
{
|
||||
current_line++;
|
||||
line_start = line_end + 1;
|
||||
if (current_line == from)
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
|
||||
if (*line_end == '\n')
|
||||
{
|
||||
current_line++;
|
||||
line_start = line_end + 1;
|
||||
}
|
||||
|
||||
/* If there are lines left to gobble, then gobble them now. */
|
||||
for (line_end = line_start; line_end < chars_read; line_end++)
|
||||
if (buffer[line_end] == '\n')
|
||||
for (line_end = line_start; line_end < bufend; line_end++)
|
||||
if (*line_end == '\n')
|
||||
{
|
||||
buffer[line_end] = '\0';
|
||||
*line_end = '\0';
|
||||
|
||||
if (buffer[line_start])
|
||||
add_history (buffer + line_start);
|
||||
if (*line_start)
|
||||
add_history (line_start);
|
||||
|
||||
current_line++;
|
||||
|
||||
@@ -216,7 +242,11 @@ read_history_range (filename, from, to)
|
||||
}
|
||||
|
||||
FREE (input);
|
||||
#ifndef HAVE_MMAP
|
||||
FREE (buffer);
|
||||
#else
|
||||
munmap (buffer, file_size);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -229,9 +259,8 @@ history_truncate_file (fname, lines)
|
||||
const char *fname;
|
||||
int lines;
|
||||
{
|
||||
register int i;
|
||||
char *buffer, *filename, *bp;
|
||||
int file, chars_read, rv;
|
||||
char *buffer, *filename;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
|
||||
@@ -276,7 +305,13 @@ history_truncate_file (fname, lines)
|
||||
goto truncate_exit;
|
||||
}
|
||||
|
||||
buffer = (char *)xmalloc (file_size + 1);
|
||||
buffer = (char *)malloc (file_size + 1);
|
||||
if (buffer == 0)
|
||||
{
|
||||
close (file);
|
||||
goto truncate_exit;
|
||||
}
|
||||
|
||||
chars_read = read (file, buffer, file_size);
|
||||
close (file);
|
||||
|
||||
@@ -288,9 +323,9 @@ history_truncate_file (fname, lines)
|
||||
|
||||
/* Count backwards from the end of buffer until we have passed
|
||||
LINES lines. */
|
||||
for (i = chars_read - 1; lines && i; i--)
|
||||
for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
if (*bp == '\n')
|
||||
lines--;
|
||||
}
|
||||
|
||||
@@ -299,22 +334,22 @@ history_truncate_file (fname, lines)
|
||||
anything. It's the first line if we don't find a newline between
|
||||
the current value of i and 0. Otherwise, write from the start of
|
||||
this line until the end of the buffer. */
|
||||
for ( ; i; i--)
|
||||
if (buffer[i] == '\n')
|
||||
for ( ; bp > buffer; bp--)
|
||||
if (*bp == '\n')
|
||||
{
|
||||
i++;
|
||||
bp++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write only if there are more lines in the file than we want to
|
||||
truncate to. */
|
||||
if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
|
||||
if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
|
||||
{
|
||||
write (file, buffer + i, chars_read - i);
|
||||
write (file, bp, chars_read - (bp - buffer));
|
||||
|
||||
#if defined (__BEOS__)
|
||||
/* BeOS ignores O_TRUNC. */
|
||||
ftruncate (file, chars_read - i);
|
||||
ftruncate (file, chars_read - (bp - buffer));
|
||||
#endif
|
||||
|
||||
close (file);
|
||||
@@ -339,8 +374,13 @@ history_do_write (filename, nelements, overwrite)
|
||||
register int i;
|
||||
char *output;
|
||||
int file, mode, rv;
|
||||
size_t cursize;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
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);
|
||||
rv = 0;
|
||||
|
||||
@@ -350,6 +390,10 @@ history_do_write (filename, nelements, overwrite)
|
||||
return (errno);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
|
||||
#endif
|
||||
|
||||
if (nelements > history_length)
|
||||
nelements = history_length;
|
||||
|
||||
@@ -367,7 +411,28 @@ history_do_write (filename, nelements, overwrite)
|
||||
buffer_size += 1 + strlen (the_history[i]->line);
|
||||
|
||||
/* Allocate the buffer, and fill it. */
|
||||
buffer = (char *)xmalloc (buffer_size);
|
||||
#ifdef HAVE_MMAP
|
||||
if (ftruncate (file, buffer_size+cursize) == -1)
|
||||
goto mmap_error;
|
||||
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
|
||||
if ((void *)buffer == MAP_FAILED)
|
||||
{
|
||||
mmap_error:
|
||||
rv = errno;
|
||||
FREE (output);
|
||||
close (file);
|
||||
return rv;
|
||||
}
|
||||
#else
|
||||
buffer = (char *)malloc (buffer_size);
|
||||
if (buffer == 0)
|
||||
{
|
||||
rv = errno;
|
||||
FREE (output);
|
||||
close (file);
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (j = 0, i = history_length - nelements; i < history_length; i++)
|
||||
{
|
||||
@@ -376,9 +441,14 @@ history_do_write (filename, nelements, overwrite)
|
||||
buffer[j++] = '\n';
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
|
||||
rv = errno;
|
||||
#else
|
||||
if (write (file, buffer, buffer_size) < 0)
|
||||
rv = errno;
|
||||
free (buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
close (file);
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
#if !defined (_HISTLIB_H_)
|
||||
#define _HISTLIB_H_
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#if !defined (STREQ)
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((n) == 0) ? (1) \
|
||||
@@ -29,9 +35,6 @@
|
||||
#endif
|
||||
|
||||
#ifndef savestring
|
||||
# ifndef strcpy
|
||||
extern char *strcpy ();
|
||||
# endif
|
||||
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
|
||||
#endif
|
||||
|
||||
|
||||
+6
-12
@@ -44,12 +44,6 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
|
||||
@@ -349,19 +343,19 @@ stifle_history (max)
|
||||
max_input_history = history_max_entries = max;
|
||||
}
|
||||
|
||||
/* Stop stifling the history. This returns the previous amount the
|
||||
history was stifled by. The value is positive if the history was
|
||||
stifled, negative if it wasn't. */
|
||||
/* Stop stifling the history. This returns the previous maximum
|
||||
number of history entries. The value is positive if the history
|
||||
was stifled, negative if it wasn't. */
|
||||
int
|
||||
unstifle_history ()
|
||||
{
|
||||
if (history_stifled)
|
||||
{
|
||||
history_stifled = 0;
|
||||
return (-history_max_entries);
|
||||
return (history_max_entries);
|
||||
}
|
||||
|
||||
return (history_max_entries);
|
||||
else
|
||||
return (-history_max_entries);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -32,17 +32,13 @@
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
|
||||
+111
-14
@@ -63,6 +63,7 @@ extern int errno;
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
@@ -86,8 +87,7 @@ static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
|
||||
|
||||
static int ibuffer_space PARAMS((void));
|
||||
static int rl_get_char PARAMS((int *));
|
||||
static int rl_unget_char PARAMS((int));
|
||||
static void rl_gather_tyi PARAMS((void));
|
||||
static int rl_gather_tyi PARAMS((void));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -139,8 +139,8 @@ rl_get_char (key)
|
||||
/* Stuff KEY into the *front* of the input buffer.
|
||||
Returns non-zero if successful, zero if there is
|
||||
no space left in the buffer. */
|
||||
static int
|
||||
rl_unget_char (key)
|
||||
int
|
||||
_rl_unget_char (key)
|
||||
int key;
|
||||
{
|
||||
if (ibuffer_space ())
|
||||
@@ -154,9 +154,10 @@ rl_unget_char (key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* If a character is available to be read, then read it
|
||||
and stuff it into IBUFFER. Otherwise, just return. */
|
||||
static void
|
||||
/* If a character is available to be read, then read it and stuff it into
|
||||
IBUFFER. Otherwise, just return. Returns number of characters read
|
||||
(0 if none available) and -1 on error (EIO). */
|
||||
static int
|
||||
rl_gather_tyi ()
|
||||
{
|
||||
int tty;
|
||||
@@ -177,13 +178,17 @@ rl_gather_tyi ()
|
||||
FD_SET (tty, &exceptfds);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = _keyboard_input_timeout;
|
||||
if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
|
||||
return; /* Nothing to read. */
|
||||
result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
|
||||
if (result <= 0)
|
||||
return 0; /* Nothing to read. */
|
||||
#endif
|
||||
|
||||
result = -1;
|
||||
#if defined (FIONREAD)
|
||||
errno = 0;
|
||||
result = ioctl (tty, FIONREAD, &chars_avail);
|
||||
if (result == -1 && errno == EIO)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#if defined (O_NDELAY)
|
||||
@@ -196,14 +201,14 @@ rl_gather_tyi ()
|
||||
|
||||
fcntl (tty, F_SETFL, tem);
|
||||
if (chars_avail == -1 && errno == EAGAIN)
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif /* O_NDELAY */
|
||||
|
||||
/* If there's nothing available, don't waste time trying to read
|
||||
something. */
|
||||
if (chars_avail <= 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
tem = ibuffer_space ();
|
||||
|
||||
@@ -227,6 +232,8 @@ rl_gather_tyi ()
|
||||
if (chars_avail)
|
||||
rl_stuff_char (input);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -242,7 +249,11 @@ rl_set_keyboard_input_timeout (u)
|
||||
}
|
||||
|
||||
/* Is there input available to be read on the readline input file
|
||||
descriptor? Only works if the system has select(2) or FIONREAD. */
|
||||
descriptor? Only works if the system has select(2) or FIONREAD.
|
||||
Uses the value of _keyboard_input_timeout as the timeout; if another
|
||||
readline function wants to specify a timeout and not leave it up to
|
||||
the user, it should use _rl_input_queued(timeout_value_in_microseconds)
|
||||
instead. */
|
||||
int
|
||||
_rl_input_available ()
|
||||
{
|
||||
@@ -277,6 +288,18 @@ _rl_input_available ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_input_queued (t)
|
||||
int t;
|
||||
{
|
||||
int old_timeout, r;
|
||||
|
||||
old_timeout = rl_set_keyboard_input_timeout (t);
|
||||
r = _rl_input_available ();
|
||||
rl_set_keyboard_input_timeout (old_timeout);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_insert_typein (c)
|
||||
int c;
|
||||
@@ -294,7 +317,7 @@ _rl_insert_typein (c)
|
||||
string[i++] = key;
|
||||
|
||||
if (t)
|
||||
rl_unget_char (key);
|
||||
_rl_unget_char (key);
|
||||
|
||||
string[i] = '\0';
|
||||
rl_insert_text (string);
|
||||
@@ -375,7 +398,11 @@ rl_read_key ()
|
||||
(*rl_event_hook) ();
|
||||
if (rl_done) /* XXX - experimental */
|
||||
return ('\n');
|
||||
rl_gather_tyi ();
|
||||
if (rl_gather_tyi () < 0) /* XXX - EIO */
|
||||
{
|
||||
rl_done = 1;
|
||||
return ('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -441,3 +468,73 @@ rl_getc (stream)
|
||||
return (EOF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* read multibyte char */
|
||||
int
|
||||
_rl_read_mbchar (mbchar, size)
|
||||
char *mbchar;
|
||||
int size;
|
||||
{
|
||||
int mb_len = 0;
|
||||
size_t mbchar_bytes_length;
|
||||
wchar_t wc;
|
||||
mbstate_t ps, ps_back;
|
||||
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
memset(&ps_back, 0, sizeof (mbstate_t));
|
||||
|
||||
while (mb_len < size)
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
mbchar[mb_len++] = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
|
||||
if (mbchar_bytes_length == (size_t)(-1))
|
||||
break; /* invalid byte sequence for the current locale */
|
||||
else if (mbchar_bytes_length == (size_t)(-2))
|
||||
{
|
||||
/* shorted bytes */
|
||||
ps = ps_back;
|
||||
continue;
|
||||
}
|
||||
else if (mbchar_bytes_length > (size_t)(0))
|
||||
break;
|
||||
}
|
||||
|
||||
return mb_len;
|
||||
}
|
||||
|
||||
/* Read a multibyte-character string whose first character is FIRST into
|
||||
the buffer MB of length MBLEN. Returns the last character read, which
|
||||
may be FIRST. Used by the search functions, among others. Very similar
|
||||
to _rl_read_mbchar. */
|
||||
int
|
||||
_rl_read_mbstring (first, mb, mblen)
|
||||
int first;
|
||||
char *mb;
|
||||
int mblen;
|
||||
{
|
||||
int i, c;
|
||||
mbstate_t ps;
|
||||
|
||||
c = first;
|
||||
memset (mb, 0, mblen);
|
||||
for (i = 0; i < mblen; i++)
|
||||
{
|
||||
mb[i] = (char)c;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
if (_rl_get_char_len (mb, &ps) == -2)
|
||||
{
|
||||
/* Read more for multibyte character */
|
||||
RL_SETSTATE (RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE (RL_STATE_MOREINPUT);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
+130
-43
@@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
@@ -45,6 +45,8 @@
|
||||
#endif
|
||||
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
@@ -165,8 +167,12 @@ rl_search_history (direction, invoking_key)
|
||||
HIST_ENTRY **hlist;
|
||||
|
||||
register int i;
|
||||
int orig_point, orig_line, last_found_line;
|
||||
int orig_point, orig_mark, orig_line, last_found_line;
|
||||
int c, found, failed, sline_len;
|
||||
int n, wstart, wlen;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
char mb[MB_LEN_MAX];
|
||||
#endif
|
||||
|
||||
/* The line currently being searched. */
|
||||
char *sline;
|
||||
@@ -184,6 +190,7 @@ rl_search_history (direction, invoking_key)
|
||||
|
||||
RL_SETSTATE(RL_STATE_ISEARCH);
|
||||
orig_point = rl_point;
|
||||
orig_mark = rl_mark;
|
||||
last_found_line = orig_line = where_history ();
|
||||
reverse = direction < 0;
|
||||
hlist = history_list ();
|
||||
@@ -246,6 +253,12 @@ rl_search_history (direction, invoking_key)
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
|
||||
#endif
|
||||
|
||||
/* Translate the keys we do something with to opcodes. */
|
||||
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
|
||||
{
|
||||
f = _rl_keymap[c].function;
|
||||
@@ -254,33 +267,53 @@ rl_search_history (direction, invoking_key)
|
||||
c = reverse ? -1 : -2;
|
||||
else if (f == rl_forward_search_history)
|
||||
c = !reverse ? -1 : -2;
|
||||
else if (f == rl_rubout)
|
||||
c = -3;
|
||||
else if (c == CTRL ('G'))
|
||||
c = -4;
|
||||
else if (c == CTRL ('W')) /* XXX */
|
||||
c = -5;
|
||||
else if (c == CTRL ('Y')) /* XXX */
|
||||
c = -6;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Let NEWLINE (^J) terminate the search for people who don't like
|
||||
using ESC. ^M can still be used to terminate the search and
|
||||
immediately execute the command. */
|
||||
if (c == ESC || c == NEWLINE)
|
||||
#else
|
||||
/* The characters in isearch_terminators (set from the user-settable
|
||||
variable isearch-terminators) are used to terminate the search but
|
||||
not subsequently execute the character as a command. The default
|
||||
value is "\033\012" (ESC and C-J). */
|
||||
if (strchr (isearch_terminators, c))
|
||||
#endif
|
||||
{
|
||||
/* ESC still terminates the search, but if there is pending
|
||||
input or if input arrives within 0.1 seconds (on systems
|
||||
with select(2)) it is used as a prefix character
|
||||
with rl_execute_next. WATCH OUT FOR THIS! This is intended
|
||||
to allow the arrow keys to be used like ^F and ^B are used
|
||||
to terminate the search and execute the movement command. */
|
||||
if (c == ESC && _rl_input_available ()) /* XXX */
|
||||
to terminate the search and execute the movement command.
|
||||
XXX - since _rl_input_available depends on the application-
|
||||
settable keyboard timeout value, this could alternatively
|
||||
use _rl_input_queued(100000) */
|
||||
if (c == ESC && _rl_input_available ())
|
||||
rl_execute_next (ESC);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT) && c != CTRL ('G'))
|
||||
#define ENDSRCH_CHAR(c) \
|
||||
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
|
||||
{
|
||||
/* This sets rl_pending_input to c; it will be picked up the next
|
||||
time rl_read_key is called. */
|
||||
rl_execute_next (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c >= 0 && ENDSRCH_CHAR (c))
|
||||
{
|
||||
/* This sets rl_pending_input to c; it will be picked up the next
|
||||
time rl_read_key is called. */
|
||||
@@ -318,10 +351,23 @@ rl_search_history (direction, invoking_key)
|
||||
reverse = direction < 0;
|
||||
break;
|
||||
|
||||
case CTRL ('G'):
|
||||
strcpy (rl_line_buffer, lines[orig_line]);
|
||||
/* delete character from search string. */
|
||||
case -3: /* C-H, DEL */
|
||||
/* This is tricky. To do this right, we need to keep a
|
||||
stack of search positions for the current search, with
|
||||
sentinels marking the beginning and end. But this will
|
||||
do until we have a real isearch-undo. */
|
||||
if (search_string_index == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
search_string[--search_string_index] = '\0';
|
||||
|
||||
break;
|
||||
|
||||
case -4: /* C-G */
|
||||
rl_replace_line (lines[orig_line], 0);
|
||||
rl_point = orig_point;
|
||||
rl_end = strlen (rl_line_buffer);
|
||||
rl_mark = orig_mark;
|
||||
rl_restore_prompt();
|
||||
rl_clear_message ();
|
||||
if (allocated_line)
|
||||
@@ -330,20 +376,53 @@ rl_search_history (direction, invoking_key)
|
||||
RL_UNSETSTATE(RL_STATE_ISEARCH);
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
/* delete character from search string. */
|
||||
case -3:
|
||||
if (search_string_index == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
case -5: /* C-W */
|
||||
/* skip over portion of line we already matched */
|
||||
wstart = rl_point + search_string_index;
|
||||
if (wstart >= rl_end)
|
||||
{
|
||||
search_string[--search_string_index] = '\0';
|
||||
/* This is tricky. To do this right, we need to keep a
|
||||
stack of search positions for the current search, with
|
||||
sentinels marking the beginning and end. */
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not in a word, move to one. */
|
||||
if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
n = wstart;
|
||||
while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
|
||||
n++;
|
||||
wlen = n - wstart + 1;
|
||||
if (search_string_index + wlen + 1 >= search_string_size)
|
||||
{
|
||||
search_string_size += wlen + 1;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
for (; wstart < n; wstart++)
|
||||
search_string[search_string_index++] = rl_line_buffer[wstart];
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
|
||||
case -6: /* C-Y */
|
||||
/* skip over portion of line we already matched */
|
||||
wstart = rl_point + search_string_index;
|
||||
if (wstart >= rl_end)
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
n = rl_end - wstart + 1;
|
||||
if (search_string_index + n + 1 >= search_string_size)
|
||||
{
|
||||
search_string_size += n + 1;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
for (n = wstart; n < rl_end; n++)
|
||||
search_string[search_string_index++] = rl_line_buffer[n];
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/* Add character to search string and continue search. */
|
||||
@@ -352,7 +431,16 @@ rl_search_history (direction, invoking_key)
|
||||
search_string_size += 128;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
search_string[search_string_index++] = c;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int j, l;
|
||||
for (j = 0, l = strlen (mb); j < l; )
|
||||
search_string[search_string_index++] = mb[j++];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
search_string[search_string_index++] = c;
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
}
|
||||
@@ -417,17 +505,9 @@ rl_search_history (direction, invoking_key)
|
||||
the location. */
|
||||
if (found)
|
||||
{
|
||||
int line_len;
|
||||
|
||||
prev_line_found = lines[i];
|
||||
line_len = strlen (lines[i]);
|
||||
|
||||
if (line_len >= rl_line_buffer_len)
|
||||
rl_extend_line_buffer (line_len);
|
||||
|
||||
strcpy (rl_line_buffer, lines[i]);
|
||||
rl_replace_line (lines[i], 0);
|
||||
rl_point = line_index;
|
||||
rl_end = line_len;
|
||||
last_found_line = i;
|
||||
rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
|
||||
}
|
||||
@@ -443,25 +523,32 @@ rl_search_history (direction, invoking_key)
|
||||
|
||||
rl_restore_prompt ();
|
||||
|
||||
#if 1
|
||||
/* Save the search string for possible later use. */
|
||||
FREE (last_isearch_string);
|
||||
last_isearch_string = search_string;
|
||||
last_isearch_string_len = search_string_index;
|
||||
#else
|
||||
/* Free the search string. */
|
||||
free (search_string);
|
||||
#endif
|
||||
|
||||
if (last_found_line < orig_line)
|
||||
rl_get_previous_history (orig_line - last_found_line, 0);
|
||||
else
|
||||
rl_get_next_history (last_found_line - orig_line, 0);
|
||||
|
||||
/* If the string was not found, put point at the end of the line. */
|
||||
/* If the string was not found, put point at the end of the last matching
|
||||
line. If last_found_line == orig_line, we didn't find any matching
|
||||
history lines at all, so put point back in its original position. */
|
||||
if (line_index < 0)
|
||||
line_index = strlen (rl_line_buffer);
|
||||
{
|
||||
if (last_found_line == orig_line)
|
||||
line_index = orig_point;
|
||||
else
|
||||
line_index = strlen (rl_line_buffer);
|
||||
rl_mark = orig_mark;
|
||||
}
|
||||
|
||||
rl_point = line_index;
|
||||
/* Don't worry about where to put the mark here; rl_get_previous_history
|
||||
and rl_get_next_history take care of it. */
|
||||
|
||||
rl_clear_message ();
|
||||
|
||||
FREE (allocated_line);
|
||||
|
||||
@@ -49,8 +49,9 @@ typedef struct _keymap_entry {
|
||||
|
||||
/* This must be large enough to hold bindings for all of the characters
|
||||
in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
|
||||
and so on). */
|
||||
#define KEYMAP_SIZE 256
|
||||
and so on) plus one for subsequence matching. */
|
||||
#define KEYMAP_SIZE 257
|
||||
#define ANYOTHERKEY KEYMAP_SIZE-1
|
||||
|
||||
/* I wanted to make the above structure contain a union of:
|
||||
union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
|
||||
|
||||
+32
-13
@@ -201,18 +201,21 @@ int
|
||||
rl_kill_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
int orig_point;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_backward_kill_word (-count, key));
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
rl_forward_word (count, key);
|
||||
|
||||
if (rl_point != orig_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
|
||||
rl_point = orig_point;
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -222,16 +225,20 @@ int
|
||||
rl_backward_kill_word (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
int orig_point;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_kill_word (-count, ignore));
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
rl_backward_word (count, ignore);
|
||||
|
||||
if (rl_point != orig_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -242,16 +249,19 @@ int
|
||||
rl_kill_line (direction, ignore)
|
||||
int direction, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
int orig_point;
|
||||
|
||||
if (direction < 0)
|
||||
return (rl_backward_kill_line (1, ignore));
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
rl_end_of_line (1, ignore);
|
||||
if (orig_point != rl_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
rl_point = orig_point;
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -262,7 +272,7 @@ int
|
||||
rl_backward_kill_line (direction, ignore)
|
||||
int direction, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
int orig_point;
|
||||
|
||||
if (direction < 0)
|
||||
return (rl_kill_line (1, ignore));
|
||||
@@ -272,8 +282,12 @@ rl_backward_kill_line (direction, ignore)
|
||||
rl_ding ();
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
rl_beg_of_line (1, ignore);
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
if (rl_point != orig_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -287,6 +301,7 @@ rl_kill_full_line (count, ignore)
|
||||
rl_begin_undo_group ();
|
||||
rl_point = 0;
|
||||
rl_kill_text (rl_point, rl_end);
|
||||
rl_mark = 0;
|
||||
rl_end_undo_group ();
|
||||
return 0;
|
||||
}
|
||||
@@ -321,6 +336,8 @@ rl_unix_word_rubout (count, key)
|
||||
}
|
||||
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -341,6 +358,8 @@ rl_unix_line_discard (count, key)
|
||||
{
|
||||
rl_kill_text (rl_point, 0);
|
||||
rl_point = 0;
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -353,17 +372,14 @@ region_kill_internal (delete)
|
||||
{
|
||||
char *text;
|
||||
|
||||
if (rl_mark == rl_point)
|
||||
if (rl_mark != rl_point)
|
||||
{
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
text = rl_copy_text (rl_point, rl_mark);
|
||||
if (delete)
|
||||
rl_delete_text (rl_point, rl_mark);
|
||||
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
|
||||
}
|
||||
|
||||
text = rl_copy_text (rl_point, rl_mark);
|
||||
if (delete)
|
||||
rl_delete_text (rl_point, rl_mark);
|
||||
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
|
||||
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
@@ -530,6 +546,8 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
|
||||
|
||||
rl_begin_undo_group ();
|
||||
|
||||
_rl_set_mark_at_pos (rl_point);
|
||||
|
||||
#if defined (VI_MODE)
|
||||
/* Vi mode always inserts a space before yanking the argument, and it
|
||||
inserts it right *after* rl_point. */
|
||||
@@ -623,6 +641,7 @@ rl_paste_from_clipboard (count, key)
|
||||
}
|
||||
else
|
||||
ptr = data;
|
||||
_rl_set_mark_at_pos (rl_point);
|
||||
rl_insert_text (ptr);
|
||||
if (ptr != data)
|
||||
free (ptr);
|
||||
|
||||
+3
-11
@@ -49,8 +49,6 @@
|
||||
#include "rlprivate.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Hacking Keyboard Macros */
|
||||
@@ -61,9 +59,6 @@
|
||||
then it is a malloc ()'ed string where input is coming from. */
|
||||
char *rl_executing_macro = (char *)NULL;
|
||||
|
||||
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
|
||||
int _rl_defining_kbd_macro = 0;
|
||||
|
||||
/* The offset in the above string to the next character to be read. */
|
||||
static int executing_macro_index;
|
||||
|
||||
@@ -186,7 +181,6 @@ _rl_kill_kbd_macro ()
|
||||
rl_executing_macro = (char *) NULL;
|
||||
executing_macro_index = 0;
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
RL_UNSETSTATE(RL_STATE_MACRODEF);
|
||||
}
|
||||
|
||||
@@ -200,7 +194,7 @@ int
|
||||
rl_start_kbd_macro (ignore1, ignore2)
|
||||
int ignore1, ignore2;
|
||||
{
|
||||
if (_rl_defining_kbd_macro)
|
||||
if (RL_ISSTATE (RL_STATE_MACRODEF))
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
@@ -214,7 +208,6 @@ rl_start_kbd_macro (ignore1, ignore2)
|
||||
else
|
||||
current_macro_index = 0;
|
||||
|
||||
_rl_defining_kbd_macro = 1;
|
||||
RL_SETSTATE(RL_STATE_MACRODEF);
|
||||
return 0;
|
||||
}
|
||||
@@ -226,7 +219,7 @@ int
|
||||
rl_end_kbd_macro (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
if (_rl_defining_kbd_macro == 0)
|
||||
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
@@ -235,7 +228,6 @@ rl_end_kbd_macro (count, ignore)
|
||||
current_macro_index -= rl_key_sequence_length - 1;
|
||||
current_macro[current_macro_index] = '\0';
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
RL_UNSETSTATE(RL_STATE_MACRODEF);
|
||||
|
||||
return (rl_call_last_kbd_macro (--count, 0));
|
||||
@@ -250,7 +242,7 @@ rl_call_last_kbd_macro (count, ignore)
|
||||
if (current_macro == 0)
|
||||
_rl_abort_internal ();
|
||||
|
||||
if (_rl_defining_kbd_macro)
|
||||
if (RL_ISSTATE (RL_STATE_MACRODEF))
|
||||
{
|
||||
rl_ding (); /* no recursive macros */
|
||||
current_macro[--current_macro_index] = '\0'; /* erase this char */
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
/* mbutil.c -- readline multibyte character utility functions */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include "posixjmp.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for _POSIX_VERSION */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
#if defined (TIOCSTAT_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* TIOCSTAT_IN_SYS_IOCTL */
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
|
||||
#include "rlprivate.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* Declared here so it can be shared between the readline and history
|
||||
libraries. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
int rl_byte_oriented = 0;
|
||||
#else
|
||||
int rl_byte_oriented = 1;
|
||||
#endif
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Multibyte Character Utility Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined(HANDLE_MULTIBYTE)
|
||||
|
||||
static int
|
||||
_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
|
||||
char *string;
|
||||
int seed, count, find_non_zero;
|
||||
{
|
||||
size_t tmp = 0;
|
||||
mbstate_t ps;
|
||||
int point = 0;
|
||||
wchar_t wc;
|
||||
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
if (seed < 0)
|
||||
seed = 0;
|
||||
if (count <= 0)
|
||||
return seed;
|
||||
|
||||
point = seed + _rl_adjust_point(string, seed, &ps);
|
||||
/* if this is true, means that seed was not pointed character
|
||||
started byte. So correct the point and consume count */
|
||||
if (seed < point)
|
||||
count --;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
|
||||
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
{
|
||||
/* invalid bytes. asume a byte represents a character */
|
||||
point++;
|
||||
count--;
|
||||
/* reset states. */
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
}
|
||||
else if (tmp == (size_t)0)
|
||||
/* found '\0' char */
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* valid bytes */
|
||||
point += tmp;
|
||||
if (find_non_zero)
|
||||
{
|
||||
if (wcwidth (wc) == 0)
|
||||
continue;
|
||||
else
|
||||
count--;
|
||||
}
|
||||
else
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
if (find_non_zero)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
|
||||
while (wcwidth (wc) == 0)
|
||||
{
|
||||
point += tmp;
|
||||
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
|
||||
if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
static int
|
||||
_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
|
||||
char *string;
|
||||
int seed, find_non_zero;
|
||||
{
|
||||
mbstate_t ps;
|
||||
int prev, non_zero_prev, point, length;
|
||||
size_t tmp;
|
||||
wchar_t wc;
|
||||
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
length = strlen(string);
|
||||
|
||||
if (seed < 0)
|
||||
return 0;
|
||||
else if (length < seed)
|
||||
return length;
|
||||
|
||||
prev = non_zero_prev = point = 0;
|
||||
while (point < seed)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string + point, length - point, &ps);
|
||||
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
a single character anyway. */
|
||||
tmp = 1;
|
||||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (tmp == 0)
|
||||
break; /* Found '\0' char. Can this happen? */
|
||||
else
|
||||
{
|
||||
if (find_non_zero)
|
||||
{
|
||||
if (wcwidth (wc) != 0)
|
||||
prev = point;
|
||||
}
|
||||
else
|
||||
prev = point;
|
||||
}
|
||||
|
||||
point += tmp;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* return the number of bytes parsed from the multibyte sequence starting
|
||||
at src, if a non-L'\0' wide character was recognized. It returns 0,
|
||||
if a L'\0' wide character was recognized. It returns (size_t)(-1),
|
||||
if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
|
||||
if it couldn't parse a complete multibyte character. */
|
||||
int
|
||||
_rl_get_char_len (src, ps)
|
||||
char *src;
|
||||
mbstate_t *ps;
|
||||
{
|
||||
size_t tmp;
|
||||
|
||||
tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
|
||||
if (tmp == (size_t)(-2))
|
||||
{
|
||||
/* shorted to compose multibyte char */
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -2;
|
||||
}
|
||||
else if (tmp == (size_t)(-1))
|
||||
{
|
||||
/* invalid to compose multibyte char */
|
||||
/* initialize the conversion state */
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -1;
|
||||
}
|
||||
else if (tmp == (size_t)0)
|
||||
return 0;
|
||||
else
|
||||
return (int)tmp;
|
||||
}
|
||||
|
||||
/* compare the specified two characters. If the characters matched,
|
||||
return 1. Otherwise return 0. */
|
||||
int
|
||||
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
|
||||
char *buf1, *buf2;
|
||||
mbstate_t *ps1, *ps2;
|
||||
int pos1, pos2;
|
||||
{
|
||||
int i, w1, w2;
|
||||
|
||||
if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
|
||||
(w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
|
||||
(w1 != w2) ||
|
||||
(buf1[pos1] != buf2[pos2]))
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < w1; i++)
|
||||
if (buf1[pos1+i] != buf2[pos2+i])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* adjust pointed byte and find mbstate of the point of string.
|
||||
adjusted point will be point <= adjusted_point, and returns
|
||||
differences of the byte(adjusted_point - point).
|
||||
if point is invalied (point < 0 || more than string length),
|
||||
it returns -1 */
|
||||
int
|
||||
_rl_adjust_point(string, point, ps)
|
||||
char *string;
|
||||
int point;
|
||||
mbstate_t *ps;
|
||||
{
|
||||
size_t tmp = 0;
|
||||
int length;
|
||||
int pos = 0;
|
||||
|
||||
length = strlen(string);
|
||||
if (point < 0)
|
||||
return -1;
|
||||
if (length < point)
|
||||
return -1;
|
||||
|
||||
while (pos < point)
|
||||
{
|
||||
tmp = mbrlen (string + pos, length - pos, ps);
|
||||
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
a single character anyway. */
|
||||
pos++;
|
||||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
memset (ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else
|
||||
pos += tmp;
|
||||
}
|
||||
|
||||
return (pos - point);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_is_mbchar_matched (string, seed, end, mbchar, length)
|
||||
char *string;
|
||||
int seed, end;
|
||||
char *mbchar;
|
||||
int length;
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((end - seed) < length)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
if (string[seed + i] != mbchar[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Find next `count' characters started byte point of the specified seed.
|
||||
If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
|
||||
characters. */
|
||||
#undef _rl_find_next_mbchar
|
||||
int
|
||||
_rl_find_next_mbchar (string, seed, count, flags)
|
||||
char *string;
|
||||
int seed, count, flags;
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return _rl_find_next_mbchar_internal (string, seed, count, flags);
|
||||
#else
|
||||
return (seed + count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Find previous character started byte point of the specified seed.
|
||||
Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
|
||||
we look for non-zero-width multibyte characters. */
|
||||
#undef _rl_find_prev_mbchar
|
||||
int
|
||||
_rl_find_prev_mbchar (string, seed, flags)
|
||||
char *string;
|
||||
int seed, flags;
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return _rl_find_prev_mbchar_internal (string, seed, flags);
|
||||
#else
|
||||
return ((seed == 0) ? seed : seed - 1);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,496 @@
|
||||
/* misc.c -- miscellaneous bindable readline functions. */
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_LOCALE_H)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#include "rlprivate.h"
|
||||
#include "rlshell.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
static int rl_digit_loop PARAMS((void));
|
||||
static void _rl_history_set_point PARAMS((void));
|
||||
|
||||
/* Forward declarations used in this file */
|
||||
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
|
||||
|
||||
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
|
||||
to preserve the value of rl_point from line to line. */
|
||||
int _rl_history_preserve_point = 0;
|
||||
|
||||
/* Saved target point for when _rl_history_preserve_point is set. Special
|
||||
value of -1 means that point is at the end of the line. */
|
||||
int _rl_history_saved_point = -1;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Numeric Arguments */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Handle C-u style numeric args, as well as M--, and M-digits. */
|
||||
static int
|
||||
rl_digit_loop ()
|
||||
{
|
||||
int key, c, sawminus, sawdigits;
|
||||
|
||||
rl_save_prompt ();
|
||||
|
||||
RL_SETSTATE(RL_STATE_NUMERICARG);
|
||||
sawminus = sawdigits = 0;
|
||||
while (1)
|
||||
{
|
||||
if (rl_numeric_arg > 1000000)
|
||||
{
|
||||
sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
|
||||
rl_ding ();
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
return 1;
|
||||
}
|
||||
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
key = c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
if (c < 0)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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 (sawdigits == 0)
|
||||
{
|
||||
rl_numeric_arg *= 4;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
key = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
return (_rl_dispatch (key, _rl_keymap));
|
||||
}
|
||||
}
|
||||
|
||||
c = UNMETA (c);
|
||||
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
|
||||
sawdigits = rl_explicit_arg = 1;
|
||||
}
|
||||
else if (c == '-' && rl_explicit_arg == 0)
|
||||
{
|
||||
rl_numeric_arg = sawminus = 1;
|
||||
rl_arg_sign = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make M-- command equivalent to M--1 command. */
|
||||
if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
|
||||
rl_explicit_arg = 1;
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
return (_rl_dispatch (key, _rl_keymap));
|
||||
}
|
||||
}
|
||||
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Add the current digit to the argument in progress. */
|
||||
int
|
||||
rl_digit_argument (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
rl_execute_next (key);
|
||||
return (rl_digit_loop ());
|
||||
}
|
||||
|
||||
/* What to do when you abort reading an argument. */
|
||||
int
|
||||
rl_discard_argument ()
|
||||
{
|
||||
rl_ding ();
|
||||
rl_clear_message ();
|
||||
_rl_init_argument ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a default argument. */
|
||||
int
|
||||
_rl_init_argument ()
|
||||
{
|
||||
rl_numeric_arg = rl_arg_sign = 1;
|
||||
rl_explicit_arg = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* C-u, universal argument. Multiply the current argument by 4.
|
||||
Read a key. If the key has nothing to do with arguments, then
|
||||
dispatch on it. If the key is the abort character then abort. */
|
||||
int
|
||||
rl_universal_argument (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_numeric_arg *= 4;
|
||||
return (rl_digit_loop ());
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* History Utilities */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* We already have a history library, and that is what we use to control
|
||||
the history features of readline. This is our local interface to
|
||||
the history mechanism. */
|
||||
|
||||
/* While we are editing the history, this is the saved
|
||||
version of the original line. */
|
||||
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
|
||||
/* Set the history pointer back to the last entry in the history. */
|
||||
void
|
||||
_rl_start_using_history ()
|
||||
{
|
||||
using_history ();
|
||||
if (_rl_saved_line_for_history)
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
}
|
||||
|
||||
/* Free the contents (and containing structure) of a HIST_ENTRY. */
|
||||
void
|
||||
_rl_free_history_entry (entry)
|
||||
HIST_ENTRY *entry;
|
||||
{
|
||||
if (entry == 0)
|
||||
return;
|
||||
if (entry->line)
|
||||
free (entry->line);
|
||||
free (entry);
|
||||
}
|
||||
|
||||
/* Perhaps put back the current line if it has changed. */
|
||||
int
|
||||
rl_maybe_replace_line ()
|
||||
{
|
||||
HIST_ENTRY *temp;
|
||||
|
||||
temp = current_history ();
|
||||
/* If the current line has changed, save the changes. */
|
||||
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
|
||||
{
|
||||
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
|
||||
free (temp->line);
|
||||
free (temp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restore the _rl_saved_line_for_history if there is one. */
|
||||
int
|
||||
rl_maybe_unsave_line ()
|
||||
{
|
||||
if (_rl_saved_line_for_history)
|
||||
{
|
||||
rl_replace_line (_rl_saved_line_for_history->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
rl_point = rl_end; /* rl_replace_line sets rl_end */
|
||||
}
|
||||
else
|
||||
rl_ding ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save the current line in _rl_saved_line_for_history. */
|
||||
int
|
||||
rl_maybe_save_line ()
|
||||
{
|
||||
if (_rl_saved_line_for_history == 0)
|
||||
{
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
|
||||
_rl_saved_line_for_history->data = (char *)rl_undo_list;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_free_saved_history_line ()
|
||||
{
|
||||
if (_rl_saved_line_for_history)
|
||||
{
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_rl_history_set_point ()
|
||||
{
|
||||
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
|
||||
? _rl_history_saved_point
|
||||
: rl_end;
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
rl_point = 0;
|
||||
#endif /* VI_MODE */
|
||||
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = (rl_point == rl_end ? 0 : rl_end);
|
||||
}
|
||||
|
||||
void
|
||||
rl_replace_from_history (entry, flags)
|
||||
HIST_ENTRY *entry;
|
||||
int flags; /* currently unused */
|
||||
{
|
||||
rl_replace_line (entry->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)entry->data;
|
||||
rl_point = rl_end;
|
||||
rl_mark = 0;
|
||||
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
{
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* History Commands */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Meta-< goes to the start of the history. */
|
||||
int
|
||||
rl_beginning_of_history (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (rl_get_previous_history (1 + where_history (), key));
|
||||
}
|
||||
|
||||
/* Meta-> goes to the end of the history. (The current line). */
|
||||
int
|
||||
rl_end_of_history (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_maybe_replace_line ();
|
||||
using_history ();
|
||||
rl_maybe_unsave_line ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move down to the next history line. */
|
||||
int
|
||||
rl_get_next_history (count, key)
|
||||
int count, key;
|
||||
{
|
||||
HIST_ENTRY *temp;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_previous_history (-count, key));
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
/* either not saved by rl_newline or at end of line, so set appropriately. */
|
||||
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
|
||||
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
|
||||
|
||||
temp = (HIST_ENTRY *)NULL;
|
||||
while (count)
|
||||
{
|
||||
temp = next_history ();
|
||||
if (!temp)
|
||||
break;
|
||||
--count;
|
||||
}
|
||||
|
||||
if (temp == 0)
|
||||
rl_maybe_unsave_line ();
|
||||
else
|
||||
{
|
||||
rl_replace_from_history (temp, 0);
|
||||
_rl_history_set_point ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the previous item out of our interactive history, making it the current
|
||||
line. If there is no previous history, just ding. */
|
||||
int
|
||||
rl_get_previous_history (count, key)
|
||||
int count, key;
|
||||
{
|
||||
HIST_ENTRY *old_temp, *temp;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_get_next_history (-count, key));
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
/* either not saved by rl_newline or at end of line, so set appropriately. */
|
||||
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
|
||||
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
|
||||
|
||||
/* If we don't have a line saved, then save this one. */
|
||||
rl_maybe_save_line ();
|
||||
|
||||
/* If the current line has changed, save the changes. */
|
||||
rl_maybe_replace_line ();
|
||||
|
||||
temp = old_temp = (HIST_ENTRY *)NULL;
|
||||
while (count)
|
||||
{
|
||||
temp = previous_history ();
|
||||
if (temp == 0)
|
||||
break;
|
||||
|
||||
old_temp = temp;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* If there was a large argument, and we moved back to the start of the
|
||||
history, that is not an error. So use the last value found. */
|
||||
if (!temp && old_temp)
|
||||
temp = old_temp;
|
||||
|
||||
if (temp == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
{
|
||||
rl_replace_from_history (temp, 0);
|
||||
_rl_history_set_point ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Editing Modes */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* How to toggle back and forth between editing modes. */
|
||||
int
|
||||
rl_vi_editing_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
#if defined (VI_MODE)
|
||||
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
|
||||
rl_editing_mode = vi_mode;
|
||||
rl_vi_insertion_mode (1, key);
|
||||
#endif /* VI_MODE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_emacs_editing_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_editing_mode = emacs_mode;
|
||||
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function for the rest of the library to use to set insert/overwrite mode. */
|
||||
void
|
||||
_rl_set_insert_mode (im, force)
|
||||
int im, force;
|
||||
{
|
||||
#ifdef CURSOR_MODE
|
||||
_rl_set_cursor (im, force);
|
||||
#endif
|
||||
|
||||
rl_insert_mode = im;
|
||||
}
|
||||
|
||||
/* Toggle overwrite mode. A positive explicit argument selects overwrite
|
||||
mode. A negative or zero explicit argument selects insert mode. */
|
||||
int
|
||||
rl_overwrite_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_explicit_arg == 0)
|
||||
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
|
||||
else if (count > 0)
|
||||
_rl_set_insert_mode (RL_IM_OVERWRITE, 0);
|
||||
else
|
||||
_rl_set_insert_mode (RL_IM_INSERT, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -30,6 +30,10 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (FD_SET) && !defined (HAVE_SELECT)
|
||||
# define HAVE_SELECT
|
||||
#endif
|
||||
@@ -103,7 +107,7 @@ rl_insert_close (count, invoking_key)
|
||||
int count, invoking_key;
|
||||
{
|
||||
if (rl_explicit_arg || !rl_blink_matching_paren)
|
||||
rl_insert (count, invoking_key);
|
||||
_rl_insert_char (count, invoking_key);
|
||||
else
|
||||
{
|
||||
#if defined (HAVE_SELECT)
|
||||
@@ -111,7 +115,7 @@ rl_insert_close (count, invoking_key)
|
||||
struct timeval timer;
|
||||
fd_set readfds;
|
||||
|
||||
rl_insert (1, invoking_key);
|
||||
_rl_insert_char (1, invoking_key);
|
||||
(*rl_redisplay_function) ();
|
||||
match_point =
|
||||
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
|
||||
@@ -131,7 +135,7 @@ rl_insert_close (count, invoking_key)
|
||||
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
|
||||
rl_point = orig_point;
|
||||
#else /* !HAVE_SELECT */
|
||||
rl_insert (count, invoking_key);
|
||||
_rl_insert_char (count, invoking_key);
|
||||
#endif /* !HAVE_SELECT */
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -46,4 +46,12 @@
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
#else
|
||||
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
#endif /* _POSIX_SOURCE */
|
||||
|
||||
#endif /* !_POSIXDIR_H_ */
|
||||
|
||||
+175
-1414
File diff suppressed because it is too large
Load Diff
+70
-3
@@ -29,18 +29,20 @@ extern "C" {
|
||||
|
||||
#if defined (READLINE_LIBRARY)
|
||||
# include "rlstdc.h"
|
||||
# include "rltypedefs.h"
|
||||
# include "keymaps.h"
|
||||
# include "tilde.h"
|
||||
#else
|
||||
# include <readline/rlstdc.h>
|
||||
# include <readline/rltypedefs.h>
|
||||
# include <readline/keymaps.h>
|
||||
# include <readline/tilde.h>
|
||||
#endif
|
||||
|
||||
/* Hex-encoded Readline version number. */
|
||||
#define RL_READLINE_VERSION 0x0402 /* Readline 4.2 */
|
||||
#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
|
||||
#define RL_VERSION_MAJOR 4
|
||||
#define RL_VERSION_MINOR 2
|
||||
#define RL_VERSION_MINOR 3
|
||||
|
||||
/* Readline data structures. */
|
||||
|
||||
@@ -82,7 +84,11 @@ extern int rl_digit_argument PARAMS((int, int));
|
||||
extern int rl_universal_argument PARAMS((int, int));
|
||||
|
||||
/* Bindable commands for moving the cursor. */
|
||||
extern int rl_forward_byte PARAMS((int, int));
|
||||
extern int rl_forward_char PARAMS((int, int));
|
||||
extern int rl_forward PARAMS((int, int));
|
||||
extern int rl_backward_byte PARAMS((int, int));
|
||||
extern int rl_backward_char PARAMS((int, int));
|
||||
extern int rl_backward PARAMS((int, int));
|
||||
extern int rl_beg_of_line PARAMS((int, int));
|
||||
extern int rl_end_of_line PARAMS((int, int));
|
||||
@@ -132,6 +138,9 @@ extern int rl_exchange_point_and_mark PARAMS((int, int));
|
||||
extern int rl_vi_editing_mode PARAMS((int, int));
|
||||
extern int rl_emacs_editing_mode PARAMS((int, int));
|
||||
|
||||
/* Bindable commands to change the insert mode (insert or overwrite) */
|
||||
extern int rl_overwrite_mode PARAMS((int, int));
|
||||
|
||||
/* Bindable commands for managing key bindings. */
|
||||
extern int rl_re_read_init_file PARAMS((int, int));
|
||||
extern int rl_dump_functions PARAMS((int, int));
|
||||
@@ -365,6 +374,7 @@ extern void rl_save_prompt PARAMS((void));
|
||||
extern void rl_restore_prompt PARAMS((void));
|
||||
|
||||
/* Modifying text. */
|
||||
extern void rl_replace_line PARAMS((const char *, int));
|
||||
extern int rl_insert_text PARAMS((const char *));
|
||||
extern int rl_delete_text PARAMS((int, int));
|
||||
extern int rl_kill_text PARAMS((int, int));
|
||||
@@ -417,6 +427,8 @@ extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)
|
||||
extern char *rl_username_completion_function PARAMS((const char *, int));
|
||||
extern char *rl_filename_completion_function PARAMS((const char *, int));
|
||||
|
||||
extern int rl_completion_mode PARAMS((rl_command_func_t *));
|
||||
|
||||
#if 0
|
||||
/* Backwards compatibility (compat.c). These will go away sometime. */
|
||||
extern void free_undo_list PARAMS((void));
|
||||
@@ -453,6 +465,10 @@ extern int rl_readline_state;
|
||||
0 means vi mode. */
|
||||
extern int rl_editing_mode;
|
||||
|
||||
/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
|
||||
overwrite mode. Reset to insert mode on each input line. */
|
||||
extern int rl_insert_mode;
|
||||
|
||||
/* The name of the calling program. You should initialize this to
|
||||
whatever was in argv[0]. It is used when parsing conditionals. */
|
||||
extern const char *rl_readline_name;
|
||||
@@ -675,18 +691,33 @@ extern int rl_completion_type;
|
||||
default is a space. Nothing is added if this is '\0'. */
|
||||
extern int rl_completion_append_character;
|
||||
|
||||
/* If set to non-zero by an application completion function,
|
||||
rl_completion_append_character will not be appended. */
|
||||
extern int rl_completion_suppress_append;
|
||||
|
||||
/* Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she
|
||||
is sure she wants to see them all. The default value is 100. */
|
||||
extern int rl_completion_query_items;
|
||||
|
||||
/* If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
mark-directories variable (which is user-settable). This exists so
|
||||
that application completion functions can override the user's preference
|
||||
(set via the mark-symlinked-directories variable) if appropriate.
|
||||
It's set to the value of _rl_complete_mark_symlink_dirs in
|
||||
rl_complete_internal before any application-specific completion
|
||||
function is called, so without that function doing anything, the user's
|
||||
preferences are honored. */
|
||||
extern int rl_completion_mark_symlink_dirs;
|
||||
|
||||
/* If non-zero, then disallow duplicates in the matches. */
|
||||
extern int rl_ignore_completion_duplicates;
|
||||
|
||||
/* If this is non-zero, completion is (temporarily) inhibited, and the
|
||||
completion character will be inserted as any other. */
|
||||
extern int rl_inhibit_completion;
|
||||
|
||||
|
||||
/* Definitions available for use by readline clients. */
|
||||
#define RL_PROMPT_START_IGNORE '\001'
|
||||
#define RL_PROMPT_END_IGNORE '\002'
|
||||
@@ -725,6 +756,42 @@ extern int rl_inhibit_completion;
|
||||
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
|
||||
#define RL_ISSTATE(x) (rl_readline_state & (x))
|
||||
|
||||
struct readline_state {
|
||||
/* line state */
|
||||
int point;
|
||||
int end;
|
||||
int mark;
|
||||
char *buffer;
|
||||
int buflen;
|
||||
UNDO_LIST *ul;
|
||||
char *prompt;
|
||||
|
||||
/* global state */
|
||||
int rlstate;
|
||||
int done;
|
||||
Keymap kmap;
|
||||
|
||||
/* input state */
|
||||
rl_command_func_t *lastfunc;
|
||||
int insmode;
|
||||
int edmode;
|
||||
int kseqlen;
|
||||
FILE *inf;
|
||||
FILE *outf;
|
||||
int pendingin;
|
||||
char *macro;
|
||||
|
||||
/* signal state */
|
||||
int catchsigs;
|
||||
int catchsigwinch;
|
||||
|
||||
/* reserved for future expansion, so the struct size doesn't change */
|
||||
char reserved[64];
|
||||
};
|
||||
|
||||
extern int rl_save_state PARAMS((struct readline_state *));
|
||||
extern int rl_restore_state PARAMS((struct readline_state *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -54,4 +54,7 @@
|
||||
X `callback' style. */
|
||||
#define READLINE_CALLBACKS
|
||||
|
||||
/* Define this if you want the cursor to indicate insert or overwrite mode. */
|
||||
/* #define CURSOR_MODE */
|
||||
|
||||
#endif /* _RLCONF_H_ */
|
||||
|
||||
+16
-4
@@ -74,7 +74,7 @@ extern char *strchr (), *strrchr ();
|
||||
#define _rl_strnicmp strncasecmp
|
||||
#else
|
||||
extern int _rl_stricmp PARAMS((char *, char *));
|
||||
extern int _rl_strnicmp PARAMS((char *, char *));
|
||||
extern int _rl_strnicmp PARAMS((char *, char *, int));
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRPBRK)
|
||||
@@ -89,6 +89,13 @@ extern char *_rl_strpbrk PARAMS((const char *, const char *));
|
||||
# define emacs_mode 1
|
||||
#endif
|
||||
|
||||
#if !defined (RL_IM_INSERT)
|
||||
# define RL_IM_INSERT 1
|
||||
# define RL_IM_OVERWRITE 0
|
||||
#
|
||||
# define RL_IM_DEFAULT RL_IM_INSERT
|
||||
#endif
|
||||
|
||||
/* If you cast map[key].function to type (Keymap) on a Cray,
|
||||
the compiler takes the value of map[key].function and
|
||||
divides it by 4 to convert between pointer types (pointers
|
||||
@@ -121,9 +128,10 @@ extern char *_rl_strpbrk PARAMS((const char *, const char *));
|
||||
/* Possible values for the found_quote flags word used by the completion
|
||||
functions. It says what kind of (shell-like) quoting we found anywhere
|
||||
in the line. */
|
||||
#define RL_QF_SINGLE_QUOTE 0x1
|
||||
#define RL_QF_DOUBLE_QUOTE 0x2
|
||||
#define RL_QF_BACKSLASH 0x4
|
||||
#define RL_QF_SINGLE_QUOTE 0x01
|
||||
#define RL_QF_DOUBLE_QUOTE 0x02
|
||||
#define RL_QF_BACKSLASH 0x04
|
||||
#define RL_QF_OTHER_QUOTE 0x08
|
||||
|
||||
/* Default readline line buffer length. */
|
||||
#define DEFAULT_BUFFER_SIZE 256
|
||||
@@ -138,6 +146,10 @@ extern char *_rl_strpbrk PARAMS((const char *, const char *));
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
#if !defined (SWAP)
|
||||
# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
#endif
|
||||
|
||||
/* CONFIGURATION SECTION */
|
||||
#include "rlconf.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/* rlmbutil.h -- utility functions for multibyte characters. */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (_RL_MBUTIL_H_)
|
||||
#define _RL_MBUTIL_H_
|
||||
|
||||
#include "rlstdc.h"
|
||||
|
||||
/************************************************/
|
||||
/* check multibyte capability for I18N code */
|
||||
/************************************************/
|
||||
|
||||
/* For platforms which support the ISO C amendement 1 functionality we
|
||||
support user defined character classes. */
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
|
||||
# define HANDLE_MULTIBYTE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
|
||||
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
|
||||
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
|
||||
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
|
||||
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
|
||||
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
|
||||
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
|
||||
# define mbstate_t int
|
||||
#endif
|
||||
|
||||
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
|
||||
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
# include <limits.h>
|
||||
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
|
||||
# undef MB_LEN_MAX
|
||||
# endif
|
||||
# if !defined (MB_LEN_MAX)
|
||||
# define MB_LEN_MAX 16
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/************************************************/
|
||||
/* end of multibyte capability checks for I18N */
|
||||
/************************************************/
|
||||
|
||||
/*
|
||||
* Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
|
||||
*
|
||||
* MB_FIND_ANY find any multibyte character
|
||||
* MB_FIND_NONZERO find a non-zero-width multibyte character
|
||||
*/
|
||||
|
||||
#define MB_FIND_ANY 0x00
|
||||
#define MB_FIND_NONZERO 0x01
|
||||
|
||||
extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
|
||||
extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
|
||||
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
|
||||
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
|
||||
extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
|
||||
extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
|
||||
|
||||
extern int _rl_read_mbchar PARAMS((char *, int));
|
||||
extern int _rl_read_mbstring PARAMS((int, char *, int));
|
||||
|
||||
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
|
||||
|
||||
#else /* !HANDLE_MULTIBYTE */
|
||||
|
||||
#undef MB_LEN_MAX
|
||||
#undef MB_CUR_MAX
|
||||
|
||||
#define MB_LEN_MAX 1
|
||||
#define MB_CUR_MAX 1
|
||||
|
||||
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
|
||||
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
|
||||
|
||||
#endif /* !HANDLE_MULTIBYTE */
|
||||
|
||||
extern int rl_byte_oriented;
|
||||
|
||||
#endif /* _RL_MBUTIL_H_ */
|
||||
+35
-18
@@ -52,6 +52,7 @@ extern int rl_arg_sign;
|
||||
extern int rl_visible_prompt_length;
|
||||
extern int readline_echoing_p;
|
||||
extern int rl_key_sequence_length;
|
||||
extern int rl_byte_oriented;
|
||||
|
||||
/* display.c */
|
||||
extern int rl_display_fixed;
|
||||
@@ -65,18 +66,9 @@ extern int rl_blink_matching_paren;
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
/* bind.c */
|
||||
extern char *rl_untranslate_keyseq PARAMS((int));
|
||||
|
||||
/* kill.c */
|
||||
extern int rl_set_retained_kills PARAMS((int));
|
||||
|
||||
/* readline.c */
|
||||
extern int rl_discard_argument PARAMS((void));
|
||||
|
||||
/* rltty.c */
|
||||
extern int rl_stop_output PARAMS((int, int));
|
||||
|
||||
/* terminal.c */
|
||||
extern void _rl_set_screen_size PARAMS((int, int));
|
||||
|
||||
@@ -113,6 +105,10 @@ extern int readline_internal_char PARAMS((void));
|
||||
/* bind.c */
|
||||
extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
|
||||
|
||||
/* complete.c */
|
||||
extern char _rl_find_completion_word PARAMS((int *, int *));
|
||||
extern void _rl_free_match_list PARAMS((char **));
|
||||
|
||||
/* display.c */
|
||||
extern char *_rl_strip_prompt PARAMS((char *));
|
||||
extern void _rl_move_cursor_relative PARAMS((int, const char *));
|
||||
@@ -132,7 +128,9 @@ extern int _rl_current_display_line PARAMS((void));
|
||||
/* input.c */
|
||||
extern int _rl_any_typein PARAMS((void));
|
||||
extern int _rl_input_available PARAMS((void));
|
||||
extern int _rl_input_queued PARAMS((int));
|
||||
extern void _rl_insert_typein PARAMS((int));
|
||||
extern int _rl_unget_char PARAMS((int));
|
||||
|
||||
/* macro.c */
|
||||
extern void _rl_with_macro_input PARAMS((char *));
|
||||
@@ -142,6 +140,12 @@ extern void _rl_pop_executing_macro PARAMS((void));
|
||||
extern void _rl_add_macro_char PARAMS((int));
|
||||
extern void _rl_kill_kbd_macro PARAMS((void));
|
||||
|
||||
/* misc.c */
|
||||
extern int _rl_init_argument PARAMS((void));
|
||||
extern void _rl_start_using_history PARAMS((void));
|
||||
extern int _rl_free_saved_history_line PARAMS((void));
|
||||
extern void _rl_set_insert_mode PARAMS((int, int));
|
||||
|
||||
/* nls.c */
|
||||
extern int _rl_init_eightbit PARAMS((void));
|
||||
|
||||
@@ -152,12 +156,7 @@ extern void _rl_enable_paren_matching PARAMS((int));
|
||||
extern void _rl_init_line_state PARAMS((void));
|
||||
extern void _rl_set_the_line PARAMS((void));
|
||||
extern int _rl_dispatch PARAMS((int, Keymap));
|
||||
extern int _rl_init_argument PARAMS((void));
|
||||
extern void _rl_fix_point PARAMS((int));
|
||||
extern void _rl_replace_text PARAMS((const char *, int, int));
|
||||
extern int _rl_char_search_internal PARAMS((int, int, int));
|
||||
extern int _rl_set_mark_at_pos PARAMS((int));
|
||||
extern int _rl_free_saved_history_line PARAMS((void));
|
||||
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
|
||||
|
||||
/* rltty.c */
|
||||
extern int _rl_disable_tty_signals PARAMS((void));
|
||||
@@ -175,9 +174,23 @@ extern void _rl_output_some_chars PARAMS((const char *, int));
|
||||
extern int _rl_backspace PARAMS((int));
|
||||
extern void _rl_enable_meta_key PARAMS((void));
|
||||
extern void _rl_control_keypad PARAMS((int));
|
||||
extern void _rl_set_cursor PARAMS((int, int));
|
||||
|
||||
/* text.c */
|
||||
extern void _rl_fix_point PARAMS((int));
|
||||
extern int _rl_replace_text PARAMS((const char *, int, int));
|
||||
extern int _rl_insert_char PARAMS((int, int));
|
||||
extern int _rl_overwrite_char PARAMS((int, int));
|
||||
extern int _rl_overwrite_rubout PARAMS((int, int));
|
||||
extern int _rl_rubout_char PARAMS((int, int));
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
extern int _rl_char_search_internal PARAMS((int, int, char *, int));
|
||||
#else
|
||||
extern int _rl_char_search_internal PARAMS((int, int, int));
|
||||
#endif
|
||||
extern int _rl_set_mark_at_pos PARAMS((int));
|
||||
|
||||
/* util.c */
|
||||
extern int rl_alphabetic PARAMS((int));
|
||||
extern int _rl_abort_internal PARAMS((void));
|
||||
extern char *_rl_strindex PARAMS((const char *, const char *));
|
||||
extern int _rl_qsort_string_compare PARAMS((char **, char **));
|
||||
@@ -207,9 +220,11 @@ extern const char *_rl_possible_meta_prefixes[];
|
||||
/* complete.c */
|
||||
extern int _rl_complete_show_all;
|
||||
extern int _rl_complete_mark_directories;
|
||||
extern int _rl_complete_mark_symlink_dirs;
|
||||
extern int _rl_print_completions_horizontally;
|
||||
extern int _rl_completion_case_fold;
|
||||
extern int _rl_match_hidden_files;
|
||||
extern int _rl_page_completions;
|
||||
|
||||
/* display.c */
|
||||
extern int _rl_vis_botlin;
|
||||
@@ -221,9 +236,12 @@ extern char *rl_display_prompt;
|
||||
extern char *_rl_isearch_terminators;
|
||||
|
||||
/* macro.c */
|
||||
extern int _rl_defining_kbd_macro;
|
||||
extern char *_rl_executing_macro;
|
||||
|
||||
/* misc.c */
|
||||
extern int _rl_history_preserve_point;
|
||||
extern int _rl_history_saved_point;
|
||||
|
||||
/* readline.c */
|
||||
extern int _rl_horizontal_scroll_mode;
|
||||
extern int _rl_mark_modified_lines;
|
||||
@@ -231,7 +249,6 @@ extern int _rl_bell_preference;
|
||||
extern int _rl_meta_flag;
|
||||
extern int _rl_convert_meta_chars_to_ascii;
|
||||
extern int _rl_output_meta_chars;
|
||||
extern int _rl_history_preserve_point;
|
||||
extern char *_rl_comment_begin;
|
||||
extern unsigned char _rl_parsing_conditionalized_out;
|
||||
extern Keymap _rl_keymap;
|
||||
|
||||
@@ -647,7 +647,6 @@ rl_prep_terminal (meta_flag)
|
||||
if (get_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
release_sigint ();
|
||||
fprintf(stderr, "readline: warning: rl_prep_terminal: cannot get terminal settings");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+30
-11
@@ -40,6 +40,8 @@
|
||||
#endif
|
||||
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
@@ -80,15 +82,8 @@ static void
|
||||
make_history_line_current (entry)
|
||||
HIST_ENTRY *entry;
|
||||
{
|
||||
int line_len;
|
||||
|
||||
line_len = strlen (entry->line);
|
||||
if (line_len >= rl_line_buffer_len)
|
||||
rl_extend_line_buffer (line_len);
|
||||
strcpy (rl_line_buffer, entry->line);
|
||||
|
||||
rl_replace_line (entry->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)entry->data;
|
||||
rl_end = line_len;
|
||||
|
||||
if (_rl_saved_line_for_history)
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
@@ -169,6 +164,8 @@ noninc_dosearch (string, dir)
|
||||
make_history_line_current (entry);
|
||||
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
|
||||
rl_clear_message ();
|
||||
}
|
||||
|
||||
@@ -182,11 +179,15 @@ noninc_search (dir, pchar)
|
||||
int dir;
|
||||
int pchar;
|
||||
{
|
||||
int saved_point, c;
|
||||
int saved_point, saved_mark, c;
|
||||
char *p;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
char mb[MB_LEN_MAX];
|
||||
#endif
|
||||
|
||||
rl_maybe_save_line ();
|
||||
saved_point = rl_point;
|
||||
saved_mark = rl_mark;
|
||||
|
||||
/* Use the line buffer to read the search string. */
|
||||
rl_line_buffer[0] = 0;
|
||||
@@ -206,6 +207,11 @@ noninc_search (dir, pchar)
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
|
||||
#endif
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
@@ -218,9 +224,10 @@ noninc_search (dir, pchar)
|
||||
rl_maybe_unsave_line ();
|
||||
rl_clear_message ();
|
||||
rl_point = saved_point;
|
||||
rl_mark = saved_mark;
|
||||
SEARCH_RETURN;
|
||||
}
|
||||
rl_rubout (1, c);
|
||||
_rl_rubout_char (1, c);
|
||||
break;
|
||||
|
||||
case CTRL('W'):
|
||||
@@ -242,17 +249,25 @@ noninc_search (dir, pchar)
|
||||
rl_maybe_unsave_line ();
|
||||
rl_clear_message ();
|
||||
rl_point = saved_point;
|
||||
rl_mark = saved_mark;
|
||||
rl_ding ();
|
||||
SEARCH_RETURN;
|
||||
|
||||
default:
|
||||
rl_insert (1, c);
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
rl_insert_text (mb);
|
||||
else
|
||||
#endif
|
||||
_rl_insert_char (1, c);
|
||||
break;
|
||||
}
|
||||
(*rl_redisplay_function) ();
|
||||
}
|
||||
|
||||
dosearch:
|
||||
rl_mark = saved_mark;
|
||||
|
||||
/* If rl_point == 0, we want to re-use the previous search string and
|
||||
start from the saved history position. If there's no previous search
|
||||
string, punt. */
|
||||
@@ -373,9 +388,11 @@ rl_history_search_internal (count, dir)
|
||||
{
|
||||
rl_point = rl_end = rl_history_search_len;
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
rl_mark = 0;
|
||||
}
|
||||
#else
|
||||
rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
|
||||
rl_mark = rl_end;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -384,6 +401,8 @@ rl_history_search_internal (count, dir)
|
||||
make_history_line_current (temp);
|
||||
|
||||
rl_point = rl_history_search_len;
|
||||
rl_mark = rl_end;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
|
||||
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
|
||||
|
||||
/* Exported variables for use by applications. */
|
||||
|
||||
@@ -232,7 +233,7 @@ rl_set_sighandler (sig, handler, ohandler)
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = handler;
|
||||
act.sa_flags = 0;
|
||||
act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigemptyset (&ohandler->sa_mask);
|
||||
sigaction (sig, &act, &old_handler);
|
||||
|
||||
+72
-22
@@ -66,6 +66,9 @@
|
||||
#include "rlshell.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
|
||||
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Terminal and Termcap */
|
||||
@@ -140,6 +143,16 @@ static char *_rl_term_ke;
|
||||
/* The key sequences sent by the Home and End keys, if any. */
|
||||
static char *_rl_term_kh;
|
||||
static char *_rl_term_kH;
|
||||
static char *_rl_term_at7; /* @7 */
|
||||
|
||||
/* Insert key */
|
||||
static char *_rl_term_kI;
|
||||
|
||||
/* Cursor control */
|
||||
static char *_rl_term_vs; /* very visible */
|
||||
static char *_rl_term_ve; /* normal */
|
||||
|
||||
static void bind_termcap_arrow_keys PARAMS((Keymap));
|
||||
|
||||
/* Variables that hold the screen dimensions, used by the display code. */
|
||||
int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
|
||||
@@ -274,7 +287,10 @@ rl_resize_terminal ()
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_get_screen_size (fileno (rl_instream), 1);
|
||||
_rl_redisplay_after_sigwinch ();
|
||||
if (CUSTOM_REDISPLAY_FUNC ())
|
||||
rl_forced_update_display ();
|
||||
else
|
||||
_rl_redisplay_after_sigwinch ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +303,7 @@ struct _tc_string {
|
||||
search algorithm to something smarter. */
|
||||
static struct _tc_string tc_strings[] =
|
||||
{
|
||||
{ "@7", &_rl_term_at7 },
|
||||
{ "DC", &_rl_term_DC },
|
||||
{ "IC", &_rl_term_IC },
|
||||
{ "ce", &_rl_term_clreol },
|
||||
@@ -296,14 +313,15 @@ static struct _tc_string tc_strings[] =
|
||||
{ "ei", &_rl_term_ei },
|
||||
{ "ic", &_rl_term_ic },
|
||||
{ "im", &_rl_term_im },
|
||||
{ "kH", &_rl_term_kH }, /* home down ?? */
|
||||
{ "kI", &_rl_term_kI }, /* insert */
|
||||
{ "kd", &_rl_term_kd },
|
||||
{ "ke", &_rl_term_ke }, /* end keypad mode */
|
||||
{ "kh", &_rl_term_kh }, /* home */
|
||||
{ "kH", &_rl_term_kH }, /* end */
|
||||
{ "kl", &_rl_term_kl },
|
||||
{ "kr", &_rl_term_kr },
|
||||
{ "ks", &_rl_term_ks }, /* start keypad mode */
|
||||
{ "ku", &_rl_term_ku },
|
||||
{ "ks", &_rl_term_ks },
|
||||
{ "ke", &_rl_term_ke },
|
||||
{ "le", &_rl_term_backspace },
|
||||
{ "mm", &_rl_term_mm },
|
||||
{ "mo", &_rl_term_mo },
|
||||
@@ -313,6 +331,8 @@ static struct _tc_string tc_strings[] =
|
||||
{ "pc", &_rl_term_pc },
|
||||
{ "up", &_rl_term_up },
|
||||
{ "vb", &_rl_visible_bell },
|
||||
{ "vs", &_rl_term_vs },
|
||||
{ "ve", &_rl_term_ve },
|
||||
};
|
||||
|
||||
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
|
||||
@@ -336,9 +356,6 @@ get_term_capabilities (bp)
|
||||
tcap_initialized = 1;
|
||||
}
|
||||
|
||||
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
|
||||
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
|
||||
|
||||
int
|
||||
_rl_init_terminal_io (terminal_name)
|
||||
const char *terminal_name;
|
||||
@@ -346,7 +363,6 @@ _rl_init_terminal_io (terminal_name)
|
||||
const char *term;
|
||||
char *buffer;
|
||||
int tty, tgetent_ret;
|
||||
Keymap xkeymap;
|
||||
|
||||
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
|
||||
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
|
||||
@@ -404,7 +420,10 @@ _rl_init_terminal_io (terminal_name)
|
||||
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
|
||||
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
|
||||
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
|
||||
_rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
|
||||
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
|
||||
_rl_term_mm = _rl_term_mo = (char *)NULL;
|
||||
_rl_term_ve = _rl_term_vs = (char *)NULL;
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
term_forward_char = (char *)NULL;
|
||||
#endif
|
||||
@@ -449,31 +468,36 @@ _rl_init_terminal_io (terminal_name)
|
||||
|
||||
/* Attempt to find and bind the arrow keys. Do not override already
|
||||
bound keys in an overzealous attempt, however. */
|
||||
xkeymap = _rl_keymap;
|
||||
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
|
||||
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
|
||||
_rl_bind_if_unbound (_rl_term_kr, rl_forward);
|
||||
_rl_bind_if_unbound (_rl_term_kl, rl_backward);
|
||||
|
||||
_rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
|
||||
_rl_bind_if_unbound (_rl_term_kH, rl_end_of_line); /* End */
|
||||
bind_termcap_arrow_keys (emacs_standard_keymap);
|
||||
|
||||
#if defined (VI_MODE)
|
||||
_rl_keymap = vi_movement_keymap;
|
||||
bind_termcap_arrow_keys (vi_movement_keymap);
|
||||
bind_termcap_arrow_keys (vi_insertion_keymap);
|
||||
#endif /* VI_MODE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bind the arrow key sequences from the termcap description in MAP. */
|
||||
static void
|
||||
bind_termcap_arrow_keys (map)
|
||||
Keymap map;
|
||||
{
|
||||
Keymap xkeymap;
|
||||
|
||||
xkeymap = _rl_keymap;
|
||||
_rl_keymap = map;
|
||||
|
||||
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
|
||||
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
|
||||
_rl_bind_if_unbound (_rl_term_kr, rl_forward);
|
||||
_rl_bind_if_unbound (_rl_term_kl, rl_backward);
|
||||
|
||||
_rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
|
||||
_rl_bind_if_unbound (_rl_term_kH, rl_end_of_line); /* End */
|
||||
#endif /* VI_MODE */
|
||||
_rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -610,3 +634,29 @@ _rl_control_keypad (on)
|
||||
tputs (_rl_term_ke, 1, _rl_output_character_function);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Controlling the Cursor */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Set the cursor appropriately depending on IM, which is one of the
|
||||
insert modes (insert or overwrite). Insert mode gets the normal
|
||||
cursor. Overwrite mode gets a very visible cursor. Only does
|
||||
anything if we have both capabilities. */
|
||||
void
|
||||
_rl_set_cursor (im, force)
|
||||
int im, force;
|
||||
{
|
||||
if (_rl_term_ve && _rl_term_vs)
|
||||
{
|
||||
if (force || im != rl_insert_mode)
|
||||
{
|
||||
if (im == RL_IM_OVERWRITE)
|
||||
tputs (_rl_term_vs, 1, _rl_output_character_function);
|
||||
else
|
||||
tputs (_rl_term_ve, 1, _rl_output_character_function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1540
File diff suppressed because it is too large
Load Diff
@@ -59,9 +59,6 @@ extern struct passwd *getpwnam PARAMS((const char *));
|
||||
#endif /* !HAVE_GETPW_DECLS */
|
||||
|
||||
#if !defined (savestring)
|
||||
# ifndef strcpy
|
||||
extern char *strcpy ();
|
||||
# endif
|
||||
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
|
||||
#endif /* !savestring */
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
#if !defined (_TILDE_H_)
|
||||
# define _TILDE_H_
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
#include "rlprivate.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
|
||||
the undo list. */
|
||||
int _rl_doing_an_undo = 0;
|
||||
|
||||
+15
-3
@@ -55,8 +55,6 @@
|
||||
#include "rlprivate.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Utility Functions */
|
||||
@@ -89,7 +87,7 @@ _rl_abort_internal ()
|
||||
_rl_init_argument ();
|
||||
rl_clear_pending_input ();
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
RL_UNSETSTATE (RL_STATE_MACRODEF);
|
||||
while (rl_executing_macro)
|
||||
_rl_pop_executing_macro ();
|
||||
|
||||
@@ -233,6 +231,12 @@ _rl_strpbrk (string1, string2)
|
||||
const char *string1, *string2;
|
||||
{
|
||||
register const char *scan;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps;
|
||||
register int i, v;
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
|
||||
for (; *string1; string1++)
|
||||
{
|
||||
@@ -241,6 +245,14 @@ _rl_strpbrk (string1, string2)
|
||||
if (*string1 == *scan)
|
||||
return ((char *)string1);
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
v = _rl_get_char_len (string1, &ps);
|
||||
if (v > 1)
|
||||
string += v - 1; /* -1 to account for auto-increment in loop */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, rl_emacs_editing_mode }, /* Control-e */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
|
||||
{ ISFUNC, rl_abort }, /* Control-g */
|
||||
{ ISFUNC, rl_backward }, /* Control-h */
|
||||
{ ISFUNC, rl_backward_char }, /* Control-h */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
|
||||
{ ISFUNC, rl_newline }, /* Control-j */
|
||||
{ ISFUNC, rl_kill_line }, /* Control-k */
|
||||
@@ -68,7 +68,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, rl_forward }, /* SPACE */
|
||||
{ ISFUNC, rl_forward_char }, /* SPACE */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* " */
|
||||
{ ISFUNC, rl_insert_comment }, /* # */
|
||||
@@ -150,11 +150,11 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, rl_vi_end_word }, /* e */
|
||||
{ ISFUNC, rl_vi_char_search }, /* f */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* g */
|
||||
{ ISFUNC, rl_backward }, /* h */
|
||||
{ ISFUNC, rl_backward_char }, /* h */
|
||||
{ ISFUNC, rl_vi_insertion_mode }, /* i */
|
||||
{ ISFUNC, rl_get_next_history }, /* j */
|
||||
{ ISFUNC, rl_get_previous_history }, /* k */
|
||||
{ ISFUNC, rl_forward }, /* l */
|
||||
{ ISFUNC, rl_forward_char }, /* l */
|
||||
{ ISFUNC, rl_vi_set_mark }, /* m */
|
||||
{ ISFUNC, rl_vi_search_again }, /* n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* o */
|
||||
|
||||
+166
-71
@@ -51,6 +51,8 @@
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "rldefs.h"
|
||||
#include "rlmbutil.h"
|
||||
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
@@ -61,10 +63,6 @@
|
||||
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
|
||||
#endif
|
||||
|
||||
#ifndef exchange
|
||||
#define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
|
||||
#endif
|
||||
|
||||
/* Non-zero means enter insertion mode. */
|
||||
static int _rl_vi_doing_insert;
|
||||
|
||||
@@ -89,7 +87,11 @@ static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
|
||||
static int _rl_vi_last_repeat = 1;
|
||||
static int _rl_vi_last_arg_sign = 1;
|
||||
static int _rl_vi_last_motion;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
|
||||
#else
|
||||
static int _rl_vi_last_search_char;
|
||||
#endif
|
||||
static int _rl_vi_last_replacement;
|
||||
|
||||
static int _rl_vi_last_key_before_insert;
|
||||
@@ -158,12 +160,15 @@ int
|
||||
rl_vi_redo (count, c)
|
||||
int count, c;
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!rl_explicit_arg)
|
||||
{
|
||||
rl_numeric_arg = _rl_vi_last_repeat;
|
||||
rl_arg_sign = _rl_vi_last_arg_sign;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
vi_redoing = 1;
|
||||
/* If we're redoing an insert with `i', stuff in the inserted text
|
||||
and do not go into insertion mode. */
|
||||
@@ -175,10 +180,10 @@ rl_vi_redo (count, c)
|
||||
rl_point--;
|
||||
}
|
||||
else
|
||||
_rl_dispatch (_rl_vi_last_command, _rl_keymap);
|
||||
r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
|
||||
vi_redoing = 0;
|
||||
|
||||
return (0);
|
||||
return (r);
|
||||
}
|
||||
|
||||
/* A placeholder for further expansion. */
|
||||
@@ -547,7 +552,17 @@ rl_vi_append_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_point < rl_end)
|
||||
rl_point++;
|
||||
{
|
||||
if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
rl_point++;
|
||||
else
|
||||
{
|
||||
int point = rl_point;
|
||||
rl_forward_char (1, key);
|
||||
if (point == rl_point)
|
||||
rl_point = rl_end;
|
||||
}
|
||||
}
|
||||
rl_vi_insertion_mode (1, key);
|
||||
return (0);
|
||||
}
|
||||
@@ -612,6 +627,7 @@ _rl_vi_done_inserting ()
|
||||
{
|
||||
if (_rl_vi_doing_insert)
|
||||
{
|
||||
/* The `C', `s', and `S' commands set this. */
|
||||
rl_end_undo_group ();
|
||||
/* Now, the text between rl_undo_list->next->start and
|
||||
rl_undo_list->next->end is what was inserted while in insert
|
||||
@@ -640,7 +656,7 @@ rl_vi_movement_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_point > 0)
|
||||
rl_backward (1, key);
|
||||
rl_backward_char (1, key);
|
||||
|
||||
_rl_keymap = vi_movement_keymap;
|
||||
_rl_vi_done_inserting ();
|
||||
@@ -657,6 +673,51 @@ rl_vi_arg_digit (count, c)
|
||||
return (rl_digit_argument (count, c));
|
||||
}
|
||||
|
||||
/* Change the case of the next COUNT characters. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int
|
||||
_rl_vi_change_mbchar_case (count)
|
||||
int count;
|
||||
{
|
||||
wchar_t wc;
|
||||
char mb[MB_LEN_MAX];
|
||||
mbstate_t ps;
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
|
||||
count--;
|
||||
while (count-- && rl_point < rl_end)
|
||||
{
|
||||
mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
|
||||
if (iswupper (wc))
|
||||
wc = towlower (wc);
|
||||
else if (iswlower (wc))
|
||||
wc = towupper (wc);
|
||||
else
|
||||
{
|
||||
/* Just skip over chars neither upper nor lower case */
|
||||
rl_forward_char (1, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Vi is kind of strange here. */
|
||||
if (wc)
|
||||
{
|
||||
wctomb (mb, wc);
|
||||
rl_begin_undo_group ();
|
||||
rl_delete (1, 0);
|
||||
rl_insert_text (mb);
|
||||
rl_end_undo_group ();
|
||||
rl_vi_check ();
|
||||
}
|
||||
else
|
||||
rl_forward_char (1, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
rl_vi_change_case (count, ignore)
|
||||
int count, ignore;
|
||||
@@ -667,6 +728,11 @@ rl_vi_change_case (count, ignore)
|
||||
if (rl_point >= rl_end)
|
||||
return (0);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
return (_rl_vi_change_mbchar_case (count));
|
||||
#endif
|
||||
|
||||
while (count-- && rl_point < rl_end)
|
||||
{
|
||||
if (_rl_uppercase_p (rl_line_buffer[rl_point]))
|
||||
@@ -676,7 +742,7 @@ rl_vi_change_case (count, ignore)
|
||||
else
|
||||
{
|
||||
/* Just skip over characters neither upper nor lower case. */
|
||||
rl_forward (1, c);
|
||||
rl_forward_char (1, c);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -685,12 +751,12 @@ rl_vi_change_case (count, ignore)
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
rl_delete (1, c);
|
||||
rl_insert (1, c);
|
||||
_rl_insert_char (1, c);
|
||||
rl_end_undo_group ();
|
||||
rl_vi_check ();
|
||||
}
|
||||
else
|
||||
rl_forward (1, c);
|
||||
rl_forward_char (1, c);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@@ -700,10 +766,10 @@ rl_vi_put (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
|
||||
rl_point++;
|
||||
rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
|
||||
|
||||
rl_yank (1, key);
|
||||
rl_backward (1, key);
|
||||
rl_backward_char (1, key);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -711,7 +777,12 @@ int
|
||||
rl_vi_check ()
|
||||
{
|
||||
if (rl_point && rl_point == rl_end)
|
||||
rl_point--;
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
|
||||
else
|
||||
rl_point--;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -813,7 +884,7 @@ rl_vi_domove (key, nextkey)
|
||||
}
|
||||
|
||||
if (rl_mark < rl_point)
|
||||
exchange (rl_point, rl_mark);
|
||||
SWAP (rl_point, rl_mark);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -991,7 +1062,10 @@ rl_vi_delete (count, key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
end = rl_point + count;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
|
||||
else
|
||||
end = rl_point + count;
|
||||
|
||||
if (end >= rl_end)
|
||||
end = rl_end;
|
||||
@@ -999,7 +1073,7 @@ rl_vi_delete (count, key)
|
||||
rl_kill_text (rl_point, end);
|
||||
|
||||
if (rl_point > 0 && rl_point == rl_end)
|
||||
rl_backward (1, key);
|
||||
rl_backward_char (1, key);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1024,7 +1098,12 @@ int
|
||||
rl_vi_char_search (count, key)
|
||||
int count, key;
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static char *target;
|
||||
static int mb_len;
|
||||
#else
|
||||
static char target;
|
||||
#endif
|
||||
static int orig_dir, dir;
|
||||
|
||||
if (key == ';' || key == ',')
|
||||
@@ -1032,12 +1111,21 @@ rl_vi_char_search (count, key)
|
||||
else
|
||||
{
|
||||
if (vi_redoing)
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
target = _rl_vi_last_search_mbchar;
|
||||
#else
|
||||
target = _rl_vi_last_search_char;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
|
||||
target = _rl_vi_last_search_mbchar;
|
||||
#else
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
_rl_vi_last_search_char = target = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (key)
|
||||
@@ -1060,7 +1148,11 @@ rl_vi_char_search (count, key)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return (_rl_char_search_internal (count, dir, target, mb_len));
|
||||
#else
|
||||
return (_rl_char_search_internal (count, dir, target));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Match brackets */
|
||||
@@ -1068,14 +1160,25 @@ int
|
||||
rl_vi_match (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
int count = 1, brack, pos;
|
||||
int count = 1, brack, pos, tmp, pre;
|
||||
|
||||
pos = rl_point;
|
||||
if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
|
||||
{
|
||||
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
|
||||
rl_point < rl_end - 1)
|
||||
rl_forward (1, key);
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
|
||||
{
|
||||
pre = rl_point;
|
||||
rl_forward_char (1, key);
|
||||
if (pre == rl_point)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
|
||||
rl_point < rl_end - 1)
|
||||
rl_forward_char (1, key);
|
||||
|
||||
if (brack <= 0)
|
||||
{
|
||||
@@ -1091,7 +1194,16 @@ rl_vi_match (ignore, key)
|
||||
{
|
||||
while (count)
|
||||
{
|
||||
if (--pos >= 0)
|
||||
tmp = pos;
|
||||
if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
pos--;
|
||||
else
|
||||
{
|
||||
pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
|
||||
if (tmp == pos)
|
||||
pos--;
|
||||
}
|
||||
if (pos >= 0)
|
||||
{
|
||||
int b = rl_vi_bracktype (rl_line_buffer[pos]);
|
||||
if (b == -brack)
|
||||
@@ -1110,7 +1222,12 @@ rl_vi_match (ignore, key)
|
||||
{ /* brack > 0 */
|
||||
while (count)
|
||||
{
|
||||
if (++pos < rl_end)
|
||||
if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
pos++;
|
||||
else
|
||||
pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
|
||||
|
||||
if (pos < rl_end)
|
||||
{
|
||||
int b = rl_vi_bracktype (rl_line_buffer[pos]);
|
||||
if (b == -brack)
|
||||
@@ -1145,6 +1262,11 @@ rl_vi_bracktype (c)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
|
||||
inserting it in one bunch instead of the loop below (like in
|
||||
rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
|
||||
for test against 033 or ^C. Make sure that _rl_read_mbchar does
|
||||
this right. */
|
||||
int
|
||||
rl_vi_change_char (count, key)
|
||||
int count, key;
|
||||
@@ -1168,9 +1290,19 @@ rl_vi_change_char (count, key)
|
||||
rl_begin_undo_group ();
|
||||
|
||||
rl_delete (1, c);
|
||||
rl_insert (1, c);
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
while (_rl_insert_char (1, c))
|
||||
{
|
||||
RL_SETSTATE (RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE (RL_STATE_MOREINPUT);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
_rl_insert_char (1, c);
|
||||
if (count == 0)
|
||||
rl_backward (1, c);
|
||||
rl_backward_char (1, c);
|
||||
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
@@ -1181,66 +1313,29 @@ int
|
||||
rl_vi_subst (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
/* If we are redoing, rl_vi_change_to will stuff the last motion char */
|
||||
if (vi_redoing == 0)
|
||||
rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
|
||||
|
||||
if (_rl_uppercase_p (key))
|
||||
{
|
||||
rl_beg_of_line (1, key);
|
||||
rl_kill_line (1, key);
|
||||
}
|
||||
else
|
||||
rl_delete_text (rl_point, rl_point+count);
|
||||
|
||||
rl_end_undo_group ();
|
||||
|
||||
_rl_vi_set_last (key, count, rl_arg_sign);
|
||||
|
||||
if (vi_redoing)
|
||||
{
|
||||
int o = _rl_doing_an_undo;
|
||||
|
||||
_rl_doing_an_undo = 1;
|
||||
if (vi_insert_buffer && *vi_insert_buffer)
|
||||
rl_insert_text (vi_insert_buffer);
|
||||
_rl_doing_an_undo = o;
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
_rl_vi_doing_insert = 1;
|
||||
rl_vi_insertion_mode (1, key);
|
||||
}
|
||||
|
||||
return (0);
|
||||
return (rl_vi_change_to (count, 'c'));
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_overstrike (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (_rl_vi_doing_insert == 0)
|
||||
{
|
||||
_rl_vi_doing_insert = 1;
|
||||
rl_begin_undo_group ();
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (count > 0)
|
||||
{
|
||||
vi_replace_count++;
|
||||
rl_begin_undo_group ();
|
||||
|
||||
if (rl_point < rl_end)
|
||||
{
|
||||
rl_delete (1, key);
|
||||
rl_insert (1, key);
|
||||
}
|
||||
else
|
||||
rl_insert (1, key);
|
||||
|
||||
rl_end_undo_group ();
|
||||
_rl_overwrite_char (count, key);
|
||||
vi_replace_count += count;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1263,7 +1358,7 @@ rl_vi_overstrike_delete (count, key)
|
||||
vi_replace_count--;
|
||||
|
||||
if (rl_point == s)
|
||||
rl_backward (1, key);
|
||||
rl_backward_char (1, key);
|
||||
}
|
||||
|
||||
if (vi_replace_count == 0 && _rl_vi_doing_insert)
|
||||
|
||||
Reference in New Issue
Block a user