Check all user settings for correct type, range etc.

This commit is contained in:
EinfachToll 2019-01-19 21:05:27 +01:00
parent 6257c8fa54
commit fdc367f725
2 changed files with 209 additions and 76 deletions

View File

@ -13,7 +13,7 @@
" global user variables and syntax stuff which is the same for every syntax. " global user variables and syntax stuff which is the same for every syntax.
" "
" - wiki-local variables. They are stored in g:vimwiki_wikilocal_vars which is a list of " - wiki-local variables. They are stored in g:vimwiki_wikilocal_vars which is a list of
" dictionaries. One dict for every registered wiki. The last dictionary contains default values " dictionaries, one dict for every registered wiki. The last dictionary contains default values
" (used for temporary wikis). " (used for temporary wikis).
" "
" - syntax variables. Stored in the dict g:vimwiki_syntax_variables which holds all the regexes and " - syntax variables. Stored in the dict g:vimwiki_syntax_variables which holds all the regexes and
@ -28,50 +28,10 @@
function! s:populate_global_variables() function! s:populate_global_variables()
let g:vimwiki_global_vars = { let g:vimwiki_global_vars = {}
\ 'CJK_length': 0,
\ 'auto_chdir': 0,
\ 'autowriteall': 1,
\ 'conceallevel': 2,
\ 'diary_months':
\ {
\ 1: 'January', 2: 'February', 3: 'March',
\ 4: 'April', 5: 'May', 6: 'June',
\ 7: 'July', 8: 'August', 9: 'September',
\ 10: 'October', 11: 'November', 12: 'December'
\ },
\ 'dir_link': '',
\ 'ext2syntax': {},
\ 'folding': '',
\ 'global_ext': 1,
\ 'hl_cb_checked': 0,
\ 'hl_headers': 0,
\ 'html_header_numbering': 0,
\ 'html_header_numbering_sym': '',
\ 'list_ignore_newline': 1,
\ 'text_ignore_newline': 1,
\ 'listsyms': ' .oOX',
\ 'listsym_rejected': '-',
\ 'map_prefix': '<Leader>w',
\ 'menu': 'Vimwiki',
\ 'table_auto_fmt': 1,
\ 'table_mappings': 1,
\ 'toc_header': 'Contents',
\ 'url_maxsave': 15,
\ 'use_calendar': 1,
\ 'use_mouse': 0,
\ 'user_htmls': '',
\ 'valid_html_tags': 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em',
\ 'w32_dir_enc': '',
\ }
" copy the user's settings from variables of the form g:vimwiki_<option> into the dict call s:read_global_settings_from_user()
" g:vimwiki_global_vars (or set a default value) call s:normalize_global_settings()
for key in keys(g:vimwiki_global_vars)
if exists('g:vimwiki_'.key)
let g:vimwiki_global_vars[key] = g:vimwiki_{key}
endif
endfor
" non-configurable global variables: " non-configurable global variables:
@ -179,31 +139,131 @@ function! s:populate_global_variables()
endfunction endfunction
function! s:read_global_settings_from_user()
let global_settings = {
\ 'CJK_length': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'auto_chdir': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'autowriteall': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'conceallevel': {'type': type(0), 'default': 2, 'min': 0, 'max': 3},
\ 'diary_months': {'type': type({}), 'default':
\ {
\ 1: 'January', 2: 'February', 3: 'March',
\ 4: 'April', 5: 'May', 6: 'June',
\ 7: 'July', 8: 'August', 9: 'September',
\ 10: 'October', 11: 'November', 12: 'December'
\ }},
\ 'dir_link': {'type': type(''), 'default': ''},
\ 'ext2syntax': {'type': type({}), 'default': {}},
\ 'folding': {'type': type(''), 'default': '', 'possible_values': ['', 'expr', 'syntax',
\ 'list', 'custom', ':quick', 'expr:quick', 'syntax:quick', 'list:quick',
\ 'custom:quick']},
\ 'global_ext': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'hl_cb_checked': {'type': type(0), 'default': 0, 'min': 0, 'max': 2},
\ 'hl_headers': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'html_header_numbering': {'type': type(0), 'default': 0, 'min': 0, 'max': 6},
\ 'html_header_numbering_sym': {'type': type(''), 'default': ''},
\ 'list_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'text_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'listsyms': {'type': type(''), 'default': ' .oOX', 'min_length': 2},
\ 'listsym_rejected': {'type': type(''), 'default': '-', 'length': 1},
\ 'map_prefix': {'type': type(''), 'default': '<Leader>w'},
\ 'menu': {'type': type(''), 'default': 'Vimwiki'},
\ 'table_auto_fmt': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'table_mappings': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'toc_header': {'type': type(''), 'default': 'Contents', 'min_length': 1},
\ 'url_maxsave': {'type': type(0), 'default': 15, 'min': 0},
\ 'use_calendar': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'use_mouse': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'user_htmls': {'type': type(''), 'default': ''},
\ 'valid_html_tags': {'type': type(''), 'default':
\ 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em'},
\ 'w32_dir_enc': {'type': type(''), 'default': ''},
\ }
" copy the user's settings from variables of the form g:vimwiki_<option> into the dict
" g:vimwiki_global_vars (or set a default value)
for key in keys(global_settings)
if exists('g:vimwiki_'.key)
let users_value = g:vimwiki_{key}
let value_infos = global_settings[key]
call s:check_users_value(key, users_value, value_infos, 1)
let g:vimwiki_global_vars[key] = users_value
else
let g:vimwiki_global_vars[key] = global_settings[key].default
endif
endfor
" validate some settings individually
let key = 'diary_months'
let users_value = g:vimwiki_global_vars[key]
for month in range(1, 12)
if !has_key(users_value, month) || type(users_value[month]) != type('') ||
\ empty(users_value[month])
echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
\ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
break
endif
endfor
let key = 'ext2syntax'
let users_value = g:vimwiki_global_vars[key]
for ext in keys(users_value)
if empty(ext) || index(['markdown', 'media', 'mediawiki', 'default'], users_value[ext]) == -1
echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
\ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
break
endif
endfor
endfunction
function! s:normalize_global_settings()
let keys = keys(g:vimwiki_global_vars.ext2syntax)
for ext in keys
" ensure the file extensions in ext2syntax start with a dot
if ext[0] != '.'
let new_ext = '.' . ext
let g:vimwiki_global_vars.ext2syntax[new_ext] = g:vimwiki_global_vars.ext2syntax[ext]
call remove(g:vimwiki_global_vars.ext2syntax, ext)
endif
" for convenience, we also allow the term 'mediawiki'
if g:vimwiki_global_vars.ext2syntax[ext] ==# 'mediawiki'
let g:vimwiki_global_vars.ext2syntax[ext] = 'media'
endif
endfor
endfunction
function! s:populate_wikilocal_options() function! s:populate_wikilocal_options()
let default_values = { let default_values = {
\ 'auto_diary_index': 0, \ 'auto_diary_index': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'auto_export': 0, \ 'auto_export': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'auto_tags': 0, \ 'auto_tags': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'auto_toc': 0, \ 'auto_toc': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'automatic_nested_syntaxes': 1, \ 'automatic_nested_syntaxes': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
\ 'css_name': 'style.css', \ 'css_name': {'type': type(''), 'default': 'style.css', 'min_length': 1},
\ 'custom_wiki2html': '', \ 'custom_wiki2html': {'type': type(''), 'default': ''},
\ 'custom_wiki2html_args': '', \ 'custom_wiki2html_args': {'type': type(''), 'default': ''},
\ 'diary_header': 'Diary', \ 'diary_header': {'type': type(''), 'default': 'Diary', 'min_length': 1},
\ 'diary_index': 'diary', \ 'diary_index': {'type': type(''), 'default': 'diary', 'min_length': 1},
\ 'diary_rel_path': 'diary/', \ 'diary_rel_path': {'type': type(''), 'default': 'diary/', 'min_length': 1},
\ 'diary_sort': 'desc', \ 'diary_sort': {'type': type(''), 'default': 'desc', 'possible_values': ['asc', 'desc']},
\ 'ext': '.wiki', \ 'ext': {'type': type(''), 'default': '.wiki', 'min_length': 1},
\ 'index': 'index', \ 'index': {'type': type(''), 'default': 'index', 'min_length': 1},
\ 'list_margin': -1, \ 'list_margin': {'type': type(0), 'default': -1, 'min': -1},
\ 'maxhi': 0, \ 'maxhi': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
\ 'nested_syntaxes': {}, \ 'nested_syntaxes': {'type': type({}), 'default': {}},
\ 'path': $HOME . '/vimwiki/', \ 'path': {'type': type(''), 'default': $HOME . '/vimwiki/', 'min_length': 1},
\ 'path_html': '', \ 'path_html': {'type': type(''), 'default': ''},
\ 'syntax': 'default', \ 'syntax': {'type': type(''), 'default': 'default',
\ 'template_default': 'default', \ 'possible_values': ['default', 'markdown', 'media', 'mediawiki']},
\ 'template_ext': '.tpl', \ 'template_default': {'type': type(''), 'default': 'default', 'min_length': 1},
\ 'template_path': $HOME . '/vimwiki/templates/', \ 'template_ext': {'type': type(''), 'default': '.tpl'},
\ 'template_path': {'type': type(''), 'default': $HOME . '/vimwiki/templates/'},
\ } \ }
let g:vimwiki_wikilocal_vars = [] let g:vimwiki_wikilocal_vars = []
@ -211,9 +271,10 @@ function! s:populate_wikilocal_options()
let default_wiki_settings = {} let default_wiki_settings = {}
for key in keys(default_values) for key in keys(default_values)
if exists('g:vimwiki_'.key) if exists('g:vimwiki_'.key)
call s:check_users_value(key, g:vimwiki_{key}, default_values[key], 1)
let default_wiki_settings[key] = g:vimwiki_{key} let default_wiki_settings[key] = g:vimwiki_{key}
else else
let default_wiki_settings[key] = default_values[key] let default_wiki_settings[key] = default_values[key].default
endif endif
endfor endfor
@ -223,11 +284,10 @@ function! s:populate_wikilocal_options()
let new_wiki_settings = {} let new_wiki_settings = {}
for key in keys(default_values) for key in keys(default_values)
if has_key(users_wiki_settings, key) if has_key(users_wiki_settings, key)
call s:check_users_value(key, users_wiki_settings[key], default_values[key], 0)
let new_wiki_settings[key] = users_wiki_settings[key] let new_wiki_settings[key] = users_wiki_settings[key]
elseif exists('g:vimwiki_'.key)
let new_wiki_settings[key] = g:vimwiki_{key}
else else
let new_wiki_settings[key] = default_values[key] let new_wiki_settings[key] = default_wiki_settings[key]
endif endif
endfor endfor
@ -247,11 +307,79 @@ function! s:populate_wikilocal_options()
let temporary_wiki_settings.is_temporary_wiki = 1 let temporary_wiki_settings.is_temporary_wiki = 1
call add(g:vimwiki_wikilocal_vars, temporary_wiki_settings) call add(g:vimwiki_wikilocal_vars, temporary_wiki_settings)
call s:validate_settings() " check some values individually
let key = 'nested_syntaxes'
for wiki_settings in g:vimwiki_wikilocal_vars
let users_value = wiki_settings[key]
for keyword in keys(users_value)
if type(keyword) != type('') || empty(keyword) || type(users_value[keyword]) != type('') ||
\ empty(users_value[keyword])
echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
\ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
break
endif
endfor
endfor
call s:normalize_wikilocal_settings()
endfunction endfunction
function! s:validate_settings() function! s:check_users_value(key, users_value, value_infos, comes_from_global_variable)
let type_code_to_name = {
\ type(0): 'number',
\ type(''): 'string',
\ type([]): 'list',
\ type({}): 'dictionary'}
let setting_origin = a:comes_from_global_variable ?
\ printf('''g:vimwiki_%s''', a:key) :
\ printf('''%s'' in g:vimwiki_list', a:key)
if has_key(a:value_infos, 'type') && type(a:users_value) != a:value_infos.type
echom printf('Vimwiki Error: The provided value of the option %s is a %s, ' .
\ 'but expected is a %s. See '':h g:vimwiki_%s''.', setting_origin,
\ type_code_to_name[type(a:users_value)], type_code_to_name[a:value_infos.type], a:key)
endif
if a:value_infos.type == type(0) && has_key(a:value_infos, 'min') &&
\ a:users_value < a:value_infos.min
echom printf('Vimwiki Error: The provided value ''%i'' of the option %s is'
\ . ' too small. The minimum value is %i. See '':h g:vimwiki_%s''.', a:users_value,
\ setting_origin, a:value_infos.min, a:key)
endif
if a:value_infos.type == type(0) && has_key(a:value_infos, 'max') &&
\ a:users_value > a:value_infos.max
echom printf('Vimwiki Error: The provided value ''%i'' of the option %s is'
\ . ' too large. The maximum value is %i. See '':h g:vimwiki_%s''.', a:users_value,
\ setting_origin, a:value_infos.max, a:key)
endif
if has_key(a:value_infos, 'possible_values') &&
\ index(a:value_infos.possible_values, a:users_value) == -1
echom printf('Vimwiki Error: The provided value ''%s'' of the option %s is'
\ . ' invalid. Allowed values are %s. See ''g:vimwiki_%s''.', a:users_value,
\ setting_origin, string(a:value_infos.possible_values), a:key)
endif
if a:value_infos.type == type('') && has_key(a:value_infos, 'length') &&
\ strwidth(a:users_value) != a:value_infos.length
echom printf('Vimwiki Error: The provided value ''%s'' of the option %s must'
\ . ' contain exactly %i character(s) but has %i. See '':h g:vimwiki_%s''.',
\ a:users_value, setting_origin, a:value_infos.length, strwidth(a:users_value), a:key)
endif
if a:value_infos.type == type('') && has_key(a:value_infos, 'min_length') &&
\ strwidth(a:users_value) < a:value_infos.min_length
echom printf('Vimwiki Error: The provided value ''%s'' of the option %s must'
\ . ' have at least %d character(s) but has %d. See '':h g:vimwiki_%s''.', a:users_value,
\ setting_origin, a:value_infos.min_length, strwidth(a:users_value), a:key)
endif
endfunction
function! s:normalize_wikilocal_settings()
for wiki_settings in g:vimwiki_wikilocal_vars for wiki_settings in g:vimwiki_wikilocal_vars
let wiki_settings['path'] = s:normalize_path(wiki_settings['path']) let wiki_settings['path'] = s:normalize_path(wiki_settings['path'])
@ -270,6 +398,11 @@ function! s:validate_settings()
if !empty(ext) && ext[0] != '.' if !empty(ext) && ext[0] != '.'
let wiki_settings['ext'] = '.' . ext let wiki_settings['ext'] = '.' . ext
endif endif
" for convenience, we also allow the term 'mediawiki'
if wiki_settings.syntax ==# 'mediawiki'
let wiki_settings.syntax = 'media'
endif
endfor endfor
endfunction endfunction
@ -706,7 +839,7 @@ function! vimwiki#vars#add_temporary_wiki(settings)
let new_temp_wiki_settings[key] = value let new_temp_wiki_settings[key] = value
endfor endfor
call insert(g:vimwiki_wikilocal_vars, new_temp_wiki_settings, -1) call insert(g:vimwiki_wikilocal_vars, new_temp_wiki_settings, -1)
call s:validate_settings() call s:normalize_wikilocal_settings()
endfunction endfunction

View File

@ -31,7 +31,7 @@ function! s:setup_buffer_leave()
let &autowriteall = s:vimwiki_autowriteall_saved let &autowriteall = s:vimwiki_autowriteall_saved
if vimwiki#vars#get_global('menu') != "" if !empty(vimwiki#vars#get_global('menu'))
exe 'nmenu disable '.vimwiki#vars#get_global('menu').'.Table' exe 'nmenu disable '.vimwiki#vars#get_global('menu').'.Table'
endif endif
endfunction endfunction
@ -147,7 +147,7 @@ function! s:set_global_options()
let s:vimwiki_autowriteall_saved = &autowriteall let s:vimwiki_autowriteall_saved = &autowriteall
let &autowriteall = vimwiki#vars#get_global('autowriteall') let &autowriteall = vimwiki#vars#get_global('autowriteall')
if vimwiki#vars#get_global('menu') !=# '' if !empty(vimwiki#vars#get_global('menu'))
exe 'nmenu enable '.vimwiki#vars#get_global('menu').'.Table' exe 'nmenu enable '.vimwiki#vars#get_global('menu').'.Table'
endif endif
endfunction endfunction