1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-12-04 14:46:46 -05:00

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
This commit is contained in:
William Wennerström 2019-07-13 19:08:10 +02:00
parent 6355272091
commit 0c10a699f2
No known key found for this signature in database
GPG Key ID: E1382990BEDD319B
3 changed files with 85 additions and 48 deletions

View File

@ -1290,11 +1290,15 @@ cmd_ac_uninit(void)
autocomplete_free(statusbar_show_ac); autocomplete_free(statusbar_show_ac);
} }
static void
_filepath_item_free(char **ptr) {
char *item = *ptr;
free(item);
}
char* char*
cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous) cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous)
{ {
static char* last_directory = NULL;
unsigned int output_off = 0; unsigned int output_off = 0;
char *result = NULL; char *result = NULL;
@ -1339,56 +1343,57 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean
free(inpcp); free(inpcp);
free(inpcp2); free(inpcp2);
if (!last_directory || strcmp(last_directory, directory) != 0) { struct dirent *dir;
free(last_directory); GArray *files = g_array_new(TRUE, FALSE, sizeof(char *));
last_directory = directory; g_array_set_clear_func(files, (GDestroyNotify)_filepath_item_free);
autocomplete_reset(filepath_ac);
struct dirent *dir; DIR *d = opendir(directory);
if (d) {
DIR *d = opendir(directory); while ((dir = readdir(d)) != NULL) {
if (d) { if (strcmp(dir->d_name, ".") == 0) {
while ((dir = readdir(d)) != NULL) { continue;
if (strcmp(dir->d_name, ".") == 0) { } else if (strcmp(dir->d_name, "..") == 0) {
continue; continue;
} else if (strcmp(dir->d_name, "..") == 0) { } else if (*(dir->d_name) == '.' && *foofile != '.') {
continue; // only show hidden files on explicit request
} else if (*(dir->d_name) == '.' && *foofile != '.') { continue;
// 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;
}
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;
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;
}
}
char *acstring_cpy = strdup(acstring);
g_array_append_val(files, acstring_cpy);
free(acstring);
} }
} else { closedir(d);
free(directory);
} }
free(directory);
free(foofile); 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); result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE, previous);
if (result) { if (result) {
return result; return result;

View File

@ -66,8 +66,10 @@ void
autocomplete_clear(Autocomplete ac) autocomplete_clear(Autocomplete ac)
{ {
if (ac) { if (ac) {
g_list_free_full(ac->items, free); if (ac->items) {
ac->items = NULL; g_list_free_full(ac->items, free);
ac->items = NULL;
}
autocomplete_reset(ac); autocomplete_reset(ac);
} }
@ -101,6 +103,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 void
autocomplete_add(Autocomplete ac, const char *item) autocomplete_add(Autocomplete ac, const char *item)
{ {

View File

@ -51,6 +51,7 @@ void autocomplete_free(Autocomplete ac);
void autocomplete_add(Autocomplete ac, const char *item); void autocomplete_add(Autocomplete ac, const char *item);
void autocomplete_add_all(Autocomplete ac, char **items); 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(Autocomplete ac, const char *const item);
void autocomplete_remove_all(Autocomplete ac, char **items); void autocomplete_remove_all(Autocomplete ac, char **items);