From 4d48aca5f3c92d9c01282cd40b8d3b2c959bdac6 Mon Sep 17 00:00:00 2001 From: Konstantin Pospelov Date: Sun, 23 Jun 2024 10:50:45 +0200 Subject: [PATCH] Implement an include option Fixes #523 --- config.c | 46 ++++++++++++++++++++++++++++++---------------- doc/mako.5.scd | 6 ++++++ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/config.c b/config.c index ff7e7db..70be717 100644 --- a/config.c +++ b/config.c @@ -486,6 +486,25 @@ bool apply_superset_style( return true; } +static char *expand_config_path(const char *path) { + if (strncmp(path, "/", 1) == 0) { + return strdup(path); + } + + if (strncmp(path, "~/", 2) != 0) { + fprintf(stderr, "Config path must start with / or ~/\n"); + return NULL; + } + + const char *home = getenv("HOME"); + if (home == NULL) { + fprintf(stderr, "HOME env var not set\n"); + return NULL; + } + + return mako_asprintf("%s/%s", home, path + 2); +} + static bool apply_config_option(struct mako_config *config, const char *name, const char *value) { if (strcmp(name, "sort") == 0) { @@ -507,6 +526,9 @@ static bool apply_config_option(struct mako_config *config, const char *name, return true; } else if (strcmp(name, "max-history") == 0) { return parse_int(value, &config->max_history); + } else if (strcmp(name, "include") == 0) { + char *path = expand_config_path(value); + return path && load_config_file(config, path) == 0; } return false; @@ -699,7 +721,7 @@ static bool file_exists(const char *path) { return path && access(path, R_OK) != -1; } -static char *get_config_path(void) { +static char *get_default_config_path() { const char *home = getenv("HOME"); if (home == NULL) { fprintf(stderr, "HOME env var not set\n"); @@ -736,17 +758,7 @@ static char *get_config_path(void) { return found_path; } -int load_config_file(struct mako_config *config, char *config_arg) { - char *path = NULL; - if (config_arg == NULL) { - path = get_config_path(); - if (!path) { - return 0; - } - } else { - path = config_arg; - } - +int load_config_file(struct mako_config *config, char *path) { FILE *f = fopen(path, "r"); if (!f) { fprintf(stderr, "Unable to open %s for reading\n", path); @@ -814,7 +826,6 @@ int load_config_file(struct mako_config *config, char *config_arg) { valid_option = apply_config_option(config, line, eq + 1); } - if (!valid_option) { fprintf(stderr, "[%s:%d] Failed to parse option '%s'\n", base, lineno, line); @@ -903,9 +914,12 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) { return opt_status; } - int config_status = load_config_file(config, config_arg); - if (config_status < 0) { - return -1; + char *config_path = config_arg ? config_arg : get_default_config_path(); + if (config_path) { + int config_status = load_config_file(config, config_path); + if (config_status < 0) { + return -1; + } } optind = 1; diff --git a/doc/mako.5.scd b/doc/mako.5.scd index f62dc1c..91378ba 100644 --- a/doc/mako.5.scd +++ b/doc/mako.5.scd @@ -29,6 +29,12 @@ Empty lines and lines that begin with # are ignored. Default: -time +*include*=_config path_ + Includes a config at the specified path. The path must be absolute + or otherwise start with ~/. + + Default: none + # BINDING OPTIONS Bindings allow one to perform an action when an event is triggered.