diff --git a/inc/wofi.h b/inc/wofi.h index 7618409..a84507f 100644 --- a/inc/wofi.h +++ b/inc/wofi.h @@ -48,6 +48,8 @@ char* wofi_parse_image_escapes(const char* text); void wofi_write_cache(const gchar* mode, const gchar* cmd); +void wofi_remove_cache(const gchar* mode, const gchar* cmd); + struct wl_list* wofi_read_cache(char* mode); void wofi_insert_widget(char* mode, char** text, char* search_text, char** actions, size_t action_count); diff --git a/modes/dmenu.c b/modes/dmenu.c index 84cd05b..2c8454e 100644 --- a/modes/dmenu.c +++ b/modes/dmenu.c @@ -29,16 +29,10 @@ void wofi_dmenu_init(struct map* config) { struct map* cached = map_init(); struct wl_list* cache = wofi_read_cache(MODE); - struct cache_line* node, *tmp; - wl_list_for_each_safe(node, tmp, cache, link) { - wofi_insert_widget(MODE, &node->line, node->line, &node->line, 1); - map_put(cached, node->line, "true"); - free(node->line); - wl_list_remove(&node->link); - free(node); - } + struct wl_list entries; + wl_list_init(&entries); - free(cache); + struct map* entry_map = map_init(); char* line = NULL; size_t size = 0; @@ -47,12 +41,37 @@ void wofi_dmenu_init(struct map* config) { if(lf != NULL) { *lf = 0; } - if(map_contains(cached, line)) { - continue; - } - wofi_insert_widget(MODE, &line, line, &line, 1); + struct cache_line* node = malloc(sizeof(struct cache_line)); + node->line = strdup(line); + wl_list_insert(&entries, &node->link); + map_put(entry_map, line, "true"); } free(line); + + struct cache_line* node, *tmp; + wl_list_for_each_safe(node, tmp, cache, link) { + if(map_contains(entry_map, node->line)) { + map_put(cached, node->line, "true"); + wofi_insert_widget(MODE, &node->line, node->line, &node->line, 1); + } else { + wofi_remove_cache(MODE, node->line); + } + free(node->line); + wl_list_remove(&node->link); + free(node); + } + + free(cache); + map_free(entry_map); + + wl_list_for_each_reverse_safe(node, tmp, &entries, link) { + if(!map_contains(cached, node->line)) { + wofi_insert_widget(MODE, &node->line, node->line, &node->line, 1); + } + free(node->line); + wl_list_remove(&node->link); + free(node); + } map_free(cached); } diff --git a/modes/drun.c b/modes/drun.c index 32bad5f..e0b9d6a 100644 --- a/modes/drun.c +++ b/modes/drun.c @@ -185,6 +185,7 @@ void wofi_drun_init() { size_t action_count; char** text = get_action_text(node->line, &action_count); if(text == NULL) { + wofi_remove_cache(MODE, node->line); goto cache_cont; } diff --git a/modes/run.c b/modes/run.c index cfb272c..843a655 100644 --- a/modes/run.c +++ b/modes/run.c @@ -42,9 +42,15 @@ void wofi_run_init(struct map* config) { } else { text = final_slash + 1; } - wofi_insert_widget(MODE, &text, text, &node->line, 1); - map_put(cached, node->line, "true"); - map_put(entries, text, "true"); + struct stat info; + stat(node->line, &info); + if(access(node->line, X_OK) == 0 && S_ISREG(info.st_mode)) { + wofi_insert_widget(MODE, &text, text, &node->line, 1); + map_put(cached, node->line, "true"); + map_put(entries, text, "true"); + } else { + wofi_remove_cache(MODE, node->line); + } free(node->line); wl_list_remove(&node->link); free(node); diff --git a/src/wofi.c b/src/wofi.c index 8949a8c..0e23380 100644 --- a/src/wofi.c +++ b/src/wofi.c @@ -348,9 +348,9 @@ void wofi_write_cache(const gchar* mode, const gchar* cmd) { size_t size = 0; while(getline(&line, &size, file) != -1) { char* space = strchr(line, ' '); - char* nl = strchr(line, '\n'); - if(nl != NULL) { - *nl = 0; + char* lf = strchr(line, '\n'); + if(lf != NULL) { + *lf = 0; } if(space != NULL && strcmp(cmd, space + 1) == 0) { struct cache_line* node = malloc(sizeof(struct cache_line)); @@ -401,6 +401,43 @@ void wofi_write_cache(const gchar* mode, const gchar* cmd) { free(cache_path); } +void wofi_remove_cache(const gchar* mode, const gchar* cmd) { + char* cache_path = get_cache_path(mode); + if(access(cache_path, R_OK) == 0) { + struct wl_list lines; + wl_list_init(&lines); + + FILE* file = fopen(cache_path, "r"); + char* line = NULL; + size_t size = 0; + while(getline(&line, &size, file) != -1) { + char* space = strchr(line, ' '); + char* lf = strchr(line, '\n'); + if(lf != NULL) { + *lf = 0; + } + if(space == NULL || strcmp(cmd, space + 1) != 0) { + struct cache_line* node = malloc(sizeof(struct cache_line)); + node->line = utils_concat(2, line, "\n"); + wl_list_insert(&lines, &node->link); + } + } + free(line); + fclose(file); + + file = fopen(cache_path, "w"); + struct cache_line* node, *tmp; + wl_list_for_each_safe(node, tmp, &lines, link) { + fwrite(node->line, 1, strlen(node->line), file); + free(node->line); + wl_list_remove(&node->link); + free(node); + } + fclose(file); + } + free(cache_path); +} + struct wl_list* wofi_read_cache(char* mode) { char* cache_path = get_cache_path(mode); struct wl_list* cache = malloc(sizeof(struct wl_list));