diff options
-rw-r--r-- | include/list.h | 2 | ||||
-rw-r--r-- | sway.5.txt | 5 | ||||
-rw-r--r-- | sway/commands.c | 34 | ||||
-rw-r--r-- | sway/config.c | 65 | ||||
-rw-r--r-- | sway/list.c | 4 |
5 files changed, 73 insertions, 37 deletions
diff --git a/include/list.h b/include/list.h index 29b988aa..aff6800f 100644 --- a/include/list.h +++ b/include/list.h | |||
@@ -13,5 +13,7 @@ void list_add(list_t *list, void *item); | |||
13 | void list_insert(list_t *list, int index, void *item); | 13 | void list_insert(list_t *list, int index, void *item); |
14 | void list_del(list_t *list, int index); | 14 | void list_del(list_t *list, int index); |
15 | void list_cat(list_t *list, list_t *source); | 15 | void list_cat(list_t *list, list_t *source); |
16 | // See qsort | ||
17 | void list_sort(list_t *list, int compare(const void *left, const void *right)); | ||
16 | 18 | ||
17 | #endif | 19 | #endif |
@@ -85,6 +85,11 @@ Commands | |||
85 | Sets the layout mode of the focused container. _mode_ can be one of _splith_, | 85 | Sets the layout mode of the focused container. _mode_ can be one of _splith_, |
86 | _splitv_, or _toggle split_. | 86 | _splitv_, or _toggle split_. |
87 | 87 | ||
88 | **mode** <mode_name>:: | ||
89 | Switches to the given mode_name. the default mode is simply _default_. To | ||
90 | create a new mode in config append _{_ to this command, the following lines | ||
91 | will be keybinds for that mode, and _}_ on its own line to close the block. | ||
92 | |||
88 | **move** <left|right|up|down>:: | 93 | **move** <left|right|up|down>:: |
89 | Moves the focused container _left_, _right_, _up_, or _down_. | 94 | Moves the focused container _left_, _right_, _up_, or _down_. |
90 | 95 | ||
diff --git a/sway/commands.c b/sway/commands.c index e7ddfa71..44407bfa 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -139,8 +139,7 @@ static bool cmd_bindsym(int argc, char **argv) { | |||
139 | // TODO: Check if there are other commands with this key binding | 139 | // TODO: Check if there are other commands with this key binding |
140 | struct sway_mode *mode = config->current_mode; | 140 | struct sway_mode *mode = config->current_mode; |
141 | list_add(mode->bindings, binding); | 141 | list_add(mode->bindings, binding); |
142 | qsort(mode->bindings->items, mode->bindings->length, | 142 | list_sort(mode->bindings, bindsym_sort); |
143 | sizeof(mode->bindings->items[0]), bindsym_sort); | ||
144 | 143 | ||
145 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); | 144 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); |
146 | return true; | 145 | return true; |
@@ -828,14 +827,36 @@ static bool cmd_scratchpad(int argc, char **argv) { | |||
828 | } | 827 | } |
829 | } | 828 | } |
830 | 829 | ||
830 | // sort in order of longest->shortest | ||
831 | static int compare_set(const void *_l, const void *_r) { | ||
832 | struct sway_variable * const *l = _l; | ||
833 | struct sway_variable * const *r = _r; | ||
834 | return strlen((*r)->name) - strlen((*l)->name); | ||
835 | } | ||
836 | |||
831 | static bool cmd_set(int argc, char **argv) { | 837 | static bool cmd_set(int argc, char **argv) { |
832 | if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) { | 838 | if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) { |
833 | return false; | 839 | return false; |
834 | } | 840 | } |
835 | struct sway_variable *var = malloc(sizeof(struct sway_variable)); | 841 | struct sway_variable *var = NULL; |
836 | var->name = strdup(argv[0]); | 842 | // Find old variable if it exists |
843 | int i; | ||
844 | for (i = 0; i < config->symbols->length; ++i) { | ||
845 | var = config->symbols->items[i]; | ||
846 | if (strcmp(var->name, argv[0]) == 0) { | ||
847 | break; | ||
848 | } | ||
849 | var = NULL; | ||
850 | } | ||
851 | if (var) { | ||
852 | free(var->value); | ||
853 | } else { | ||
854 | var = malloc(sizeof(struct sway_variable)); | ||
855 | var->name = strdup(argv[0]); | ||
856 | list_add(config->symbols, var); | ||
857 | list_sort(config->symbols, compare_set); | ||
858 | } | ||
837 | var->value = strdup(argv[1]); | 859 | var->value = strdup(argv[1]); |
838 | list_add(config->symbols, var); | ||
839 | return true; | 860 | return true; |
840 | } | 861 | } |
841 | 862 | ||
@@ -1048,7 +1069,8 @@ bool handle_command(char *exec) { | |||
1048 | bool exec_success = false; | 1069 | bool exec_success = false; |
1049 | if (handler) { | 1070 | if (handler) { |
1050 | int i; | 1071 | int i; |
1051 | for (i = 1; i < argc; ++i) { | 1072 | // Skip var replacement for first value of cmd_set |
1073 | for (i = (handler->handle == cmd_set ? 2 : 1); i < argc; ++i) { | ||
1052 | argv[i] = do_var_replacement(argv[i]); | 1074 | argv[i] = do_var_replacement(argv[i]); |
1053 | } | 1075 | } |
1054 | exec_success = handler->handle(argc - 1, argv + 1); | 1076 | exec_success = handler->handle(argc - 1, argv + 1); |
diff --git a/sway/config.c b/sway/config.c index 6c8fe8c1..daaedeed 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -230,19 +230,17 @@ bool read_config(FILE *file, bool is_active) { | |||
230 | char *line; | 230 | char *line; |
231 | while (!feof(file)) { | 231 | while (!feof(file)) { |
232 | line = read_line(file); | 232 | line = read_line(file); |
233 | line = strip_whitespace(line); | ||
234 | line = strip_comments(line); | 233 | line = strip_comments(line); |
235 | if (line[0] == '\0') { | 234 | list_t *args = split_string(line, whitespace); |
236 | goto _continue; | 235 | if (!args->length) { |
236 | goto cleanup; | ||
237 | } | 237 | } |
238 | if (line[0] == '}') { | 238 | //TODO make this better, it only handles modes right now, and very |
239 | //simply at that | ||
240 | if (strncmp(args->items[0], "}", 1) == 0) { | ||
239 | config->current_mode = default_mode; | 241 | config->current_mode = default_mode; |
240 | goto _continue; | 242 | goto cleanup; |
241 | } | 243 | } |
242 | |||
243 | // Any command which would require wlc to be initialized | ||
244 | // should be queued for later execution | ||
245 | list_t *args = split_string(line, whitespace); | ||
246 | struct cmd_handler *handler; | 244 | struct cmd_handler *handler; |
247 | if ((handler = find_handler(args->items[0]))) { | 245 | if ((handler = find_handler(args->items[0]))) { |
248 | if (handler->config_type == CMD_KEYBIND) { | 246 | if (handler->config_type == CMD_KEYBIND) { |
@@ -259,9 +257,8 @@ bool read_config(FILE *file, bool is_active) { | |||
259 | } else { | 257 | } else { |
260 | sway_log(L_ERROR, "Invalid command ``%s''", line); | 258 | sway_log(L_ERROR, "Invalid command ``%s''", line); |
261 | } | 259 | } |
260 | cleanup: | ||
262 | free_flat_list(args); | 261 | free_flat_list(args); |
263 | |||
264 | _continue: | ||
265 | free(line); | 262 | free(line); |
266 | } | 263 | } |
267 | 264 | ||
@@ -277,27 +274,33 @@ _continue: | |||
277 | } | 274 | } |
278 | 275 | ||
279 | char *do_var_replacement(char *str) { | 276 | char *do_var_replacement(char *str) { |
280 | // TODO: Handle escaping $ and using $ in string literals | ||
281 | int i; | 277 | int i; |
282 | for (i = 0; str[i]; ++i) { | 278 | char *find = str; |
283 | if (str[i] == '$') { | 279 | while ((find = strchr(find, '$'))) { |
284 | // Try for match (note: this could be faster) | 280 | // Skip if escaped. |
285 | int j; | 281 | if (find > str + 1 && find[-1] == '\\') { |
286 | for (j = 0; j < config->symbols->length; ++j) { | 282 | if (!(find > str + 2 && find[-2] == '\\')) { |
287 | struct sway_variable *var = config->symbols->items[j]; | 283 | continue; |
288 | if (strstr(str + i, var->name) == str + i) { | 284 | } |
289 | // Match, do replacement | 285 | } |
290 | char *new_string = malloc( | 286 | // Find matching variable |
291 | strlen(str) - | 287 | for (i = 0; i < config->symbols->length; ++i) { |
292 | strlen(var->name) + | 288 | struct sway_variable *var = config->symbols->items[i]; |
293 | strlen(var->value) + 1); | 289 | int vnlen = strlen(var->name); |
294 | strncpy(new_string, str, i); | 290 | if (strncmp(find, var->name, vnlen) == 0) { |
295 | new_string[i] = 0; | 291 | int vvlen = strlen(var->value); |
296 | strcat(new_string, var->value); | 292 | char *newstr = malloc(strlen(str) - vnlen + vvlen + 1); |
297 | strcat(new_string, str + i + strlen(var->name)); | 293 | char *newptr = newstr; |
298 | free(str); | 294 | int offset = find - str; |
299 | str = new_string; | 295 | strncpy(newptr, str, offset); |
300 | } | 296 | newptr += offset; |
297 | strncpy(newptr, var->value, vvlen); | ||
298 | newptr += vvlen; | ||
299 | strcpy(newptr, find + vnlen); | ||
300 | free(str); | ||
301 | str = newstr; | ||
302 | find = str + offset + vvlen; | ||
303 | break; | ||
301 | } | 304 | } |
302 | } | 305 | } |
303 | } | 306 | } |
diff --git a/sway/list.c b/sway/list.c index 1be1e17c..45efc16f 100644 --- a/sway/list.c +++ b/sway/list.c | |||
@@ -49,3 +49,7 @@ void list_cat(list_t *list, list_t *source) { | |||
49 | list_add(list, source->items[i]); | 49 | list_add(list, source->items[i]); |
50 | } | 50 | } |
51 | } | 51 | } |
52 | |||
53 | void list_sort(list_t *list, int compare(const void *left, const void *right)) { | ||
54 | qsort(list->items, list->length, sizeof(void *), compare); | ||
55 | } | ||