@@ -35,7 +35,7 @@ function M.check()
3535 end
3636
3737 vim .health .start (' markdown.nvim [configuration]' )
38- local errors = M .check_keys ( md . default_config , state .config , {} )
38+ local errors = M .check_config ( state .config )
3939 if # errors == 0 then
4040 vim .health .ok (' valid' )
4141 end
@@ -69,27 +69,157 @@ function M.check_executable(name, advice)
6969 end
7070end
7171
72- --- @param t1 table<any , any>
73- --- @param t2 table<any , any>
74- --- @param path string[]
72+ --- @param config render.md.Config
7573--- @return string[]
76- function M .check_keys ( t1 , t2 , path )
74+ function M .check_config ( config )
7775 local errors = {}
78- for k , v2 in pairs (t2 ) do
79- local v1 = t1 [k ]
80- local key_path = vim .list_extend (vim .list_extend ({}, path ), { k })
81- local key = vim .fn .join (key_path , ' .' )
82- if v1 == nil then
83- table.insert (errors , string.format (' Invalid key: %s' , key ))
84- elseif type (v1 ) ~= type (v2 ) then
85- table.insert (errors , string.format (' Invalid type: %s, expected %s, found %s' , key , type (v1 ), type (v2 )))
86- elseif type (v1 ) == ' table' and type (v2 ) == ' table' then
87- -- Some tables are meant to have unrestricted keys
88- if not vim .tbl_contains ({ ' win_options' , ' custom' , ' custom_handlers' }, k ) then
89- vim .list_extend (errors , M .check_keys (v1 , v2 , key_path ))
76+
77+ --- @param value string
78+ --- @param valid_values string[]
79+ --- @return vim.validate.Spec
80+ local function one_of (value , valid_values )
81+ return {
82+ value ,
83+ function (v )
84+ return vim .tbl_contains (valid_values , v )
85+ end ,
86+ ' one of ' .. vim .inspect (valid_values ),
87+ }
88+ end
89+
90+ --- @param path string ?
91+ --- @param opts table<string , vim.validate.Spec>
92+ local function append_errors (path , opts )
93+ local ok , err = pcall (vim .validate , opts )
94+ if not ok then
95+ if path == nil then
96+ table.insert (errors , err )
97+ else
98+ table.insert (errors , path .. ' .' .. err )
9099 end
91100 end
92101 end
102+
103+ --- @param path string
104+ --- @param values string[]
105+ local function all_strings (path , values )
106+ for i , value in ipairs (values ) do
107+ append_errors (path , {
108+ [tostring (i )] = { value , ' string' },
109+ })
110+ end
111+ end
112+
113+ append_errors (nil , {
114+ start_enabled = { config .start_enabled , ' boolean' },
115+ latex_enabled = { config .latex_enabled , ' boolean' },
116+ max_file_size = { config .max_file_size , ' number' },
117+ markdown_query = { config .markdown_query , ' string' },
118+ markdown_quote_query = { config .markdown_quote_query , ' string' },
119+ inline_query = { config .inline_query , ' string' },
120+ latex_converter = { config .latex_converter , ' string' },
121+ log_level = one_of (config .log_level , { ' debug' , ' error' }),
122+ file_types = { config .file_types , ' table' },
123+ render_modes = { config .render_modes , ' table' },
124+ headings = { config .headings , ' table' },
125+ dash = { config .dash , ' string' },
126+ bullets = { config .bullets , ' table' },
127+ checkbox = { config .checkbox , ' table' },
128+ quote = { config .quote , ' string' },
129+ callout = { config .callout , ' table' },
130+ win_options = { config .win_options , ' table' },
131+ code_style = one_of (config .code_style , { ' full' , ' normal' , ' none' }),
132+ table_style = one_of (config .table_style , { ' full' , ' normal' , ' none' }),
133+ cell_style = one_of (config .cell_style , { ' overlay' , ' raw' }),
134+ custom_handlers = { config .custom_handlers , ' table' },
135+ highlights = { config .highlights , ' table' },
136+ })
137+
138+ all_strings (' file_types' , config .file_types )
139+ all_strings (' render_modes' , config .render_modes )
140+ all_strings (' headings' , config .headings )
141+ all_strings (' bullets' , config .bullets )
142+
143+ append_errors (' checkbox' , {
144+ unchecked = { config .checkbox .unchecked , ' string' },
145+ checked = { config .checkbox .checked , ' string' },
146+ custom = { config .checkbox .custom , ' table' },
147+ })
148+ for name , component in pairs (config .checkbox .custom ) do
149+ append_errors (' checkbox.custom.' .. name , {
150+ raw = { component .raw , ' string' },
151+ rendered = { component .rendered , ' string' },
152+ highlight = { component .highlight , ' string' },
153+ })
154+ end
155+
156+ append_errors (' callout' , {
157+ note = { config .callout .note , ' string' },
158+ tip = { config .callout .tip , ' string' },
159+ important = { config .callout .important , ' string' },
160+ warning = { config .callout .warning , ' string' },
161+ caution = { config .callout .caution , ' string' },
162+ custom = { config .callout .custom , ' table' },
163+ })
164+ for name , component in pairs (config .callout .custom ) do
165+ append_errors (' callout.custom.' .. name , {
166+ raw = { component .raw , ' string' },
167+ rendered = { component .rendered , ' string' },
168+ highlight = { component .highlight , ' string' },
169+ })
170+ end
171+
172+ for name , win_option in pairs (config .win_options ) do
173+ append_errors (' win_options.' .. name , {
174+ default = { win_option .default , { ' number' , ' string' } },
175+ rendered = { win_option .rendered , { ' number' , ' string' } },
176+ })
177+ end
178+
179+ for name , handler in pairs (config .custom_handlers ) do
180+ append_errors (' custom_handlers.' .. name , {
181+ render = { handler .render , ' function' },
182+ extends = { handler .extends , ' boolean' , true },
183+ })
184+ end
185+
186+ append_errors (' highlights' , {
187+ heading = { config .highlights .heading , ' table' },
188+ dash = { config .highlights .dash , ' string' },
189+ code = { config .highlights .code , ' string' },
190+ bullet = { config .highlights .bullet , ' string' },
191+ checkbox = { config .highlights .checkbox , ' table' },
192+ table = { config .highlights .table , ' table' },
193+ latex = { config .highlights .latex , ' string' },
194+ quote = { config .highlights .quote , ' string' },
195+ callout = { config .highlights .callout , ' table' },
196+ })
197+
198+ append_errors (' highlights.heading' , {
199+ backgrounds = { config .highlights .heading .backgrounds , ' table' },
200+ foregrounds = { config .highlights .heading .foregrounds , ' table' },
201+ })
202+ all_strings (' highlights.heading.backgrounds' , config .highlights .heading .backgrounds )
203+ all_strings (' highlights.heading.foregrounds' , config .highlights .heading .foregrounds )
204+
205+ append_errors (' highlights.checkbox' , {
206+ unchecked = { config .highlights .checkbox .unchecked , ' string' },
207+ checked = { config .highlights .checkbox .checked , ' string' },
208+ })
209+
210+ append_errors (' highlights.table' , {
211+ head = { config .highlights .table .head , ' string' },
212+ row = { config .highlights .table .row , ' string' },
213+ })
214+
215+ append_errors (' highlights.callout' , {
216+ note = { config .highlights .callout .note , ' string' },
217+ tip = { config .highlights .callout .tip , ' string' },
218+ important = { config .highlights .callout .important , ' string' },
219+ warning = { config .highlights .callout .warning , ' string' },
220+ caution = { config .highlights .callout .caution , ' string' },
221+ })
222+
93223 return errors
94224end
95225
0 commit comments