aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c34
-rw-r--r--sway/config.c65
-rw-r--r--sway/list.c4
3 files changed, 66 insertions, 37 deletions
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) {
// TODO: Check if there are other commands with this key binding
struct sway_mode *mode = config->current_mode;
list_add(mode->bindings, binding);
- qsort(mode->bindings->items, mode->bindings->length,
- sizeof(mode->bindings->items[0]), bindsym_sort);
+ list_sort(mode->bindings, bindsym_sort);
sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command);
return true;
@@ -828,14 +827,36 @@ static bool cmd_scratchpad(int argc, char **argv) {
}
}
+// sort in order of longest->shortest
+static int compare_set(const void *_l, const void *_r) {
+ struct sway_variable * const *l = _l;
+ struct sway_variable * const *r = _r;
+ return strlen((*r)->name) - strlen((*l)->name);
+}
+
static bool cmd_set(int argc, char **argv) {
if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) {
return false;
}
- struct sway_variable *var = malloc(sizeof(struct sway_variable));
- var->name = strdup(argv[0]);
+ struct sway_variable *var = NULL;
+ // Find old variable if it exists
+ int i;
+ for (i = 0; i < config->symbols->length; ++i) {
+ var = config->symbols->items[i];
+ if (strcmp(var->name, argv[0]) == 0) {
+ break;
+ }
+ var = NULL;
+ }
+ if (var) {
+ free(var->value);
+ } else {
+ var = malloc(sizeof(struct sway_variable));
+ var->name = strdup(argv[0]);
+ list_add(config->symbols, var);
+ list_sort(config->symbols, compare_set);
+ }
var->value = strdup(argv[1]);
- list_add(config->symbols, var);
return true;
}
@@ -1048,7 +1069,8 @@ bool handle_command(char *exec) {
bool exec_success = false;
if (handler) {
int i;
- for (i = 1; i < argc; ++i) {
+ // Skip var replacement for first value of cmd_set
+ for (i = (handler->handle == cmd_set ? 2 : 1); i < argc; ++i) {
argv[i] = do_var_replacement(argv[i]);
}
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) {
char *line;
while (!feof(file)) {
line = read_line(file);
- line = strip_whitespace(line);
line = strip_comments(line);
- if (line[0] == '\0') {
- goto _continue;
+ list_t *args = split_string(line, whitespace);
+ if (!args->length) {
+ goto cleanup;
}
- if (line[0] == '}') {
+ //TODO make this better, it only handles modes right now, and very
+ //simply at that
+ if (strncmp(args->items[0], "}", 1) == 0) {
config->current_mode = default_mode;
- goto _continue;
+ goto cleanup;
}
-
- // Any command which would require wlc to be initialized
- // should be queued for later execution
- list_t *args = split_string(line, whitespace);
struct cmd_handler *handler;
if ((handler = find_handler(args->items[0]))) {
if (handler->config_type == CMD_KEYBIND) {
@@ -259,9 +257,8 @@ bool read_config(FILE *file, bool is_active) {
} else {
sway_log(L_ERROR, "Invalid command ``%s''", line);
}
+ cleanup:
free_flat_list(args);
-
-_continue:
free(line);
}
@@ -277,27 +274,33 @@ _continue:
}
char *do_var_replacement(char *str) {
- // TODO: Handle escaping $ and using $ in string literals
int i;
- for (i = 0; str[i]; ++i) {
- if (str[i] == '$') {
- // Try for match (note: this could be faster)
- int j;
- for (j = 0; j < config->symbols->length; ++j) {
- struct sway_variable *var = config->symbols->items[j];
- if (strstr(str + i, var->name) == str + i) {
- // Match, do replacement
- char *new_string = malloc(
- strlen(str) -
- strlen(var->name) +
- strlen(var->value) + 1);
- strncpy(new_string, str, i);
- new_string[i] = 0;
- strcat(new_string, var->value);
- strcat(new_string, str + i + strlen(var->name));
- free(str);
- str = new_string;
- }
+ char *find = str;
+ while ((find = strchr(find, '$'))) {
+ // Skip if escaped.
+ if (find > str + 1 && find[-1] == '\\') {
+ if (!(find > str + 2 && find[-2] == '\\')) {
+ continue;
+ }
+ }
+ // Find matching variable
+ for (i = 0; i < config->symbols->length; ++i) {
+ struct sway_variable *var = config->symbols->items[i];
+ int vnlen = strlen(var->name);
+ if (strncmp(find, var->name, vnlen) == 0) {
+ int vvlen = strlen(var->value);
+ char *newstr = malloc(strlen(str) - vnlen + vvlen + 1);
+ char *newptr = newstr;
+ int offset = find - str;
+ strncpy(newptr, str, offset);
+ newptr += offset;
+ strncpy(newptr, var->value, vvlen);
+ newptr += vvlen;
+ strcpy(newptr, find + vnlen);
+ free(str);
+ str = newstr;
+ find = str + offset + vvlen;
+ break;
}
}
}
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) {
list_add(list, source->items[i]);
}
}
+
+void list_sort(list_t *list, int compare(const void *left, const void *right)) {
+ qsort(list->items, list->length, sizeof(void *), compare);
+}