Blame SOURCES/bash-4.3-dircomp-append-slash.patch

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