about summary refs log tree commit diff stats
path: root/src/command
diff options
context:
space:
mode:
authorWilliam Wennerström <william@optmzr.se>2019-07-13 19:08:10 +0200
committerWilliam Wennerström <william@optmzr.se>2019-07-20 10:38:22 +0200
commit0c10a699f2be44665c6e7aa7ec82c0b07a71d743 (patch)
tree461073aca5fdefc72987759b662bfd95ffbeeb80 /src/command
parent63552720916dbe82cdb001eee74b7c08723b823a (diff)
downloadprofani-tty-0c10a699f2be44665c6e7aa7ec82c0b07a71d743.tar.gz
Always check for directory changes with sendfile auto completion
Instead of only checking for files when 'last_directory' has changed, do
it every time.

Add autocomplete_update function that updates the items while retaining
last_found and search_str.

Fixes #1099
Diffstat (limited to 'src/command')
-rw-r--r--src/command/cmd_ac.c95
1 files changed, 50 insertions, 45 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;