On Sun, Jun 26, 2011 at 05:42:31PM +0200, Raphaël Droz wrote:
> Attached is an updated version of "dont-bug-command-name-completion.patch".
(really) attached
commit b3572793f7e77bf3ccb4e58121aabe457ddbe39c
Author: Raphaël Droz
Date: Sat Jun 25 22:55:11 2011 +0200
Colored completion, bugfix (8/6).
When a filename completion needs $PATH traversal (like the
completion of a command name), don't hide the absolute path
of matches to readline.
Fewer matches will be considered as missing files when completing
a command name.
diff --git a/bashline.c b/bashline.c
index 692b912..b2d2e06 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1899,12 +1899,20 @@ globword:
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)))
+ int is_executable_file = 0;
+ if (match && (searching_path ? ( is_executable_file = executable_file
(val) ) : executable_or_directory (val)))
#endif
{
- free (val);
- val = ""; /* So it won't be NULL. */
- return (temp);
+ if(is_executable_file) {
+ rl_executable_completion_desired = 1;
+ free (temp);
+ return val;
+ }
+ else {
+ free (val);
+ val = ""; /* So it won't be NULL. */
+ return (temp);
+ }
}
else
{
diff --git a/lib/readline/complete.c b/lib/readline/complete.c
index 661a5fa..e534bfe 100644
--- a/lib/readline/complete.c
+++ b/lib/readline/complete.c
@@ -317,6 +317,15 @@ int rl_ignore_completion_duplicates = 1;
within a completion entry finder function. */
int rl_filename_completion_desired = 0;
+/* Non-zero means that at least one of the results of the matches is
+ an absolute path. This is ALWAYS zero on entry, and can only be changed
+ within the entry_function callback given to rl_completion_matches.
+ If it is set to a non-zero value the lower common denominator computation
+ will take care of stripping directory names each filename match belongs to.
+ The matches should expect to be processed by printable_part().
+ print_filename() will receive a correct full_pathname parameter. */
+int rl_executable_completion_desired = 0;
+
/* Non-zero means that the results of the matches are to be quoted using
double quotes (or an application-specific quoting mechanism) if the
filename contains any characters in rl_filename_quote_chars. This is
@@ -1144,6 +1153,17 @@ gen_completion_matches (text, start, end, our_func,
found_quote, quote_char)
return matches;
}
+/* Used by compute_lcd_of_matches() and remove_duplicate_matches()
+ when, during the lower common denominator calculation,
+ we have interest in stripping a possible directory part of an
+ absolute path (= if rl_executable_completion_desired > 0). */
+static char *possibly_strip_dirname(char *match) {
+ if( rl_executable_completion_desired )
+return printable_part(match);
+ else
+return match;
+}
+
/* Filter out duplicates in MATCHES. This frees up the strings in
MATCHES. */
static char **
@@ -1161,15 +1181,19 @@ remove_duplicate_matches (matches)
/* Sort the array without matches[0], since we need it to
stay in place no matter what. */
- if (i && rl_sort_completion_matches)
-qsort (matches+1, i-1, sizeof (char *), (QSFUNC
*)_rl_qsort_string_compare);
+ if (i && rl_sort_completion_matches) {
+if(rl_executable_completion_desired)
+ qsort (matches+1, i-1, sizeof (char *), (QSFUNC
*)_rl_qsort_basename_string_compare);
+else
+ qsort (matches+1, i-1, sizeof (char *), (QSFUNC
*)_rl_qsort_string_compare);
+ }
/* Remember the lowest common denominator for it may be unique. */
lowest_common = savestring (matches[0]);
for (i = newlen = 0; matches[i + 1]; i++)
{
- if (strcmp (matches[i], matches[i + 1]) == 0)
+ if (strcmp (possibly_strip_dirname(matches[i]),
possibly_strip_dirname(matches[i + 1])) == 0)
{
xfree (matches[i]);
matches[i] = (char *)&dead_slot;
@@ -1202,6 +1226,10 @@ remove_duplicate_matches (matches)
xfree (temp_array[1]);
temp_array[1] = (char *)NULL;
}
+ else if (j == 2 && rl_executable_completion_desired ) {
+strcpy (temp_array[0], printable_part(temp_array[1]));
+temp_array[1] = (char *)NULL;
+ }
return (temp_array);
}
@@ -1227,7 +1255,19 @@ compute_lcd_of_matches (match_list, matches, text)
stop matching. */
if (matches == 1)
{
- match_list[0] = match_list[1];
+ /* command name completion requested but one match only was found.
+We forget (and reverse) about the absolute path.
+See bash:command_word_completion_function(). */
+ if(rl_executable_completion_desired == 1) {
+ char