You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.1 KiB
99 lines
3.1 KiB
diff --git a/bashline.c b/bashline.c |
|
--- a/bashline.c |
|
+++ b/bashline.c |
|
@@ -117,6 +117,7 @@ static char *restore_tilde __P((char *, char *)); |
|
|
|
static char *bash_filename_rewrite_hook __P((char *, int)); |
|
static void bash_directory_expansion __P((char **)); |
|
+static int bash_filename_stat_hook __P((char **)); |
|
static int bash_directory_completion_hook __P((char **)); |
|
static int filename_completion_ignore __P((char **)); |
|
static int bash_push_line __P((void)); |
|
@@ -1414,7 +1415,7 @@ bash_default_completion (text, start, end, qc, compflags) |
|
const char *text; |
|
int start, end, qc, compflags; |
|
{ |
|
- char **matches; |
|
+ char **matches, *t; |
|
|
|
matches = (char **)NULL; |
|
|
|
@@ -1424,7 +1425,19 @@ bash_default_completion (text, start, end, qc, compflags) |
|
if (qc != '\'' && text[1] == '(') /* ) */ |
|
matches = rl_completion_matches (text, command_subst_completion_function); |
|
else |
|
- matches = rl_completion_matches (text, variable_completion_function); |
|
+ { |
|
+ matches = rl_completion_matches (text, variable_completion_function); |
|
+ if (matches && matches[0] && matches[1] == 0) |
|
+ { |
|
+ t = savestring (matches[0]); |
|
+ bash_filename_stat_hook (&t); |
|
+ /* doesn't use test_for_directory because that performs tilde |
|
+ expansion */ |
|
+ if (file_isdir (t)) |
|
+ rl_completion_append_character = '/'; |
|
+ free (t); |
|
+ } |
|
+ } |
|
} |
|
|
|
/* If the word starts in `~', and there is no slash in the word, then |
|
@@ -2763,6 +2776,57 @@ restore_directory_hook (hookf) |
|
rl_directory_rewrite_hook = hookf; |
|
} |
|
|
|
+static int |
|
+bash_filename_stat_hook (dirname) |
|
+ char **dirname; |
|
+{ |
|
+ char *local_dirname, *new_dirname, *t; |
|
+ int should_expand_dirname, return_value; |
|
+ WORD_LIST *wl; |
|
+ struct stat sb; |
|
+ |
|
+ local_dirname = *dirname; |
|
+ should_expand_dirname = return_value = 0; |
|
+ if (t = mbschr (local_dirname, '$')) |
|
+ should_expand_dirname = '$'; |
|
+ else if (t = mbschr (local_dirname, '`')) /* XXX */ |
|
+ should_expand_dirname = '`'; |
|
+ |
|
+#if defined (HAVE_LSTAT) |
|
+ if (should_expand_dirname && lstat (local_dirname, &sb) == 0) |
|
+#else |
|
+ if (should_expand_dirname && stat (local_dirname, &sb) == 0) |
|
+#endif |
|
+ should_expand_dirname = 0; |
|
+ |
|
+ if (should_expand_dirname) |
|
+ { |
|
+ new_dirname = savestring (local_dirname); |
|
+ wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB); /* does the right thing */ |
|
+ if (wl) |
|
+ { |
|
+ free (new_dirname); |
|
+ new_dirname = string_list (wl); |
|
+ /* Tell the completer we actually expanded something and change |
|
+ *dirname only if we expanded to something non-null -- stat |
|
+ behaves unpredictably when passed null or empty strings */ |
|
+ if (new_dirname && *new_dirname) |
|
+ { |
|
+ free (local_dirname); /* XXX */ |
|
+ local_dirname = *dirname = new_dirname; |
|
+ return_value = STREQ (local_dirname, *dirname) == 0; |
|
+ } |
|
+ else |
|
+ free (new_dirname); |
|
+ dispose_words (wl); |
|
+ } |
|
+ else |
|
+ free (new_dirname); |
|
+ } |
|
+ |
|
+ return (return_value); |
|
+} |
|
+ |
|
/* Handle symbolic link references and other directory name |
|
expansions while hacking completion. This should return 1 if it modifies |
|
the DIRNAME argument, 0 otherwise. It should make sure not to modify
|
|
|