Skip to content

Commit ea14741

Browse files
feat: validate all option types (#2414)
* refactor: follow config structure for `ACCEPTED_TYPES` * Bug fix * Fix check for default values * Reduce error notifications verbosity * Address issues introduced previously * stylua --------- Co-authored-by: Alexander Courtis <[email protected]>
1 parent 914a686 commit ea14741

File tree

1 file changed

+61
-22
lines changed

1 file changed

+61
-22
lines changed

lua/nvim-tree.lua

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -621,14 +621,31 @@ local FIELD_SKIP_VALIDATE = {
621621
open_win_config = true,
622622
}
623623

624-
local FIELD_OVERRIDE_TYPECHECK = {
625-
width = { string = true, ["function"] = true, number = true, ["table"] = true },
626-
max = { string = true, ["function"] = true, number = true },
627-
min = { string = true, ["function"] = true, number = true },
628-
on_attach = { ["function"] = true, string = true },
629-
sorter = { ["function"] = true, string = true },
630-
root_folder_label = { ["function"] = true, string = true, boolean = true },
631-
picker = { ["function"] = true, string = true },
624+
local ACCEPTED_TYPES = {
625+
on_attach = { "function", "string" },
626+
sort = {
627+
sorter = { "function", "string" },
628+
},
629+
view = {
630+
width = {
631+
"string",
632+
"function",
633+
"number",
634+
"table",
635+
min = { "string", "function", "number" },
636+
max = { "string", "function", "number" },
637+
},
638+
},
639+
renderer = {
640+
root_folder_label = { "function", "string", "boolean" },
641+
},
642+
actions = {
643+
open_file = {
644+
window_picker = {
645+
picker = { "function", "string" },
646+
},
647+
},
648+
},
632649
}
633650

634651
local ACCEPTED_STRINGS = {
@@ -653,43 +670,65 @@ local ACCEPTED_STRINGS = {
653670
local function validate_options(conf)
654671
local msg
655672

656-
local function validate(user, def, strs, prefix)
657-
-- only compare tables with contents that are not integer indexed
658-
if type(user) ~= "table" or type(def) ~= "table" or not next(def) or type(next(def)) == "number" then
673+
local function validate(user, def, strs, types, prefix)
674+
-- if user's option is not a table there is nothing to do
675+
if type(user) ~= "table" then
659676
return
660677
end
661678

679+
-- only compare tables with contents that are not integer indexed
680+
if type(def) ~= "table" or not next(def) or type(next(def)) == "number" then
681+
-- unless the field can be a table (and is not a table in default config)
682+
if vim.tbl_contains(types, "table") then
683+
-- use a dummy default to allow all checks
684+
def = {}
685+
else
686+
return
687+
end
688+
end
689+
662690
for k, v in pairs(user) do
663691
if not FIELD_SKIP_VALIDATE[k] then
664692
local invalid
665-
local override_typecheck = FIELD_OVERRIDE_TYPECHECK[k] or {}
666-
if def[k] == nil then
693+
694+
if def[k] == nil and types[k] == nil then
667695
-- option does not exist
668-
invalid = string.format("[NvimTree] unknown option: %s%s", prefix, k)
669-
elseif type(v) ~= type(def[k]) and not override_typecheck[type(v)] then
670-
-- option is of the wrong type and is not a function
671-
invalid =
672-
string.format("[NvimTree] invalid option: %s%s expected: %s actual: %s", prefix, k, type(def[k]), type(v))
696+
invalid = string.format("Unknown option: %s%s", prefix, k)
697+
elseif type(v) ~= type(def[k]) then
698+
local expected
699+
700+
if types[k] and #types[k] > 0 then
701+
if not vim.tbl_contains(types[k], type(v)) then
702+
expected = table.concat(types[k], "|")
703+
end
704+
else
705+
expected = type(def[k])
706+
end
707+
708+
if expected then
709+
-- option is of the wrong type
710+
invalid = string.format("Invalid option: %s%s. Expected %s, got %s", prefix, k, expected, type(v))
711+
end
673712
elseif type(v) == "string" and strs[k] and not vim.tbl_contains(strs[k], v) then
674713
-- option has type `string` but value is not accepted
675-
invalid = string.format("[NvimTree] invalid value for field %s%s: '%s'", prefix, k, v)
714+
invalid = string.format("Invalid value for field %s%s: '%s'", prefix, k, v)
676715
end
677716

678717
if invalid then
679718
if msg then
680719
msg = string.format("%s | %s", msg, invalid)
681720
else
682-
msg = string.format("%s", invalid)
721+
msg = string.format("[NvimTree] %s", invalid)
683722
end
684723
user[k] = nil
685724
else
686-
validate(v, def[k], strs[k] or {}, prefix .. k .. ".")
725+
validate(v, def[k], strs[k] or {}, types[k] or {}, prefix .. k .. ".")
687726
end
688727
end
689728
end
690729
end
691730

692-
validate(conf, DEFAULT_OPTS, ACCEPTED_STRINGS, "")
731+
validate(conf, DEFAULT_OPTS, ACCEPTED_STRINGS, ACCEPTED_TYPES, "")
693732

694733
if msg then
695734
vim.notify_once(msg .. " | see :help nvim-tree-opts for available configuration options", vim.log.levels.WARN)

0 commit comments

Comments
 (0)