aboutsummaryrefslogtreecommitdiff
path: root/vis-cmds.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-12-17 12:24:36 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-12-17 12:24:36 +0100
commitcf5fc7f044a83474a1ed46a70b4813d0c838c35f (patch)
tree7e742b386b209df61ba06ffa681fa6be1860e441 /vis-cmds.c
parent19c4f8aa853bca99da406dab96b09ca85a29dbcd (diff)
downloadvis-cf5fc7f044a83474a1ed46a70b4813d0c838c35f.tar.gz
vis-cf5fc7f044a83474a1ed46a70b4813d0c838c35f.tar.xz
vis: allow boolean :set options to be toggled
Boolean options can be toggled by appending `!` to the option name. Close #435
Diffstat (limited to 'vis-cmds.c')
-rw-r--r--vis-cmds.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/vis-cmds.c b/vis-cmds.c
index 0947e72..606699c 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -79,24 +79,40 @@ static bool parse_bool(const char *s, bool *outval) {
static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
- if (!argv[1] || argv[3]) {
+ if (!argv[1] || !argv[1][0] || argv[3]) {
vis_info_show(vis, "Expecting: set option [value]");
return false;
}
- OptionDef *opt = map_closest(vis->options, argv[1]);
- if (!opt)
- opt = map_closest(vis->options, argv[1]);
+ char name[256];
+ strncpy(name, argv[1], sizeof(name)-1);
+ char *lastchar = &name[strlen(name)-1];
+ bool toggle = (*lastchar == '!');
+ if (toggle)
+ *lastchar = '\0';
+
+ OptionDef *opt = map_closest(vis->options, name);
if (!opt) {
- vis_info_show(vis, "Unknown option: `%s'", argv[1]);
+ vis_info_show(vis, "Unknown option: `%s'", name);
return false;
}
if (!win && (opt->flags & OPTION_FLAG_WINDOW)) {
- vis_info_show(vis, "Need active window for :set %s", argv[1]);
+ vis_info_show(vis, "Need active window for `:set %s'", name);
return false;
}
+ if (toggle) {
+ if (opt->type != OPTION_TYPE_BOOL) {
+ vis_info_show(vis, "Only boolean options can be toggled");
+ return false;
+ }
+ if (argv[2]) {
+ vis_info_show(vis, "Can not specify option value when toggling");
+ return false;
+ }
+ }
+
Arg arg;
switch (opt->type) {
case OPTION_TYPE_STRING:
@@ -108,7 +124,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
break;
case OPTION_TYPE_BOOL:
if (!argv[2]) {
- arg.b = true;
+ arg.b = !toggle;
} else if (!parse_bool(argv[2], &arg.b)) {
vis_info_show(vis, "Expecting boolean option value not: `%s'", argv[2]);
return false;
@@ -163,10 +179,10 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
break;
}
case OPTION_EXPANDTAB:
- vis->expandtab = arg.b;
+ vis->expandtab = toggle ? !vis->expandtab : arg.b;
break;
case OPTION_AUTOINDENT:
- vis->autoindent = arg.b;
+ vis->autoindent = toggle ? !vis->autoindent : arg.b;
break;
case OPTION_TABWIDTH:
tabwidth_set(vis, arg.i);
@@ -198,7 +214,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
[OPTION_SHOW_NEWLINES] = UI_OPTION_SYMBOL_EOL,
};
int flags = view_options_get(win->view);
- if (arg.b)
+ if (arg.b || (toggle && !(flags & values[opt_index])))
flags |= values[opt_index];
else
flags &= ~values[opt_index];
@@ -207,7 +223,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
}
case OPTION_NUMBER: {
enum UiOption opt = view_options_get(win->view);
- if (arg.b) {
+ if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_ABSOLUTE))) {
opt &= ~UI_OPTION_LINE_NUMBERS_RELATIVE;
opt |= UI_OPTION_LINE_NUMBERS_ABSOLUTE;
} else {
@@ -218,7 +234,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
}
case OPTION_NUMBER_RELATIVE: {
enum UiOption opt = view_options_get(win->view);
- if (arg.b) {
+ if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_RELATIVE))) {
opt &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE;
opt |= UI_OPTION_LINE_NUMBERS_RELATIVE;
} else {
@@ -229,7 +245,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
}
case OPTION_CURSOR_LINE: {
enum UiOption opt = view_options_get(win->view);
- if (arg.b)
+ if (arg.b || (toggle && !(opt & UI_OPTION_CURSOR_LINE)))
opt |= UI_OPTION_CURSOR_LINE;
else
opt &= ~UI_OPTION_CURSOR_LINE;