diff --git a/include/sway/commands.h b/include/sway/commands.h index 67fae5a607..c723bfe83b 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -142,6 +142,7 @@ sway_cmd cmd_fullscreen; sway_cmd cmd_gaps; sway_cmd cmd_hide_edge_borders; sway_cmd cmd_include; +sway_cmd cmd_include_one; sway_cmd cmd_inhibit_idle; sway_cmd cmd_input; sway_cmd cmd_seat; diff --git a/sway/commands.c b/sway/commands.c index 6f2649a29e..c7d8f8ed4f 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -103,6 +103,7 @@ static const struct cmd_handler handlers[] = { static const struct cmd_handler config_handlers[] = { { "default_orientation", cmd_default_orientation }, { "include", cmd_include }, + { "include_one", cmd_include_one}, { "swaybg_command", cmd_swaybg_command }, { "swaynag_command", cmd_swaynag_command }, { "workspace_layout", cmd_workspace_layout }, diff --git a/sway/commands/include_one.c b/sway/commands/include_one.c new file mode 100644 index 0000000000..d922f66265 --- /dev/null +++ b/sway/commands/include_one.c @@ -0,0 +1,89 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/config.h" +#include "list.h" +#include "log.h" +#include "unistd.h" +#include +#include +#include + +typedef struct { + char *name; + char *path; +} config_location_map; + +int compare_paths( const config_location_map* item, char* abspath) { + if (strcmp(item->name, basename(abspath))==0) { + return 0; + } + return -1; +} +void free_config_location_map(config_location_map *config_loc) { + free(config_loc->name); + free(config_loc->path); + free(config_loc); +} +void priority_configs(const char *path, const char *parent_dir, struct sway_config *config, list_t *locations) { + char *wd = getcwd(NULL, 0); + + if (chdir(parent_dir) < 0) { + sway_log(SWAY_ERROR, "failed to change working directory"); + goto cleanup; + } + + wordexp_t p; + if (wordexp(path, &p, 0) == 0) { + char **w = p.we_wordv; + size_t i; + config_location_map *config_loc = malloc(sizeof (config_location_map)); + for (i = 0; i < p.we_wordc; ++i) { + int index = list_seq_find(locations, (int (*)(const void *, const void *))compare_paths, w[i]); + char* matched_path = strdup(w[i]); + config_loc->name = strdup(basename(matched_path)); + config_loc->path = matched_path; + if (index == -1) { + list_add(locations, config_loc); + continue; + } + free_config_location_map(locations->items[index]); + locations->items[index] = config_loc; + } + + } + + wordfree(&p); + + if (chdir(wd) < 0) { + sway_log(SWAY_ERROR, "failed to change working directory"); + } +cleanup: + free(wd); +} + +struct cmd_results *cmd_include_one(int argc, char **argv) { + + struct cmd_results *error = NULL; + char *parent_path = strdup(config->current_config_path); + const char *parent_dir = dirname(parent_path); + list_t *locs = create_list(); + + if ((error = checkarg(argc, "include_one", EXPECTED_AT_LEAST, 1))) { + return error; + } + + for(int i=0; iitems; + for(int i=0; ilength; ++i) { + load_include_configs (locs_arr[i]->path, config, &config->swaynag_config_errors); + } + for (int i = 0; ilength; ++i) { + free_config_location_map(locs_arr[i]); + } + list_free(locs); + free(parent_path); + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/meson.build b/sway/meson.build index 5573d433e3..fbe160fc2b 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -72,6 +72,7 @@ sway_sources = files( 'commands/max_render_time.c', 'commands/opacity.c', 'commands/include.c', + 'commands/include_one.c', 'commands/input.c', 'commands/layout.c', 'commands/mode.c',