[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH 1/1] guestfish: Tab-complete single / double quoted filenames containing space -- add fish_completion_word_break_characters_hook



This patch introduces fish_completion_word_break_characters_hook - Readline's
rl_completion_word_break_hook for guestfish so tab-completion on / for single /
double quoted filenames containing space would be possible too - this covers
part:

  "In addition:
  ><fs> ls "/Program Files/<tab>
    doesn't show any files to complete."

from RH BZ#547488.

Thank you, Jan.
--
Jan iankko Lieskovsky

P.S.: Feel free to remove the comment lines, if you find them unnecessary.

P.S.#2: Have got a patch for completion of unquoted filenames containing space
        too already, but need to give it further testing => will submit in
        separated post later.
diff --git a/fish/fish.c b/fish/fish.c
index db25373..4555582 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -1419,6 +1419,66 @@ static char histfile[1024];
 static int nr_history_lines = 0;
 #endif
 
+/* Readline word break hook for (guest)fish
+ * Exclude space from the set of word break characters if Readline's buffer
+ * contains path and some of possible tab-completions includes space.
+ * Return basic / default set of word break characters otherwise
+ */
+char *
+fish_completion_word_break_characters (void)
+{
+  char *p = strchr (rl_line_buffer, '/'), *q;
+  /* RL buffer contains path somewhere and path tab-completion
+   * was requested. */
+  if (p && complete_dest_paths) {
+    struct word *words = NULL;
+    size_t nr_words = 0;
+    /* List directory content into words */
+    list_directory_entries (p, &words, &nr_words);
+
+    size_t index = 0;
+    while (index < nr_words) {
+      struct word *word;
+
+      word = &words[index];
+      index++;
+
+      /* Whether we should match case insensitively here or not is
+       * determined by the value of the completion-ignore-case readline
+       * variable.  Default to case insensitive.  (See: RHBZ#582993).
+       */
+      char *cic_var = rl_variable_value ("completion-ignore-case");
+      int cic = 1;
+      if (cic_var && STREQ (cic_var, "off"))
+        cic = 0;
+
+      int matches =
+        cic ? STRCASEEQLEN (word->name, p, strlen (p))
+            : STREQLEN (word->name, p, strlen (p));
+
+      if (matches) {
+        char *nwbc = strdup (rl_completer_word_break_characters);
+
+        /* Does tab-completed form contain space? */
+        char *at = strchr (word->name, '\x20');
+        /* If so, exclude space from RL word break characters set */
+        if (at) {
+          for (q = nwbc, at = rl_completer_word_break_characters; *at; )
+            if (*at != '\x20')
+              *q++ = *at++;
+            else
+              at++;
+          *q = '\0';
+        /* Return the modified set */
+        return nwbc;
+        }
+      }
+    }
+  }
+  /* Return default word break characters set */
+  return strdup (rl_basic_word_break_characters);
+}
+
 static void
 initialize_readline (void)
 {
@@ -1426,6 +1486,7 @@ initialize_readline (void)
   const char *str;
 
   rl_readline_name = "guestfish";
+  rl_completion_word_break_hook = fish_completion_word_break_characters;
   rl_attempted_completion_function = do_completion;
 
   /* Note that .inputrc (or /etc/inputrc) is not read until the first

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]