This series provides support for tab completion also for single / double
quoted filenames, which can contain space.
Patch 0/1 - separates guestfs list directory content functionality
(from complete_dest_paths_generator()) into dedicated
list_directory_entries() routine, so it can be subsequently
re-used in other code places.
Patch 1/1 - introduces fish_completion_word_break_characters_hook for
guestfish (depends on list_directory_entries()).
Thank you && Regards, Jan.
--
Jan iankko Lieskovsky
P.S.: Feel free to remove the comment lines, if you find them unnecessary.diff --git a/fish/destpaths.c b/fish/destpaths.c
index ad57efd..03e3ef2 100644
--- a/fish/destpaths.c
+++ b/fish/destpaths.c
@@ -55,11 +55,6 @@
int complete_dest_paths = 1;
-struct word {
- char *name;
- int is_dir;
-};
-
#ifdef HAVE_LIBREADLINE
static void
free_words (struct word *words, size_t nr_words)
@@ -79,6 +74,72 @@ compare_words (const void *vp1, const void *vp2)
const struct word *w2 = (const struct word *) vp2;
return strcmp (w1->name, w2->name);
}
+
+/* List content of a directory specified by 'text' argument.
+ * Store the directory entries themselves into structure
+ * provided as 'ws' argument, and count of the items found
+ * into 'nr_ws' argument.
+ */
+void
+list_directory_entries (const char *text, struct word **ws, size_t *nr_ws)
+{
+ struct word *words = NULL;
+ size_t nr_words = 0;
+
+ /* If we've got a partial path already, we need to list everything
+ * in that directory, otherwise list everything in /
+ */
+ char *p, *dir;
+ struct guestfs_dirent_list *dirents;
+
+ p = strrchr (text, '/');
+ dir = p && p > text ? strndup (text, p - text) : strdup ("/");
+ if (dir) {
+ dirents = guestfs_readdir (g, dir);
+
+ /* Prepend directory to names before adding them to the list
+ * of words.
+ */
+ if (dirents) {
+ size_t i;
+
+ for (i = 0; i < dirents->len; ++i) {
+ int err;
+
+ if (STRNEQ (dirents->val[i].name, ".") &&
+ STRNEQ (dirents->val[i].name, "..")) {
+ if (STREQ (dir, "/"))
+ err = asprintf (&p, "/%s", dirents->val[i].name);
+ else
+ err = asprintf (&p, "%s/%s", dir, dirents->val[i].name);
+ if (err >= 0) {
+ if (!xalloc_oversized (nr_words+1, sizeof (struct word))) {
+ struct word *w;
+
+ w = realloc (words, sizeof (struct word) * (nr_words+1));
+ if (w == NULL) {
+ free_words (words, nr_words);
+ words = NULL;
+ nr_words = 0;
+ }
+ else {
+ words = w;
+ words[nr_words].name = p;
+ words[nr_words].is_dir = dirents->val[i].ftyp == 'd';
+ nr_words++;
+ }
+ }
+ }
+ }
+ }
+
+ guestfs_free_dirent_list (dirents);
+ }
+ }
+ /* Save the generated content back to the original arguments. */
+ *ws = words;
+ *nr_ws = nr_words;
+}
#endif
char *
@@ -150,58 +211,8 @@ complete_dest_paths_generator (const char *text, int state)
APPEND_STRS_AND_FREE;
}
- if (len < 1 || text[0] == '/') {
- /* If we've got a partial path already, we need to list everything
- * in that directory, otherwise list everything in /
- */
- char *p, *dir;
- struct guestfs_dirent_list *dirents;
-
- p = strrchr (text, '/');
- dir = p && p > text ? strndup (text, p - text) : strdup ("/");
- if (dir) {
- dirents = guestfs_readdir (g, dir);
-
- /* Prepend directory to names before adding them to the list
- * of words.
- */
- if (dirents) {
- size_t i;
-
- for (i = 0; i < dirents->len; ++i) {
- int err;
-
- if (STRNEQ (dirents->val[i].name, ".") &&
- STRNEQ (dirents->val[i].name, "..")) {
- if (STREQ (dir, "/"))
- err = asprintf (&p, "/%s", dirents->val[i].name);
- else
- err = asprintf (&p, "%s/%s", dir, dirents->val[i].name);
- if (err >= 0) {
- if (!xalloc_oversized (nr_words+1, sizeof (struct word))) {
- struct word *w;
-
- w = realloc (words, sizeof (struct word) * (nr_words+1));
- if (w == NULL) {
- free_words (words, nr_words);
- words = NULL;
- nr_words = 0;
- }
- else {
- words = w;
- words[nr_words].name = p;
- words[nr_words].is_dir = dirents->val[i].ftyp == 'd';
- nr_words++;
- }
- }
- }
- }
- }
-
- guestfs_free_dirent_list (dirents);
- }
- }
- }
+ if (len < 1 || text[0] == '/')
+ list_directory_entries (text, &words, &nr_words);
/* else ... In theory we could complete other things here such as VG
* names. At the moment we don't do that.
diff --git a/fish/fish.h b/fish/fish.h
index df22e34..1a56dd7 100644
--- a/fish/fish.h
+++ b/fish/fish.h
@@ -61,6 +61,11 @@ extern char **do_completion (const char *text, int start, int end);
/* in destpaths.c */
extern int complete_dest_paths;
+struct word {
+ char *name;
+ int is_dir;
+};
+extern void list_directory_entries (const char *text, struct word **ws, size_t *nr_ws);
extern char *complete_dest_paths_generator (const char *text, int state);
/* in events.c */
_______________________________________________
Libguestfs mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libguestfs