mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 22:48:34 +00:00
refactor(options): unify put_set(num|bool|string)
(#30993)
Problem: There are three separate functions for printing the `:set` command for an setting an option to a file descriptor. These functions are used when creating the session file for an option. Having a function for each type increase code duplication and also makes it harder to add logic for new option types. Solution: Replace `put_set(num|bool|string)` with a single `put_set` function which works for all option types, this reduces code duplication and also makes it trivial to add support for more option types in the future.
This commit is contained in:
@@ -4368,17 +4368,7 @@ int makeset(FILE *fd, int opt_flags, int local_only)
|
|||||||
cmd = "setlocal";
|
cmd = "setlocal";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_has_type(opt_idx, kOptValTypeBoolean)) {
|
|
||||||
if (put_setbool(fd, cmd, opt->fullname, *(int *)varp) == FAIL) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
} else if (option_has_type(opt_idx, kOptValTypeNumber)) {
|
|
||||||
if (put_setnum(fd, cmd, opt->fullname, (OptInt *)varp) == FAIL) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
} else { // string
|
|
||||||
bool do_endif = false;
|
bool do_endif = false;
|
||||||
|
|
||||||
// Don't set 'syntax' and 'filetype' again if the value is
|
// Don't set 'syntax' and 'filetype' again if the value is
|
||||||
// already right, avoids reloading the syntax file.
|
// already right, avoids reloading the syntax file.
|
||||||
if (opt->indir == PV_SYN || opt->indir == PV_FT) {
|
if (opt->indir == PV_SYN || opt->indir == PV_FT) {
|
||||||
@@ -4389,7 +4379,7 @@ int makeset(FILE *fd, int opt_flags, int local_only)
|
|||||||
}
|
}
|
||||||
do_endif = true;
|
do_endif = true;
|
||||||
}
|
}
|
||||||
if (put_setstring(fd, cmd, opt->fullname, (char **)varp, opt->flags) == FAIL) {
|
if (put_set(fd, cmd, opt_idx, varp) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (do_endif) {
|
if (do_endif) {
|
||||||
@@ -4401,7 +4391,6 @@ int makeset(FILE *fd, int opt_flags, int local_only)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4409,42 +4398,93 @@ int makeset(FILE *fd, int opt_flags, int local_only)
|
|||||||
/// 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
|
/// 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
|
||||||
int makefoldset(FILE *fd)
|
int makefoldset(FILE *fd)
|
||||||
{
|
{
|
||||||
if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL
|
if (put_set(fd, "setlocal", kOptFoldmethod, &curwin->w_p_fdm) == FAIL
|
||||||
|| put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldexpr, &curwin->w_p_fde) == FAIL
|
||||||
|| put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldmarker, &curwin->w_p_fmr) == FAIL
|
||||||
|| put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldignore, &curwin->w_p_fdi) == FAIL
|
||||||
|| put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldlevel, &curwin->w_p_fdl) == FAIL
|
||||||
|| put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldminlines, &curwin->w_p_fml) == FAIL
|
||||||
|| put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
|
|| put_set(fd, "setlocal", kOptFoldnestmax, &curwin->w_p_fdn) == FAIL
|
||||||
|| put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL) {
|
|| put_set(fd, "setlocal", kOptFoldenable, &curwin->w_p_fen) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int put_setstring(FILE *fd, char *cmd, char *name, char **valuep, uint64_t flags)
|
/// Print the ":set" command to set a single option to file.
|
||||||
|
///
|
||||||
|
/// @param fd File descriptor.
|
||||||
|
/// @param cmd Command name.
|
||||||
|
/// @param opt_idx Option index in options[] table.
|
||||||
|
/// @param varp Pointer to option variable.
|
||||||
|
///
|
||||||
|
/// @return FAIL on error, OK otherwise.
|
||||||
|
static int put_set(FILE *fd, char *cmd, OptIndex opt_idx, void *varp)
|
||||||
{
|
{
|
||||||
|
OptVal value = optval_from_varp(opt_idx, varp);
|
||||||
|
vimoption_T *opt = &options[opt_idx];
|
||||||
|
char *name = opt->fullname;
|
||||||
|
uint64_t flags = opt->flags;
|
||||||
|
|
||||||
|
if ((opt->indir & PV_BOTH) && varp != opt->var
|
||||||
|
&& optval_equal(value, get_option_unset_value(opt_idx))) {
|
||||||
|
// Processing unset local value of global-local option. Do nothing.
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (value.type) {
|
||||||
|
case kOptValTypeNil:
|
||||||
|
abort();
|
||||||
|
case kOptValTypeBoolean: {
|
||||||
|
assert(value.data.boolean != kNone);
|
||||||
|
bool value_bool = TRISTATE_TO_BOOL(value.data.boolean, false);
|
||||||
|
|
||||||
|
if (fprintf(fd, "%s %s%s", cmd, value_bool ? "" : "no", name) < 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kOptValTypeNumber: {
|
||||||
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
|
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptInt value_num = value.data.number;
|
||||||
|
|
||||||
|
OptInt wc;
|
||||||
|
if (wc_use_keyname(varp, &wc)) {
|
||||||
|
// print 'wildchar' and 'wildcharm' as a key name
|
||||||
|
if (fputs(get_special_key_name((int)wc, 0), fd) < 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
} else if (fprintf(fd, "%" PRId64, value_num) < 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kOptValTypeString: {
|
||||||
|
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *value_str = value.data.string.data;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
char *part = NULL;
|
char *part = NULL;
|
||||||
|
|
||||||
if (*valuep != NULL) {
|
if (value_str != NULL) {
|
||||||
if ((flags & kOptFlagExpand) != 0) {
|
if ((flags & kOptFlagExpand) != 0) {
|
||||||
size_t size = (size_t)strlen(*valuep) + 1;
|
size_t size = (size_t)strlen(value_str) + 1;
|
||||||
|
|
||||||
// replace home directory in the whole option value into "buf"
|
// replace home directory in the whole option value into "buf"
|
||||||
buf = xmalloc(size);
|
buf = xmalloc(size);
|
||||||
home_replace(NULL, *valuep, buf, size, false);
|
home_replace(NULL, value_str, buf, size, false);
|
||||||
|
|
||||||
// If the option value is longer than MAXPATHL, we need to append
|
// If the option value is longer than MAXPATHL, we need to append
|
||||||
// each comma separated part of the option separately, so that it
|
// each comma separated part of the option separately, so that it
|
||||||
// can be expanded when read back.
|
// can be expanded when read back.
|
||||||
if (size >= MAXPATHL && (flags & kOptFlagComma) != 0
|
if (size >= MAXPATHL && (flags & kOptFlagComma) != 0
|
||||||
&& vim_strchr(*valuep, ',') != NULL) {
|
&& vim_strchr(value_str, ',') != NULL) {
|
||||||
part = xmalloc(size);
|
part = xmalloc(size);
|
||||||
|
|
||||||
// write line break to clear the option, e.g. ':set rtp='
|
// write line break to clear the option, e.g. ':set rtp='
|
||||||
@@ -4472,52 +4512,24 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char **valuep, uint64_
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
} else if (put_escstr(fd, *valuep, 2) == FAIL) {
|
} else if (put_escstr(fd, value_str, 2) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (put_eol(fd) < 0) {
|
break;
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
fail:
|
fail:
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
xfree(part);
|
xfree(part);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int put_setnum(FILE *fd, char *cmd, char *name, OptInt *valuep)
|
|
||||||
{
|
|
||||||
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
OptInt wc;
|
|
||||||
if (wc_use_keyname(valuep, &wc)) {
|
|
||||||
// print 'wildchar' and 'wildcharm' as a key name
|
|
||||||
if (fputs(get_special_key_name((int)wc, 0), fd) < 0) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
} else if (fprintf(fd, "%" PRId64, (int64_t)(*valuep)) < 0) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
if (put_eol(fd) < 0) {
|
if (put_eol(fd) < 0) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int put_setbool(FILE *fd, char *cmd, char *name, int value)
|
|
||||||
{
|
|
||||||
if (value < 0) { // global/local option using global value
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
|
|
||||||
|| put_eol(fd) < 0) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get_varp_scope_from(vimoption_T *p, int scope, buf_T *buf, win_T *win)
|
void *get_varp_scope_from(vimoption_T *p, int scope, buf_T *buf, win_T *win)
|
||||||
{
|
{
|
||||||
if ((scope & OPT_GLOBAL) && p->indir != PV_NONE) {
|
if ((scope & OPT_GLOBAL) && p->indir != PV_NONE) {
|
||||||
|
Reference in New Issue
Block a user