* readline.h (rl_completer_quote_characters): Add declaration.
* readline.c (rl_completer_quote_characters): Add global var. * readline.c (strpbrk): Add prototype and function. * readline.c (rl_complete_internal): Add code to handle expansion of quoted strings.
This commit is contained in:
parent
d630b6150e
commit
dd823a49ca
2 changed files with 125 additions and 12 deletions
|
@ -1,3 +1,11 @@
|
|||
Mon Jun 8 23:10:07 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* readline.h (rl_completer_quote_characters): Add declaration.
|
||||
* readline.c (rl_completer_quote_characters): Add global var.
|
||||
* readline.c (strpbrk): Add prototype and function.
|
||||
* readline.c (rl_complete_internal): Add code to handle
|
||||
expansion of quoted strings.
|
||||
|
||||
Mon May 11 12:39:30 1992 John Gilmore (gnu at cygnus.com)
|
||||
|
||||
* readline.c: Can't initialize FILE *'s with stdin and stdout,
|
||||
|
|
|
@ -179,7 +179,7 @@ typedef sighandler SigHandler ();
|
|||
#define HANDLE_SIGNALS
|
||||
|
||||
#ifdef __GO32__
|
||||
#include <pc.h>
|
||||
#include <sys/pc.h>
|
||||
#undef HANDLE_SIGNALS
|
||||
#endif
|
||||
|
||||
|
@ -241,7 +241,7 @@ static jmp_buf readline_top_level;
|
|||
static FILE *in_stream, *out_stream;
|
||||
|
||||
/* The names of the streams that we do input and output to. */
|
||||
FILE *rl_instream = stdin, *rl_outstream = stdout;
|
||||
FILE *rl_instream, *rl_outstream;
|
||||
|
||||
/* Non-zero means echo characters as they are read. */
|
||||
int readline_echoing_p = 1;
|
||||
|
@ -292,6 +292,7 @@ static unsigned char parsing_conditionalized_out = 0;
|
|||
|
||||
/* Caseless strcmp (). */
|
||||
static int stricmp (), strnicmp ();
|
||||
static char *strpbrk ();
|
||||
|
||||
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
|
||||
static int defining_kbd_macro = 0;
|
||||
|
@ -1119,6 +1120,12 @@ readline_initialize_everything ()
|
|||
/* Find out if we are running in Emacs. */
|
||||
running_in_emacs = getenv ("EMACS");
|
||||
|
||||
/* Set up input and output if they aren't already. */
|
||||
if (!rl_instream)
|
||||
rl_instream = stdin;
|
||||
if (!rl_outstream)
|
||||
rl_outstream = stdout;
|
||||
|
||||
/* Allocate data structures. */
|
||||
if (!rl_line_buffer)
|
||||
rl_line_buffer =
|
||||
|
@ -3619,6 +3626,12 @@ char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
|
|||
rl_basic_word_break_characters. */
|
||||
char *rl_completer_word_break_characters = (char *)NULL;
|
||||
|
||||
/* The list of characters which are used to quote a substring of the command
|
||||
line. Command completion occurs on the entire substring, and within the
|
||||
substring rl_completer_word_break_characters are treated as any other
|
||||
character, unless they also appear within this list. */
|
||||
char *rl_completer_quote_characters = (char *)NULL;
|
||||
|
||||
/* List of characters that are word break characters, but should be left
|
||||
in TEXT when it is passed to the completion function. The shell uses
|
||||
this to help determine what kind of completing to do. */
|
||||
|
@ -3654,8 +3667,10 @@ rl_complete_internal (what_to_do)
|
|||
char *filename_completion_function ();
|
||||
char **completion_matches (), **matches;
|
||||
Function *our_func;
|
||||
int start, end, delimiter = 0;
|
||||
int start, scan, end, delimiter = 0;
|
||||
char *text, *saved_line_buffer;
|
||||
char quote_char = '\0';
|
||||
char *replacement;
|
||||
|
||||
if (the_line)
|
||||
saved_line_buffer = savestring (the_line);
|
||||
|
@ -3675,8 +3690,41 @@ rl_complete_internal (what_to_do)
|
|||
|
||||
if (rl_point)
|
||||
{
|
||||
while (--rl_point &&
|
||||
!rindex (rl_completer_word_break_characters, the_line[rl_point]));
|
||||
if (rl_completer_quote_characters)
|
||||
{
|
||||
/* We have a list of characters which can be used in pairs to quote
|
||||
substrings for completion. Try to find the start of an unclosed
|
||||
quoted substring.
|
||||
FIXME: Doesn't yet handle '\' escapes to hid embedded quotes */
|
||||
for (scan = 0; scan < end; scan++)
|
||||
{
|
||||
if (quote_char != '\0')
|
||||
{
|
||||
/* Ignore everything until the matching close quote char */
|
||||
if (the_line[scan] == quote_char)
|
||||
{
|
||||
/* Found matching close quote. Abandon this substring. */
|
||||
quote_char = '\0';
|
||||
rl_point = end;
|
||||
}
|
||||
}
|
||||
else if (rindex (rl_completer_quote_characters, the_line[scan]))
|
||||
{
|
||||
/* Found start of a quoted substring. */
|
||||
quote_char = the_line[scan];
|
||||
rl_point = scan + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rl_point == end)
|
||||
{
|
||||
/* 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 do completion. */
|
||||
while (--rl_point &&
|
||||
!rindex (rl_completer_word_break_characters,
|
||||
the_line[rl_point])) {;}
|
||||
}
|
||||
|
||||
/* If we are at a word break, then advance past it. */
|
||||
if (rindex (rl_completer_word_break_characters, the_line[rl_point]))
|
||||
|
@ -3728,7 +3776,7 @@ rl_complete_internal (what_to_do)
|
|||
some_matches:
|
||||
|
||||
/* It seems to me that in all the cases we handle we would like
|
||||
to ignore duplicate possiblilities. Scan for the text to
|
||||
to ignore duplicate possibilities. Scan for the text to
|
||||
insert being identical to the other completions. */
|
||||
if (rl_ignore_completion_duplicates)
|
||||
{
|
||||
|
@ -3801,11 +3849,40 @@ rl_complete_internal (what_to_do)
|
|||
our_func == (int (*)())filename_completion_function)
|
||||
(void)(*rl_ignore_some_completions_function)(matches);
|
||||
|
||||
if (matches[0])
|
||||
/* If we are doing completions on quoted substrings, and any matches
|
||||
contain any of the completer word break characters, then auto-
|
||||
matically prepend the substring with a quote character (just
|
||||
pick the first one from the list of such) if it does not already
|
||||
begin with a quote string. FIXME: Need to remove any such
|
||||
automatically inserted quote character when it no longer is
|
||||
necessary, such as if we change the string we are completing on
|
||||
and the new set of matches don't require a quoted substring? */
|
||||
|
||||
replacement = matches[0];
|
||||
if (matches[0] != NULL
|
||||
&& rl_completer_quote_characters != NULL
|
||||
&& (quote_char == '\0'))
|
||||
{
|
||||
for (i = 1; matches[i] != NULL; i++)
|
||||
{
|
||||
if (strpbrk (matches[i], rl_completer_word_break_characters))
|
||||
{
|
||||
/* Found an embedded word break character in a potential
|
||||
match, so need to prepend a quote character if we are
|
||||
replacing the completion string. */
|
||||
replacement = alloca (strlen (matches[0]) + 2);
|
||||
quote_char = *rl_completer_quote_characters;
|
||||
*replacement = quote_char;
|
||||
strcpy (replacement + 1, matches[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (replacement)
|
||||
{
|
||||
rl_delete_text (start, rl_point);
|
||||
rl_point = start;
|
||||
rl_insert_text (matches[0]);
|
||||
rl_insert_text (replacement);
|
||||
}
|
||||
|
||||
/* If there are more matches, ring the bell to indicate.
|
||||
|
@ -3819,10 +3896,15 @@ rl_complete_internal (what_to_do)
|
|||
}
|
||||
else
|
||||
{
|
||||
char temp_string[2];
|
||||
char temp_string[16];
|
||||
int temp_index = 0;
|
||||
|
||||
temp_string[0] = delimiter ? delimiter : ' ';
|
||||
temp_string[1] = '\0';
|
||||
if (quote_char)
|
||||
{
|
||||
temp_string[temp_index++] = quote_char;
|
||||
}
|
||||
temp_string[temp_index++] = delimiter ? delimiter : ' ';
|
||||
temp_string[temp_index++] = '\0';
|
||||
|
||||
if (rl_filename_completion_desired)
|
||||
{
|
||||
|
@ -5559,8 +5641,10 @@ rl_named_function (string)
|
|||
|
||||
/* The last key bindings file read. */
|
||||
#ifdef __MSDOS__
|
||||
static char *last_readline_init_file = "~/inputrc";
|
||||
/* Don't know what to do, but this is a guess */
|
||||
static char *last_readline_init_file = "/INPUTRC";
|
||||
#else
|
||||
static char *last_readline_init_file = "~/inputrc";
|
||||
#endif
|
||||
|
||||
/* Re-read the current keybindings file. */
|
||||
|
@ -6310,6 +6394,27 @@ rl_function_dumper (print_readably)
|
|||
|
||||
static char *strindex ();
|
||||
|
||||
/* Return pointer to first occurance in STRING1 of any character from STRING2,
|
||||
or NULL if no occurance found. */
|
||||
static char *
|
||||
strpbrk (string1, string2)
|
||||
char *string1, *string2;
|
||||
{
|
||||
register char *scan;
|
||||
|
||||
for (; *string1 != '\0'; string1++)
|
||||
{
|
||||
for (scan = string2; *scan != '\0'; scan++)
|
||||
{
|
||||
if (*string1 == *scan)
|
||||
{
|
||||
return (string1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Return non-zero if any members of ARRAY are a substring in STRING. */
|
||||
static int
|
||||
substring_member_of_array (string, array)
|
||||
|
|
Loading…
Reference in a new issue