fix(options): better handling of empty values

Problem:

Whether an option is allowed to be empty isn't well defined and
isn't properly checked.

Solution:

- For non-list string options, explicitly check the option value
  if it is empty.
- Annotate non-list string options that can accept an empty value.
  - Adjust command completion to ignore the empty value.
- Render values in Lua meta files
This commit is contained in:
Lewis Russell
2025-01-10 10:20:43 +00:00
committed by Lewis Russell
parent cb7b4e2962
commit 34e2185022
9 changed files with 72 additions and 42 deletions

View File

@@ -395,7 +395,9 @@ static int expand_set_opt_string(optexpand_T *args, const char **values, size_t
}
for (const char **val = values; *val != NULL; val++) {
if (include_orig_val && *option_val != NUL) {
if (**val == NUL) {
continue; // Ignore empty
} else if (include_orig_val && *option_val != NUL) {
if (strcmp(*val, option_val) == 0) {
continue;
}
@@ -1091,7 +1093,7 @@ int expand_set_cursorlineopt(optexpand_T *args, int *numMatches, char ***matches
/// The 'debug' option is changed.
const char *did_set_debug(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_debug, opt_debug_values, false);
return did_set_opt_strings(p_debug, opt_debug_values, true);
}
int expand_set_debug(optexpand_T *args, int *numMatches, char ***matches)
@@ -2545,7 +2547,7 @@ int expand_set_winhighlight(optexpand_T *args, int *numMatches, char ***matches)
/// @param list when true: accept a list of values
///
/// @return OK for correct value, FAIL otherwise. Empty is always OK.
static int check_opt_strings(char *val, const char **values, int list)
static int check_opt_strings(char *val, const char **values, bool list)
{
return opt_strings_flags(val, values, NULL, list);
}
@@ -2562,7 +2564,10 @@ static int opt_strings_flags(const char *val, const char **values, unsigned *fla
{
unsigned new_flags = 0;
while (*val) {
// If not list and val is empty, then force one iteration of the while loop
bool iter_one = (*val == NUL) && !list;
while (*val || iter_one) {
for (unsigned i = 0;; i++) {
if (values[i] == NULL) { // val not found in values[]
return FAIL;
@@ -2577,6 +2582,9 @@ static int opt_strings_flags(const char *val, const char **values, unsigned *fla
break; // check next item in val list
}
}
if (iter_one) {
break;
}
}
if (flagp != NULL) {
*flagp = new_flags;