fe
terminal file explorer and picker
git clone https://9o.is/git/fe.git
commit a746585ada39bfc628f3a371644482701cfb0491 parent 92006568f975ff5e11e6c6170d227e97124ab2e6 Author: Jul <jul@9o.is> Date: Tue, 27 Jan 2026 03:55:50 -0500 add 'D' keybinding to create directory Diffstat:
| M | config.def.h | | | 1 | + |
| M | entries.c | | | 12 | ++++++++++++ |
| M | entries.h | | | 1 | + |
| M | tty_interface.c | | | 49 | ++++++++++++++++++++++++++++++++++++------------- |
| M | tty_interface.h | | | 1 | + |
5 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/config.def.h b/config.def.h @@ -39,6 +39,7 @@ static const keybinding_t keybindings[] = { {KEY('~'), action_home, NULL}, /* ~ */ {KEY('.'), action_togglehidden, NULL}, /* . */ {KEY('%'), action_create, NULL}, /* % (create) */ + {KEY('D'), action_mkdir, NULL}, /* D (mkdir) */ {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 @@ -409,6 +409,18 @@ int entries_create_file(entries_t *entries, const char *filename) { return 0; } +int entries_create_dir(entries_t *entries, const char *dirname) { + char fullpath[PATH_MAX]; + + mkpath(entries->path, (char *)dirname, fullpath, sizeof(fullpath)); + + if (mkdir(fullpath, 0755) == -1) { + return -1; + } + + 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) { diff --git a/entries.h b/entries.h @@ -37,6 +37,7 @@ 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_create_dir(entries_t *entries, const char *dirname); int entries_find_file(entries_t *entries, const char *filename); #endif diff --git a/tty_interface.c b/tty_interface.c @@ -322,15 +322,14 @@ 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; +static int prompt_input(tty_interface_t *state, const char *prompt, char *buffer, size_t size) { tty_t *tty = state->tty; + int len = 0; tty_unhide_cursor(tty); tty_setcol(tty, 0); - tty_printf(tty, "Enter filename: "); + tty_clearline(tty); + tty_printf(tty, "%s", prompt); tty_flush(tty); for (;;) { @@ -338,24 +337,30 @@ void action_create(tty_interface_t *state, const char *argv) { if (c == '\r' || c == '\n') { break; } else if (c == '\x1b') { - filename[0] = '\0'; - break; + buffer[0] = '\0'; + return -1; } else if (c == '\x7f' || c == '\b') { if (len > 0) { len--; - filename[len] = '\0'; + buffer[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'; + } else if (len < (int)size - 1 && c >= ' ' && c <= '~') { + buffer[len++] = c; + buffer[len] = '\0'; tty_printf(tty, "%c", c); tty_flush(tty); } } + return len; +} - if (filename[0] != '\0') { +void action_create(tty_interface_t *state, const char *argv) { + (void)argv; + char filename[PATH_MAX] = ""; + + if (prompt_input(state, "Create file: ", filename, sizeof(filename)) > 0) { if (entries_create_file(state->entries, filename) == 0) { entries_setpath(state->entries, state->entries->path); int index = entries_find_file(state->entries, filename); @@ -365,7 +370,25 @@ void action_create(tty_interface_t *state, const char *argv) { } } - tty_hide_cursor(tty); + tty_hide_cursor(state->tty); + draw(state); +} + +void action_mkdir(tty_interface_t *state, const char *argv) { + (void)argv; + char dirname[PATH_MAX] = ""; + + if (prompt_input(state, "Create directory: ", dirname, sizeof(dirname)) > 0) { + if (entries_create_dir(state->entries, dirname) == 0) { + entries_setpath(state->entries, state->entries->path); + int index = entries_find_file(state->entries, dirname); + if (index != -1) { + entries_position(state->entries, (size_t)index); + } + } + } + + tty_hide_cursor(state->tty); draw(state); } diff --git a/tty_interface.h b/tty_interface.h @@ -35,6 +35,7 @@ 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_mkdir(tty_interface_t *state, const char *argv); void action_exit(tty_interface_t *state, const char *argv); #endif