diff --git a/sysmisc.c b/sysmisc.c index 4618538..b91eaad 100644 --- a/sysmisc.c +++ b/sysmisc.c @@ -5,6 +5,30 @@ #include <errno.h> #include <sys/stat.h> +static char const *const xdg_config_home_env = "XDG_CONFIG_HOME"; +static char const *const home_env = "HOME"; + +void expand_home_tilde(oso **path) { + oso *s = *path; + size_t n = osolen(s); + if (n < 2) + return; + if (osoc(s)[0] != '~' || osoc(s)[1] != '/') + return; + char const *homedir = getenv(home_env); + if (!homedir) + return; + size_t hlen = strlen(homedir); + osoensurecap(&s, n + hlen - 1); + if (!s) + goto done; + memmove((char *)s + hlen, (char *)s + 1, n); // includes '\0' + memcpy((char *)s, homedir, hlen); + osopokelen(s, n + hlen - 1); +done: + *path = s; +} + ORCA_NOINLINE Cboard_error cboard_copy(Glyph const *gbuffer, Usz field_height, Usz field_width, Usz rect_y, Usz rect_x, Usz rect_h, @@ -220,9 +244,6 @@ typedef enum { Conf_dir_no_home, } Conf_dir_error; -static char const *const xdg_config_home_env = "XDG_CONFIG_HOME"; -static char const *const home_env = "HOME"; - static Conf_dir_error try_get_conf_dir(oso **out) { char const *xdgcfgdir = getenv(xdg_config_home_env); if (xdgcfgdir) { diff --git a/sysmisc.h b/sysmisc.h index 453e56c..561a2c1 100644 --- a/sysmisc.h +++ b/sysmisc.h @@ -1,6 +1,9 @@ #pragma once #include "base.h" #include <stdio.h> // FILE cannot be forward declared +struct oso; + +void expand_home_tilde(struct oso **path); typedef enum { Cboard_error_none = 0, @@ -127,7 +130,7 @@ typedef struct { uint32_t stateflags; } Ezconf_w; -void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, - size_t buffercap, char const *conf_file_name); +void ezconf_w_start(Ezconf_w *ezcw, Ezconf_opt *optsbuffer, size_t buffercap, + char const *conf_file_name); void ezconf_w_addopt(Ezconf_w *ezcw, char const *key, intptr_t id); bool ezconf_w_step(Ezconf_w *ezcw); diff --git a/tui_main.c b/tui_main.c index 757d808..c92ffd7 100644 --- a/tui_main.c +++ b/tui_main.c @@ -3139,6 +3139,9 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) { switch (qform_id(qf)) { case Open_form_id: { oso *temp_name = get_nonempty_singular_form_text(qf); + if (!temp_name) + break; + expand_home_tilde(&temp_name); if (!temp_name) break; bool added_hist = undo_history_push(&t->ged.undo_hist, &t->ged.field,