aboutsummaryrefslogtreecommitdiffstats
path: root/src/fm.c
diff options
context:
space:
mode:
authorverdant <im@verdant.ee>2026-07-28 20:28:25 +0800
committerverdant <im@verdant.ee>2026-07-28 20:44:30 +0800
commit19e0828979724e409e7da545976d93f5c2e82381 (patch)
treeaa50b22a631efa19670be5e7d5ff8e1af3208ee8 /src/fm.c
parent9bffcafa9ae0c38103a8c64b3482bb099e792869 (diff)
downloadsf-19e0828979724e409e7da545976d93f5c2e82381.tar.gz
sf-19e0828979724e409e7da545976d93f5c2e82381.zip
Add preview path caching to prevent redundant I/O
Diffstat (limited to 'src/fm.c')
-rw-r--r--src/fm.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/src/fm.c b/src/fm.c
index 92526c3..c863cad 100644
--- a/src/fm.c
+++ b/src/fm.c
@@ -22,6 +22,7 @@
static magic_t g_magic_ctx = NULL;
static char *const utils[] = {"vi", "xdg-open"};
static char *const envs[] = {"SHELL", "EDITOR", "SF"};
+static char last_preview_path[PATH_MAX] = "";
bool need_redraw = true;
/* Function forward declarations */
@@ -201,6 +202,12 @@ detect_file_type(const char *filepath)
return desc ? strdup(desc) : strdup("unknown");
}
+static bool
+is_previewed_path(const char *path)
+{
+ return (strcmp(last_preview_path, path) == 0);
+}
+
void
fm_draw_file_stream(window *w, FILE *fp)
{
@@ -220,30 +227,57 @@ fm_preview_file(window *w, const char *path)
if (!w || !path)
return false;
- wclear(w->win);
-
- char *file_type = detect_file_type(path);
-
- if (strstr(file_type, "text") == NULL) {
- mvwprintw(w->win, 0, 0, "%s", file_type);
- free(file_type);
+ if (is_previewed_path(path))
return false;
- }
+ wclear(w->win);
+ char *file_type = detect_file_type(path);
FILE *fp = fopen(path, "r");
if (!fp) {
mvwprintw(w->win, 0, 0, "<Cannot open file>");
free(file_type);
return false;
+ } else if (strstr(file_type, "text")) {
+ fm_draw_file_stream(w, fp);
+ } else {
+ mvwprintw(w->win, 0, 0, "%s", file_type);
}
- fm_draw_file_stream(w, fp);
+ snprintf(last_preview_path, sizeof(last_preview_path), "%s", path);
fclose(fp);
free(file_type);
return true;
}
+bool
+fm_preview_dir(fm_info *info, const char *path)
+{
+ if (!info)
+ return false;
+
+ if (is_previewed_path(path))
+ return false;
+
+ window *right = info->windows[FM_PANE_RIGHT];
+ int right_height = info->windows[FM_PANE_RIGHT]->height;
+
+ wclear(right->win);
+
+ file_list *new_list = info->next;
+ new_list = fm_getdir(new_list, path);
+ if (new_list) {
+ info->next = new_list;
+ fm_draw_entries(right, new_list, -1, 0, right_height);
+ } else {
+ return false;
+ }
+
+ snprintf(last_preview_path, sizeof(last_preview_path), "%s", path);
+
+ return true;
+}
+
void
fm_draw_entries(window *window, file_list *list, size_t cursor, int top,
int bottom)