summaryrefslogtreecommitdiff
path: root/bashline.c
diff options
context:
space:
mode:
Diffstat (limited to 'bashline.c')
-rw-r--r--bashline.c76
1 files changed, 60 insertions, 16 deletions
diff --git a/bashline.c b/bashline.c
index d11904a..1c41582 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1,6 +1,6 @@
/* bashline.c -- Bash's interface to the readline library. */
-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -238,6 +238,9 @@ static int dot_in_path = 0;
#define COMPLETE_BSQUOTE 3
static int completion_quoting_style = COMPLETE_BSQUOTE;
+/* Flag values for the final argument to bash_default_completion */
+#define DEFCOMP_CMDPOS 1
+
/* Change the readline VI-mode keymaps into or out of Posix.2 compliance.
Called when the shell is put into or out of `posix' mode. */
void
@@ -1006,7 +1009,7 @@ attempt_shell_completion (text, start, end)
const char *text;
int start, end;
{
- int in_command_position, ti, saveti, qc;
+ int in_command_position, ti, saveti, qc, dflags;
char **matches, *command_separator_chars;
command_separator_chars = COMMAND_SEPARATORS;
@@ -1124,15 +1127,20 @@ attempt_shell_completion (text, start, end)
#endif
if (matches == 0)
- matches = bash_default_completion (text, start, end, qc, in_command_position);
+ {
+ dflags = 0;
+ if (in_command_position)
+ dflags |= DEFCOMP_CMDPOS;
+ matches = bash_default_completion (text, start, end, qc, dflags);
+ }
return matches;
}
char **
-bash_default_completion (text, start, end, qc, in_command_position)
+bash_default_completion (text, start, end, qc, compflags)
const char *text;
- int start, end, qc, in_command_position;
+ int start, end, qc, compflags;
{
char **matches;
@@ -1165,9 +1173,11 @@ bash_default_completion (text, start, end, qc, in_command_position)
/* And last, (but not least) if this word is in a command position, then
complete over possible command names, including aliases, functions,
and command names. */
- if (!matches && in_command_position)
+ if (matches == 0 && (compflags & DEFCOMP_CMDPOS))
{
- if (start == 0 && end == 0 && text[0] == '\0' && no_empty_command_completion)
+ /* If END == START and text[0] == 0, we are trying to complete an empty
+ command word. */
+ if (no_empty_command_completion && end == start && text[0] == '\0')
{
matches = (char **)NULL;
rl_ignore_some_completions_function = bash_ignore_everything;
@@ -1243,7 +1253,7 @@ command_word_completion_function (hint_text, state)
static char *filename_hint = (char *)NULL;
static char *dequoted_hint = (char *)NULL;
static int path_index, hint_len, dequoted_len, istate, igncase;
- static int mapping_over, local_index;
+ static int mapping_over, local_index, searching_path, hint_is_dir;
static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
#if defined (ALIAS)
static alias_t **alias_list = (alias_t **)NULL;
@@ -1259,7 +1269,8 @@ command_word_completion_function (hint_text, state)
if (hint)
free (hint);
- mapping_over = 0;
+ mapping_over = searching_path = 0;
+ hint_is_dir = CMD_IS_DIR (hint_text);
val = (char *)NULL;
temp = rl_variable_value ("completion-ignore-case");
@@ -1398,6 +1409,16 @@ command_word_completion_function (hint_text, state)
mapping_over++;
}
+ /* If the text passed is a directory in the current directory, return it
+ as a possible match. Executables in directories in the current
+ directory can be specified using relative pathnames and successfully
+ executed even when `.' is not in $PATH. */
+ if (hint_is_dir)
+ {
+ hint_is_dir = 0; /* only return the hint text once */
+ return (savestring (hint_text));
+ }
+
/* Repeatedly call filename_completion_function while we have
members of PATH left. Question: should we stat each file?
Answer: we call executable_file () on each file. */
@@ -1415,6 +1436,7 @@ command_word_completion_function (hint_text, state)
(current_path = extract_colon_unit (path, &path_index)) == 0)
return ((char *)NULL);
+ searching_path = 1;
if (*current_path == 0)
{
free (current_path);
@@ -1456,7 +1478,9 @@ command_word_completion_function (hint_text, state)
else
{
int match, freetemp;
- char *temp;
+#if 0
+ char *temp; /* shadows previous declaration */
+#endif
if (absolute_program (hint))
{
@@ -1508,9 +1532,18 @@ command_word_completion_function (hint_text, state)
freetemp = match = 0;
}
+#if 0
/* If we have found a match, and it is an executable file or a
directory name, return it. */
if (match && executable_or_directory (val))
+#else
+ /* If we have found a match, and it is an executable file, return it.
+ We don't return directory names when searching $PATH, since the
+ bash execution code won't find executables in directories which
+ appear in directories in $PATH when they're specified using
+ relative pathnames. */
+ if (match && (searching_path ? executable_file (val) : executable_or_directory (val)))
+#endif
{
free (val);
val = ""; /* So it won't be NULL. */
@@ -1746,8 +1779,9 @@ bash_servicename_completion_function (text, state)
if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen)))
break;
/* Not primary, check aliases */
- for (alist = srvent->s_aliases; aentry = *alist; alist++)
+ for (alist = srvent->s_aliases; *alist; alist++)
{
+ aentry = *alist;
if (STREQN (sname, aentry, snamelen))
{
afound = 1;
@@ -2282,7 +2316,7 @@ static void
bash_directory_expansion (dirname)
char **dirname;
{
- char *d;
+ char *d, *nd;
d = savestring (*dirname);
@@ -2294,6 +2328,13 @@ bash_directory_expansion (dirname)
free (*dirname);
*dirname = d;
}
+ else if (rl_completion_found_quote)
+ {
+ nd = bash_dequote_filename (d, rl_completion_quote_character);
+ free (*dirname);
+ free (d);
+ *dirname = nd;
+ }
}
/* Handle symbolic link references and other directory name
@@ -2354,6 +2395,13 @@ bash_directory_completion_hook (dirname)
return 1;
}
}
+ else
+ {
+ /* Dequote the filename even if we don't expand it. */
+ new_dirname = bash_dequote_filename (local_dirname, rl_completion_quote_character);
+ free (local_dirname);
+ local_dirname = *dirname = new_dirname;
+ }
if (!no_symbolic_links && (local_dirname[0] != '.' || local_dirname[1]))
{
@@ -3140,11 +3188,7 @@ bash_directory_completion_matches (text)
char *dfn;
int qc;
-#if 0
- qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
-#else
qc = rl_dispatching ? rl_completion_quote_character : 0;
-#endif
dfn = bash_dequote_filename ((char *)text, qc);
m1 = rl_completion_matches (dfn, rl_filename_completion_function);
free (dfn);