about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorMichael Vetter <jubalh@iodoru.org>2019-07-20 19:36:59 +0200
committerGitHub <noreply@github.com>2019-07-20 19:36:59 +0200
commit4a0fa1cf9eec0d12477f3feffa52b9d27ff6a2e0 (patch)
tree6d1b02c415a64e8468ae594a2742c973b37695c1 /src
parent9357726ed25e45f9634ecd0193ba603eca84cc5a (diff)
parent0c10a699f2be44665c6e7aa7ec82c0b07a71d743 (diff)
downloadprofani-tty-4a0fa1cf9eec0d12477f3feffa52b9d27ff6a2e0.tar.gz
Merge pull request #1154 from optmzr/issue-1099
 Always check for directory changes with sendfile auto completion
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_ac.c95
-rw-r--r--src/tools/autocomplete.c35
-rw-r--r--src/tools/autocomplete.h1
3 files changed, 84 insertions, 47 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 1ce20862..619ec55d 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -1290,11 +1290,15 @@ cmd_ac_uninit(void)
     autocomplete_free(statusbar_show_ac);
 }
 
+static void
+_filepath_item_free(char **ptr) {
+    char *item = *ptr;
+    free(item);
+}
+
 char*
 cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous)
 {
-    static char* last_directory = NULL;
-
     unsigned int output_off = 0;
 
     char *result = NULL;
@@ -1339,56 +1343,57 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean
     free(inpcp);
     free(inpcp2);
 
-    if (!last_directory || strcmp(last_directory, directory) != 0) {
-        free(last_directory);
-        last_directory = directory;
-        autocomplete_reset(filepath_ac);
-
-        struct dirent *dir;
-
-        DIR *d = opendir(directory);
-        if (d) {
-            while ((dir = readdir(d)) != NULL) {
-                if (strcmp(dir->d_name, ".") == 0) {
-                    continue;
-                } else if (strcmp(dir->d_name, "..") == 0) {
-                    continue;
-                } else if (*(dir->d_name) == '.' && *foofile != '.') {
-                    // only show hidden files on explicit request
-                    continue;
+    struct dirent *dir;
+    GArray *files = g_array_new(TRUE, FALSE, sizeof(char *));
+    g_array_set_clear_func(files, (GDestroyNotify)_filepath_item_free);
+
+    DIR *d = opendir(directory);
+    if (d) {
+        while ((dir = readdir(d)) != NULL) {
+            if (strcmp(dir->d_name, ".") == 0) {
+                continue;
+            } else if (strcmp(dir->d_name, "..") == 0) {
+                continue;
+            } else if (*(dir->d_name) == '.' && *foofile != '.') {
+                // only show hidden files on explicit request
+                continue;
+            }
+
+            char *acstring;
+            if (output_off) {
+                if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) {
+                    free(foofile);
+                    return NULL;
                 }
-                char * acstring;
-                if (output_off) {
-                    if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                    if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                    free(tmp);
-                } else if (strcmp(directory, "/") == 0) {
-                    if (asprintf(&acstring, "/%s", dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                } else {
-                    if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
+                if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) {
+                    free(foofile);
+                   return NULL;
+                }
+                free(tmp);
+            } else if (strcmp(directory, "/") == 0) {
+                if (asprintf(&acstring, "/%s", dir->d_name) == -1) {
+                    free(foofile);
+                    return NULL;
+                }
+            } else {
+                if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) {
+                    free(foofile);
+                    return NULL;
                 }
-                autocomplete_add(filepath_ac, acstring);
-                free(acstring);
             }
-            closedir(d);
+
+            char *acstring_cpy = strdup(acstring);
+            g_array_append_val(files, acstring_cpy);
+            free(acstring);
         }
-    } else {
-        free(directory);
+        closedir(d);
     }
+    free(directory);
     free(foofile);
 
+    autocomplete_update(filepath_ac, (char **)files->data);
+    g_array_free(files, TRUE);
+
     result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE, previous);
     if (result) {
         return result;
diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c
index 79312e53..03a30553 100644
--- a/src/tools/autocomplete.c
+++ b/src/tools/autocomplete.c
@@ -66,8 +66,10 @@ void
 autocomplete_clear(Autocomplete ac)
 {
     if (ac) {
-        g_list_free_full(ac->items, free);
-        ac->items = NULL;
+        if (ac->items) {
+            g_list_free_full(ac->items, free);
+            ac->items = NULL;
+        }
 
         autocomplete_reset(ac);
     }
@@ -102,6 +104,35 @@ autocomplete_length(Autocomplete ac)
 }
 
 void
+autocomplete_update(Autocomplete ac, char **items)
+{
+    gchar *last_found = NULL;
+    gchar *search_str = NULL;
+
+    if (ac->last_found) {
+        last_found = strdup(ac->last_found->data);
+    }
+
+    if (ac->search_str) {
+        search_str = strdup(ac->search_str);
+    }
+
+    autocomplete_clear(ac);
+    autocomplete_add_all(ac, items);
+
+    if (last_found) {
+        // NULL if last_found was removed on update.
+        ac->last_found = g_list_find_custom(ac->items, last_found, (GCompareFunc)strcmp);
+        free(last_found);
+    }
+
+    if (search_str) {
+        ac->search_str = strdup(search_str);
+        free(search_str);
+    }
+}
+
+void
 autocomplete_add(Autocomplete ac, const char *item)
 {
     if (ac) {
diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h
index 78bec44d..a8797369 100644
--- a/src/tools/autocomplete.h
+++ b/src/tools/autocomplete.h
@@ -51,6 +51,7 @@ void autocomplete_free(Autocomplete ac);
 
 void autocomplete_add(Autocomplete ac, const char *item);
 void autocomplete_add_all(Autocomplete ac, char **items);
+void autocomplete_update(Autocomplete ac, char **items);
 void autocomplete_remove(Autocomplete ac, const char *const item);
 void autocomplete_remove_all(Autocomplete ac, char **items);