Skip to content

Commit

Permalink
vis: allow boolean :set options to be toggled
Browse files Browse the repository at this point in the history
Boolean options can be toggled by appending `!` to the option name.

Close martanne#435
  • Loading branch information
martanne committed Dec 17, 2016
1 parent 19c4f8a commit cf5fc7f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
3 changes: 3 additions & 0 deletions man/vis.1
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,9 @@ to change the editor's behavior using the
command.
This section describes the options, their abbreviations and their
default values.
Boolean options can be toggled by appending
.Sy "!"
to the option name.
.Pp
In each entry below, the first part of the tag line is the full name
of the option, followed by any equivalent abbreviations.
Expand Down
42 changes: 29 additions & 13 deletions vis-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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];
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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;
Expand Down

0 comments on commit cf5fc7f

Please sign in to comment.