" Title: Vimwiki variable definition and manipulation functions " " Home: https://github.com/vimwiki/vimwiki/ " ------------------------------------------------------------------------------------------------ " This file provides functions to manage the various state variables which are needed during a " Vimwiki session. " They consist of: " " - global variables. These are stored in the dict g:vimwiki_global_vars. They consist mainly of " 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 " dictionaries, one dict for every registered wiki. The last dictionary contains default values " (used for temporary wikis). " " - syntax variables. Stored in the dict g:vimwiki_syntaxlocal_vars which holds all the regexes and " other stuff which is needed for highlighting. " " - buffer-local variables. They are stored as buffer variables directly (b:foo) " As a developer, you should, if possible, only use the get_ and set_ functions for these types of " variables, not the underlying dicts! " ------------------------------------------------------------------------------------------------ " Script variable let s:margin_set_by_user = 0 function! vimwiki#vars#init() abort " Init global and local variables " Init && Populate: global variable container let g:vimwiki_global_vars = {} call s:populate_global_variables() " Init && Populate: local variable container let g:vimwiki_wikilocal_vars = [] call s:populate_wikilocal_options() endfunction function! s:check_users_value(key, users_value, value_infos, comes_from_global_variable) abort " Helper: Check user setting " warn user with message if not good type " Param: 1: key : variable name " Param: 2: vimwiki_key : user value " Param: 3: value_infod : type and default value " Param: 4: coming from a 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) let help_text = a:comes_from_global_variable ? \ 'g:vimwiki_' : \ 'vimwiki-option-' if has_key(a:value_infos, 'type') && type(a:users_value) != a:value_infos.type call vimwiki#u#error(printf('The provided value of the option %s is a %s, ' . \ 'but expected is a %s. See '':h '.help_text.'%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 call vimwiki#u#error(printf('The provided value ''%i'' of the option %s is' \ . ' too small. The minimum value is %i. See '':h '.help_text.'%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 call vimwiki#u#error(printf('The provided value ''%i'' of the option %s is' \ . ' too large. The maximum value is %i. See '':h '.help_text.'%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 call vimwiki#u#error(printf('The provided value ''%s'' of the option %s is' \ . ' invalid. Allowed values are %s. See '':h '.help_text.'%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 call vimwiki#u#error(printf('The provided value ''%s'' of the option %s must' \ . ' contain exactly %i character(s) but has %i. See '':h '.help_text.'_%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 call vimwiki#u#error(printf('The provided value ''%s'' of the option %s must' \ . ' have at least %d character(s) but has %d. See '':h '.help_text.'%s''.', a:users_value, \ setting_origin, a:value_infos.min_length, strwidth(a:users_value), a:key)) endif endfunction function! s:update_key(output_dic, key, old, new) abort " Helper: Treat special variables " Set list margin if a:key ==# 'list_margin' let s:margin_set_by_user = 1 let a:output_dic[a:key] = a:new return " Extend Tag format elseif a:key ==# 'tag_format' let a:output_dic[a:key] = {} call extend(a:output_dic[a:key], a:old) call extend(a:output_dic[a:key], a:new) return else let a:output_dic[a:key] = a:new return endif endfunction " ---------------------------------------------------------- " 1. Global {{{1 " ---------------------------------------------------------- function! s:get_default_global() abort " Get default wikilocal values " Please: keep alphabetical sort return { \ 'CJK_length': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, \ 'auto_chdir': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, \ 'auto_header': {'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}, \ 'conceal_onechar_markers': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, \ 'conceal_pre': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, \ 'create_link': {'type': type(0), 'default': 1, 'min':0, 'max': 1}, \ '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': ''}, \ 'emoji_enable': {'type': type(0), 'default': 3, 'min':0, 'max': 3}, \ 'ext2syntax': {'type': type({}), 'default': {'.md': 'markdown', '.mkdn': 'markdown', \ '.mdwn': 'markdown', '.mdown': 'markdown', '.markdown': 'markdown', '.mw': 'media'}}, \ 'folding': {'type': type(''), 'default': '', 'possible_values': ['', 'expr', 'syntax', \ 'list', 'custom', ':quick', 'expr:quick', 'syntax:quick', 'list:quick', \ 'custom:quick']}, \ 'filetypes': {'type': type([]), 'default': []}, \ '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': ''}, \ 'key_mappings': {'type': type({}), 'default': \ { \ 'all_maps': 1, 'global': 1, 'headers': 1, 'text_objs': 1, \ 'table_format': 1, 'table_mappings': 1, 'lists': 1, 'lists_return': 1, \ 'links': 1, 'html': 1, 'mouse': 0, \ }}, \ 'links_header': {'type': type(''), 'default': 'Generated Links', 'min_length': 1}, \ 'links_header_level': {'type': type(0), 'default': 1, 'min': 1, 'max': 6}, \ 'listing_hl': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, \ 'listing_hl_command': {'type': type(''), 'default': 'pygmentize -f html'}, \ 'listsyms': {'type': type(''), 'default': ' .oOX', 'min_length': 2}, \ 'listsym_rejected': {'type': type(''), 'default': '-', 'length': 1}, \ 'map_prefix': {'type': type(''), 'default': 'w'}, \ 'markdown_header_style': {'type': type(0), 'default': 1, 'min':0, 'max': 2}, \ 'menu': {'type': type(''), 'default': 'Vimwiki'}, \ 'schemes_web': {'type': type([]), 'default': \ [ \ 'http', 'https', 'file', 'ftp', 'gopher', 'telnet', 'nntp', 'ldap', \ 'rsync', 'imap', 'pop', 'irc', 'ircs', 'cvs', 'svn', 'svn+ssh', \ 'git', 'ssh', 'fish', 'sftp', 'thunderlink' \ ]}, \ 'schemes_any': {'type': type([]), 'default': ['mailto', 'matrix', 'news', 'xmpp', 'sip', 'sips', 'doi', 'urn', 'tel', 'data']}, \ 'table_auto_fmt': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, \ 'table_reduce_last_col': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, \ 'table_mappings': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, \ 'tags_header': {'type': type(''), 'default': 'Generated Tags', 'min_length': 1}, \ 'tags_header_level': {'type': type(0), 'default': 1, 'min': 1, 'max': 5}, \ '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': ''}, \ } endfunction function! s:populate_global_variables() abort " Populate: global variable <- user & default " Called: s:vimwiki#vars#init call s:read_global_settings_from_user() call s:normalize_global_settings() call s:internal_global_settings() endfunction function! s:internal_global_settings() abort " Declare: normalized settings -> more usefull variables to use internally " non-configurable global variables: " Scheme regexes must be defined even if syntax file is not loaded yet cause users should be " able to ww without opening any vimwiki file first " Know internal schemes let g:vimwiki_global_vars.schemes_web = \ join(vimwiki#vars#get_global('schemes_web'), '\|') let g:vimwiki_global_vars.schemes_any = \ join(vimwiki#vars#get_global('schemes_any'), '\|') let g:vimwiki_global_vars.schemes_local = \ join(['wiki\d\+', 'diary', 'local'], '\|') " Concatenate known schemes => regex let g:vimwiki_global_vars.rxSchemes = '\%('. \ g:vimwiki_global_vars.schemes_local . '\|'. \ g:vimwiki_global_vars.schemes_web . '\|'. \ g:vimwiki_global_vars.schemes_any . \ '\)' " Match URL for common protocols; see http://en.wikipedia.org/wiki/URI_scheme " http://tools.ietf.org/html/rfc3986 let rxWebProtocols = \ '\%('. \ '\%('. \ '\%('. g:vimwiki_global_vars.schemes_web . '\):'. \ '\%(//\)'. \ '\)'. \ '\|'. \ '\%('. g:vimwiki_global_vars.schemes_any .'\):'. \ '\)' let g:vimwiki_global_vars.rxWeblinkUrl = rxWebProtocols . '\S\{-1,}'. '\%(([^ \t()]*)\)\=' let wikilink_prefix = '[[' let wikilink_suffix = ']]' let wikilink_separator = '|' let g:vimwiki_global_vars.rx_wikilink_prefix = vimwiki#u#escape(wikilink_prefix) let g:vimwiki_global_vars.rx_wikilink_suffix = vimwiki#u#escape(wikilink_suffix) let g:vimwiki_global_vars.rx_wikilink_separator = vimwiki#u#escape(wikilink_separator) " templates for the creation of wiki links " [[URL]] let g:vimwiki_global_vars.WikiLinkTemplate1 = wikilink_prefix . '__LinkUrl__'. wikilink_suffix " [[URL|DESCRIPTION]] let g:vimwiki_global_vars.WikiLinkTemplate2 = wikilink_prefix . '__LinkUrl__'. wikilink_separator \ . '__LinkDescription__' . wikilink_suffix let valid_chars = '[^\\\]]' let g:vimwiki_global_vars.rxWikiLinkUrl = valid_chars.'\{-}' let g:vimwiki_global_vars.rxWikiLinkDescr = valid_chars.'\{-}' " this regexp defines what can form a link when the user presses in the " buffer (and not on a link) to create a link " basically, it's Ascii alphanumeric characters plus #|./@-_~ plus all " non-Ascii characters, except that . is not accepted as the last character " TODO look behind for . reduces the second part of the regex that is the same with '.' added let g:vimwiki_global_vars.rxWord = '[^[:blank:]!"$%&''()*+,:;<=>?\[\]\\^`{}]*[^[:blank:]!"$%&''()*+.,:;<=>?\[\]\\^`{}]' let g:vimwiki_global_vars.rx_wikilink_prefix1 = g:vimwiki_global_vars.rx_wikilink_prefix . \ g:vimwiki_global_vars.rxWikiLinkUrl . g:vimwiki_global_vars.rx_wikilink_separator let g:vimwiki_global_vars.rx_wikilink_suffix1 = g:vimwiki_global_vars.rx_wikilink_suffix let g:vimwiki_global_vars.rxWikiInclPrefix = '{{' let g:vimwiki_global_vars.rxWikiInclSuffix = '}}' let g:vimwiki_global_vars.rxWikiInclSeparator = '|' " '{{__LinkUrl__}}' let g:vimwiki_global_vars.WikiInclTemplate1 = g:vimwiki_global_vars.rxWikiInclPrefix \ .'__LinkUrl__'. g:vimwiki_global_vars.rxWikiInclSuffix " '{{__LinkUrl____LinkDescription__}}' let g:vimwiki_global_vars.WikiInclTemplate2 = g:vimwiki_global_vars.rxWikiInclPrefix \ . '__LinkUrl__' . g:vimwiki_global_vars.rxWikiInclSeparator . '__LinkDescription__' \ . g:vimwiki_global_vars.rxWikiInclSuffix let valid_chars = '[^\\\}]' let g:vimwiki_global_vars.rxWikiInclUrl = valid_chars.'\{-}' let g:vimwiki_global_vars.rxWikiInclArg = valid_chars.'\{-}' let g:vimwiki_global_vars.rxWikiInclArgs = '\%('. g:vimwiki_global_vars.rxWikiInclSeparator. \ g:vimwiki_global_vars.rxWikiInclArg. '\)'.'\{-}' " *. {{URL}[{...}]} - i.e. {{URL}}, {{URL|ARG1}}, {{URL|ARG1|ARG2}}, etc. " *a) match {{URL}[{...}]} let g:vimwiki_global_vars.rxWikiIncl = g:vimwiki_global_vars.rxWikiInclPrefix. \ g:vimwiki_global_vars.rxWikiInclUrl. \ g:vimwiki_global_vars.rxWikiInclArgs. g:vimwiki_global_vars.rxWikiInclSuffix " *b) match URL within {{URL}[{...}]} let g:vimwiki_global_vars.rxWikiInclMatchUrl = g:vimwiki_global_vars.rxWikiInclPrefix. \ '\zs'. g:vimwiki_global_vars.rxWikiInclUrl . '\ze'. \ g:vimwiki_global_vars.rxWikiInclArgs . g:vimwiki_global_vars.rxWikiInclSuffix let g:vimwiki_global_vars.rxWikiInclPrefix1 = g:vimwiki_global_vars.rxWikiInclPrefix. \ g:vimwiki_global_vars.rxWikiInclUrl . g:vimwiki_global_vars.rxWikiInclSeparator let g:vimwiki_global_vars.rxWikiInclSuffix1 = g:vimwiki_global_vars.rxWikiInclArgs. \ g:vimwiki_global_vars.rxWikiInclSuffix " default colors when headers of different levels are highlighted differently " not making it yet another option; needed by ColorScheme autocommand let g:vimwiki_global_vars.hcolor_guifg_light = ['#aa5858', '#507030', '#1030a0', '#103040' \ , '#505050', '#636363'] let g:vimwiki_global_vars.hcolor_ctermfg_light = ['DarkRed', 'DarkGreen', 'DarkBlue', 'Black' \ , 'Black', 'Black'] let g:vimwiki_global_vars.hcolor_guifg_dark = ['#e08090', '#80e090', '#6090e0', '#c0c0f0' \ , '#e0e0f0', '#f0f0f0'] let g:vimwiki_global_vars.hcolor_ctermfg_dark = ['Red', 'Green', 'Blue', 'White', 'White' \ , 'White'] endfunction function! s:extend_global(output_dic, default_dic) abort " Extend global dictionary <- default <- user " Note: user_dic is unused here because it comes from g:vimwiki_* vars " Copy the user's settings from variables of the form g:vimwiki_