fe
terminal file explorer and picker
git clone https://9o.is/git/fe.git
commit fb854e640b1eb062712e54512481dd4ca4e16aa8 parent 53e2d88012681add15c52253a41fe1a1f087b21f Author: Jul <jul@9o.is> Date: Tue, 27 Jan 2026 03:12:13 -0500 add '%' keybinding to create file Diffstat:
| M | config.def.h | | | 1 | + |
| M | entries.c | | | 28 | ++++++++++++++++++++++++++-- |
| M | entries.h | | | 2 | ++ |
| M | tty_interface.c | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | tty_interface.h | | | 1 | + |
5 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h @@ -37,6 +37,7 @@ static const keybinding_t keybindings[] = { {KEY('G'), action_last, NULL}, /* G */ {KEY('~'), action_home, NULL}, /* ~ */ {KEY('.'), action_togglehidden, NULL}, /* . */ + {KEY('%'), action_create, NULL}, /* % (create) */ {KEY('d'), action_remove, NULL}, /* d (delete/remove) */ {KEY('p'), action_run, "less %s/%s"}, /* p (preview) */ {KEY('t'), action_run, "tmux new-window -b 'vis %s/%s'"}, /* edit new tab */ diff --git a/entries.c b/entries.c @@ -368,8 +368,8 @@ int entries_remove(entries_t *entries) { if (filetype(child_path) == S_IFDIR) { if (stack_top < 1024) { if (is_empty) { - strlcpy(stack[stack_top], current_path, PATH_MAX); - stack_top++; + strlcpy(stack[stack_top], current_path, PATH_MAX); + stack_top++; } strlcpy(stack[stack_top], child_path, PATH_MAX); stack_top++; @@ -393,3 +393,27 @@ int entries_remove(entries_t *entries) { return 0; } + +int entries_create_file(entries_t *entries, const char *filename) { + char fullpath[PATH_MAX]; + int fd; + + mkpath(entries->path, (char *)filename, fullpath, sizeof(fullpath)); + + fd = open(fullpath, O_CREAT | O_EXCL | O_WRONLY, 0644); + if (fd == -1) { + return -1; + } + + close(fd); + return 0; +} + +int entries_find_file(entries_t *entries, const char *filename) { + for (size_t i = 0; i < entries->size; i++) { + if (strcmp(entries->dents[i].name, filename) == 0) { + return i; + } + } + return -1; +} diff --git a/entries.h b/entries.h @@ -35,5 +35,7 @@ int entries_select(entries_t *entries); struct entry *entries_item(entries_t *entries, size_t n); struct entry *entries_selected(entries_t *entries); int entries_remove(entries_t *entries); +int entries_create_file(entries_t *entries, const char *filename); +int entries_find_file(entries_t *entries, const char *filename); #endif diff --git a/tty_interface.c b/tty_interface.c @@ -316,6 +316,54 @@ void action_remove(tty_interface_t *state, const char *argv) { draw(state); } +void action_create(tty_interface_t *state, const char *argv) { + (void)argv; + char filename[PATH_MAX] = ""; + int len = 0; + tty_t *tty = state->tty; + + tty_unhide_cursor(tty); + tty_setcol(tty, 0); + tty_printf(tty, "Enter filename: "); + tty_flush(tty); + + for (;;) { + char c = tty_getchar(tty); + if (c == '\r' || c == '\n') { + break; + } else if (c == '\x1b') { + filename[0] = '\0'; + break; + } else if (c == '\x7f' || c == '\b') { + if (len > 0) { + len--; + filename[len] = '\0'; + tty_printf(tty, "\b \b"); + tty_flush(tty); + } + } else if (len < (int)sizeof(filename) - 1 && c >= ' ' && c <= '~') { + filename[len++] = c; + filename[len] = '\0'; + tty_printf(tty, "%c", c); + tty_flush(tty); + } + } + + if (filename[0] != '\0') { + if (entries_create_file(state->entries, filename) == 0) { + entries_setpath(state->entries, state->entries->path); + int index = entries_find_file(state->entries, filename); + if (index != -1) { + entries_position(state->entries, (size_t)index); + } + } + } + + tty_hide_cursor(tty); + draw(state); +} + + void action_exit(tty_interface_t *state, const char *argv) { (void)argv; clear(state); diff --git a/tty_interface.h b/tty_interface.h @@ -33,6 +33,7 @@ void action_togglehidden(tty_interface_t *state, const char *argv); void action_run(tty_interface_t *state, const char *argv); void action_setpath(tty_interface_t *state, const char *argv); void action_remove(tty_interface_t *state, const char *argv); +void action_create(tty_interface_t *state, const char *argv); void action_exit(tty_interface_t *state, const char *argv); #endif