]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - bashline.c
commit bash-20150619 snapshot
[thirdparty/bash.git] / bashline.c
index 1449b869fa6a810cf51278ce165995b52ab0cacd..1cef29efad1cf2207fca5635041f4c5d0570e037 100644 (file)
 #include "shmbutil.h"
 #include "trap.h"
 
+#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
+#  include <mbstr.h>           /* mbschr */
+#endif
+
 #include "builtins/common.h"
 
 #include <readline/rlconf.h>
@@ -137,6 +141,8 @@ static int executable_completion __P((const char *, int));
 static rl_icppfunc_t *save_directory_hook __P((void));
 static void restore_directory_hook __P((rl_icppfunc_t));
 
+static int directory_exists __P((const char *));
+
 static void cleanup_expansion_error __P((void));
 static void maybe_make_readline_line __P((char *));
 static void set_up_new_line __P((char *));
@@ -631,6 +637,8 @@ bashline_reset ()
   rl_filename_stat_hook = bash_filename_stat_hook;
 
   bashline_reset_event_hook ();
+
+  rl_sort_completion_matches = 1;
 }
 
 /* Contains the line to push into readline. */
@@ -1429,6 +1437,8 @@ attempt_shell_completion (text, start, end)
   set_directory_hook ();
   rl_filename_stat_hook = bash_filename_stat_hook;
 
+  rl_sort_completion_matches = 1;      /* sort by default */
+
   /* Determine if this could be a command word.  It is if it appears at
      the start of the line (ignoring preceding whitespace), or if it
      appears after a character that separates commands.  It cannot be a
@@ -3069,6 +3079,30 @@ restore_directory_hook (hookf)
     rl_directory_rewrite_hook = hookf;
 }
 
+/* Check whether not the (dequoted) version of DIRNAME, with any trailing slash
+   removed, exists. */
+static int
+directory_exists (dirname)
+     const char *dirname;
+{
+  char *new_dirname;
+  int dirlen, r;
+  struct stat sb;
+
+  /* First, dequote the directory name */
+  new_dirname = bash_dequote_filename (dirname, rl_completion_quote_character);
+  dirlen = STRLEN (new_dirname);
+  if (new_dirname[dirlen - 1] == '/')
+    new_dirname[dirlen - 1] = '\0';
+#if defined (HAVE_LSTAT)
+  r = lstat (new_dirname, &sb) == 0;
+#else
+  r = stat (new_dirname, &sb) == 0;
+#endif
+  free (new_dirname);
+  return (r);
+}
+  
 /* Expand a filename before the readline completion code passes it to stat(2).
    The filename will already have had tilde expansion performed. */
 static int
@@ -3087,11 +3121,7 @@ bash_filename_stat_hook (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
+  if (should_expand_dirname && directory_exists (local_dirname))
     should_expand_dirname = 0;
   
   if (should_expand_dirname)  
@@ -3155,7 +3185,8 @@ bash_directory_completion_hook (dirname)
      char **dirname;
 {
   char *local_dirname, *new_dirname, *t;
-  int return_value, should_expand_dirname, nextch, closer;
+  int return_value, should_expand_dirname, nextch, closer, changed;
+  size_t local_dirlen;
   WORD_LIST *wl;
   struct stat sb;
 
@@ -3184,11 +3215,7 @@ bash_directory_completion_hook (dirname)
        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
+  if (should_expand_dirname && directory_exists (local_dirname))
     should_expand_dirname = 0;
 
   if (should_expand_dirname)  
@@ -4084,7 +4111,14 @@ bash_execute_unix_command (count, key)
   array_needs_making = 1;
 
   /* and restore the readline buffer and display after command execution. */
-  rl_forced_update_display ();
+  /* If we clear the last line of the prompt above, redraw only that last
+     line.  If the command returns 124, we redraw unconditionally as in
+     previous versions. */
+  if (ce && r != 124)
+    rl_redraw_prompt_last_line ();
+  else
+    rl_forced_update_display ();
+
   return 0;
 }