From ac4d0a1d46857231e072c41515f3f035312742ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20F=2E=20Sch=C3=B6nitzer?= Date: Thu, 4 Jun 2020 18:33:12 +0200 Subject: [PATCH] Allow to configure bullet points & status indicators per wiki (#889) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow the bullet point characters of lists to be configures by the wiki option `bullet_types`. This allows to use other/additional characters for the bullets of lists – including unicode-chars like '→' or '•'. The default values depends on the chooses syntax. * Allow to configure `vimwiki-listsyms` and `vimwiki-listsym_rejected` on per wiki basis. * Fix a test for mediawiki syntax --- autoload/vimwiki/html.vim | 6 +-- autoload/vimwiki/lst.vim | 34 ++++++------ autoload/vimwiki/vars.vim | 107 ++++++++++++++++++++++++-------------- doc/vimwiki.txt | 59 +++++++++++++++++++-- ftplugin/vimwiki.vim | 2 +- syntax/vimwiki.vim | 10 ++-- 6 files changed, 151 insertions(+), 67 deletions(-) diff --git a/autoload/vimwiki/html.vim b/autoload/vimwiki/html.vim index 0da3d81..f50608c 100644 --- a/autoload/vimwiki/html.vim +++ b/autoload/vimwiki/html.vim @@ -922,8 +922,8 @@ function! s:process_tag_list(line, lists) abort let st_tag = '
  • ' let chk = matchlist(a:line, a:rx_list) if !empty(chk) && len(chk[1]) > 0 - let completion = index(vimwiki#vars#get_syntaxlocal('listsyms_list'), chk[1]) - let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list')) + let completion = index(vimwiki#vars#get_wikilocal('listsyms_list'), chk[1]) + let n = len(vimwiki#vars#get_wikilocal('listsyms_list')) if completion == 0 let st_tag = '
  • ' elseif completion == -1 && chk[1] == vimwiki#vars#get_global('listsym_rejected') @@ -1554,7 +1554,7 @@ function! s:convert_file(path_html, wikifile) abort endif " prepare regexps for lists - let s:bullets = '[*-]' + let s:bullets = vimwiki#vars#get_wikilocal('rx_bullet_char') let s:numbers = '\C\%(#\|\d\+)\|\d\+\.\|[ivxlcdm]\+)\|[IVXLCDM]\+)\|\l\{1,2})\|\u\{1,2})\)' for line in lsource diff --git a/autoload/vimwiki/lst.vim b/autoload/vimwiki/lst.vim index bebd89b..ad2a4d5 100644 --- a/autoload/vimwiki/lst.vim +++ b/autoload/vimwiki/lst.vim @@ -137,7 +137,7 @@ endfunction "Returns: the column where the text of a line starts (possible list item "markers and checkboxes are skipped) function! s:text_begin(lnum) abort - return s:string_length(matchstr(getline(a:lnum), vimwiki#vars#get_syntaxlocal('rxListItem'))) + return s:string_length(matchstr(getline(a:lnum), vimwiki#vars#get_wikilocal('rxListItem'))) endfunction @@ -145,9 +145,9 @@ endfunction " 1 for a marker and no text " 0 for no marker at all (empty line or only text) function! s:line_has_marker(lnum) abort - if getline(a:lnum) =~# vimwiki#vars#get_syntaxlocal('rxListItem').'\s*$' + if getline(a:lnum) =~# vimwiki#vars#get_wikilocal('rxListItem').'\s*$' return 1 - elseif getline(a:lnum) =~# vimwiki#vars#get_syntaxlocal('rxListItem').'\s*\S' + elseif getline(a:lnum) =~# vimwiki#vars#get_wikilocal('rxListItem').'\s*\S' return 2 else return 0 @@ -172,7 +172,7 @@ function! s:get_item(lnum) abort return item endif - let matches = matchlist(getline(a:lnum), vimwiki#vars#get_syntaxlocal('rxListItem')) + let matches = matchlist(getline(a:lnum), vimwiki#vars#get_wikilocal('rxListItem')) if matches == [] || \ (matches[1] ==? '' && matches[2] ==? '') || \ (matches[1] !=? '' && matches[2] !=? '') @@ -209,7 +209,7 @@ function! s:get_level(lnum) abort let level = indent(a:lnum) else let level = s:string_length(matchstr(getline(a:lnum), - \ vimwiki#vars#get_syntaxlocal('rx_bullet_chars')))-1 + \ vimwiki#vars#get_wikilocal('rx_bullet_chars')))-1 if level < 0 let level = (indent(a:lnum) == 0) ? 0 : 9999 endif @@ -302,7 +302,7 @@ endfunction " Returns: Whether or not the checkbox of a list item is [X] or [-] function! s:is_closed(item) abort let state = a:item.cb - return state ==# vimwiki#vars#get_syntaxlocal('listsyms_list')[-1] + return state ==# vimwiki#vars#get_wikilocal('listsyms_list')[-1] \ || state ==# vimwiki#vars#get_global('listsym_rejected') endfunction @@ -746,8 +746,8 @@ function! s:get_rate(item) abort if state == vimwiki#vars#get_global('listsym_rejected') return -1 endif - let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list')) - return index(vimwiki#vars#get_syntaxlocal('listsyms_list'), state) * 100/(n-1) + let n = len(vimwiki#vars#get_wikilocal('listsyms_list')) + return index(vimwiki#vars#get_wikilocal('listsyms_list'), state) * 100/(n-1) endfunction @@ -786,7 +786,7 @@ function! s:set_state_plus_children(item, new_rate, ...) abort if child_item.cb != vimwiki#vars#get_global('listsym_rejected') let all_children_are_rejected = 0 endif - if child_item.cb != vimwiki#vars#get_syntaxlocal('listsyms_list')[-1] + if child_item.cb != vimwiki#vars#get_wikilocal('listsyms_list')[-1] let all_children_are_done = 0 endif if !all_children_are_done && !all_children_are_rejected @@ -822,7 +822,7 @@ endfunction "Returns: the appropriate symbol for a given percent rate function! s:rate_to_state(rate) abort - let listsyms_list = vimwiki#vars#get_syntaxlocal('listsyms_list') + let listsyms_list = vimwiki#vars#get_wikilocal('listsyms_list') let state = '' let n = len(listsyms_list) if a:rate == 100 @@ -999,7 +999,7 @@ function! vimwiki#lst#decrement_cb(from_line, to_line) abort "if from_line has CB, decrement it and set all siblings to the same new state let rate_first_line = s:get_rate(from_item) - let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list')) + let n = len(vimwiki#vars#get_wikilocal('listsyms_list')) let new_rate = max([rate_first_line - 100/(n-1)-1, 0]) call s:change_cb(a:from_line, a:to_line, new_rate) @@ -1017,7 +1017,7 @@ function! vimwiki#lst#increment_cb(from_line, to_line) abort "if from_line has CB, increment it and set all siblings to the same new state let rate_first_line = s:get_rate(from_item) - let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list')) + let n = len(vimwiki#vars#get_wikilocal('listsyms_list')) let new_rate = min([rate_first_line + 100/(n-1)+1, 100]) call s:change_cb(a:from_line, a:to_line, new_rate) @@ -1103,7 +1103,7 @@ endfunction function! s:decrease_level(item) abort let removed_indent = 0 if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 && - \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), + \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(a:item.mrkr)) > -1 if s:string_length(a:item.mrkr) >= 2 call s:substitute_string_in_line(a:item.lnum, s:first_char(a:item.mrkr), '') @@ -1126,7 +1126,7 @@ endfunction function! s:increase_level(item) abort let additional_indent = 0 if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 && - \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), + \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(a:item.mrkr)) > -1 call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, a:item.mrkr . \ s:first_char(a:item.mrkr)) @@ -1150,7 +1150,7 @@ endfunction function! s:indent_line_by(lnum, indent_by) abort let item = s:get_item(a:lnum) if vimwiki#vars#get_syntaxlocal('recurring_bullets') && item.type == 1 && - \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), + \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(item.mrkr)) > -1 if a:indent_by > 0 call s:substitute_string_in_line(a:lnum, item.mrkr, item.mrkr . s:first_char(item.mrkr)) @@ -1325,7 +1325,7 @@ function! vimwiki#lst#change_marker(from_line, to_line, new_mrkr, mode) abort endif "handle markers like *** - if index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), s:first_char(new_mrkr)) > -1 + if index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), s:first_char(new_mrkr)) > -1 "use *** if the item above has *** too let item_above = s:get_prev_list_item(cur_item, 1) if item_above.type == 1 && s:first_char(item_above.mrkr) ==# s:first_char(new_mrkr) @@ -1396,7 +1396,7 @@ function! s:adjust_mrkr(item) abort "if possible, set e.g. *** if parent has ** as marker if neighbor_item.type == 0 && a:item.type == 1 && - \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), + \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(a:item.mrkr)) > -1 let parent_item = s:get_parent(a:item) if parent_item.type == 1 && s:first_char(parent_item.mrkr) ==# s:first_char(a:item.mrkr) diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim index 4087710..0453541 100644 --- a/autoload/vimwiki/vars.vim +++ b/autoload/vimwiki/vars.vim @@ -357,6 +357,9 @@ function! s:populate_wikilocal_options() abort \ 'template_ext': {'type': type(''), 'default': '.tpl'}, \ 'template_path': {'type': type(''), 'default': $HOME . '/vimwiki/templates/'}, \ 'html_filename_parameterization': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, + \ 'bullet_types': {'type': type([]), 'default': []}, + \ 'listsyms': {'type': type(''), 'default': vimwiki#vars#get_global('listsyms')}, + \ 'listsym_rejected': {'type': type(''), 'default': vimwiki#vars#get_global('listsym_rejected')}, \ } let g:vimwiki_wikilocal_vars = [] @@ -402,6 +405,13 @@ function! s:populate_wikilocal_options() abort let temporary_wiki_settings = deepcopy(default_wiki_settings) let temporary_wiki_settings.is_temporary_wiki = 1 call add(g:vimwiki_wikilocal_vars, temporary_wiki_settings) + " Set up variables for the lists, depending on config and syntax + for wiki in g:vimwiki_wikilocal_vars + if len(wiki.bullet_types) == 0 + let wiki.bullet_types = vimwiki#vars#get_syntaxlocal('bullet_types', wiki.syntax) + endif + call vimwiki#vars#populate_list_vars(wiki) + endfor " check some values individually let key = 'nested_syntaxes' @@ -587,14 +597,6 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort let g:vimwiki_syntax_variables[a:syntax].rxMathEnd = \ '^\s*'.g:vimwiki_syntax_variables[a:syntax].rxMathEnd.'\s*$' - " list stuff - let g:vimwiki_syntax_variables[a:syntax].rx_bullet_chars = - \ '['.join(g:vimwiki_syntax_variables[a:syntax].bullet_types, '').']\+' - - let g:vimwiki_syntax_variables[a:syntax].multiple_bullet_chars = - \ g:vimwiki_syntax_variables[a:syntax].recurring_bullets - \ ? g:vimwiki_syntax_variables[a:syntax].bullet_types : [] - let g:vimwiki_syntax_variables[a:syntax].number_kinds = [] let g:vimwiki_syntax_variables[a:syntax].number_divisors = '' for i in g:vimwiki_syntax_variables[a:syntax].number_types @@ -632,36 +634,6 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort let g:vimwiki_syntax_variables[a:syntax].rxListNumber = '$^' endif - "the user can set the listsyms as string, but vimwiki needs a list - let g:vimwiki_syntax_variables[a:syntax].listsyms_list = - \ split(vimwiki#vars#get_global('listsyms'), '\zs') - if match(vimwiki#vars#get_global('listsyms'), vimwiki#vars#get_global('listsym_rejected')) != -1 - echomsg 'Vimwiki Warning: the value of g:vimwiki_listsym_rejected (''' - \ . vimwiki#vars#get_global('listsym_rejected') - \ . ''') must not be a part of g:vimwiki_listsyms (''' - \ . vimwiki#vars#get_global('listsyms') . ''')' - endif - let g:vimwiki_syntax_variables[a:syntax].rxListItemWithoutCB = - \ '^\s*\%(\('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\)\|\(' - \ .g:vimwiki_syntax_variables[a:syntax].rxListNumber.'\)\)\s' - let g:vimwiki_syntax_variables[a:syntax].rxListItem = - \ g:vimwiki_syntax_variables[a:syntax].rxListItemWithoutCB - \ . '\+\%(\[\(['.vimwiki#vars#get_global('listsyms') - \ . vimwiki#vars#get_global('listsym_rejected').']\)\]\s\)\?' - if g:vimwiki_syntax_variables[a:syntax].recurring_bullets - let g:vimwiki_syntax_variables[a:syntax].rxListItemAndChildren = - \ '^\('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\)\s\+\[[' - \ . g:vimwiki_syntax_variables[a:syntax].listsyms_list[-1] - \ . vimwiki#vars#get_global('listsym_rejected') . ']\]\s.*\%(\n\%(\1\%(' - \ .g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\).*\|^$\|\s.*\)\)*' - else - let g:vimwiki_syntax_variables[a:syntax].rxListItemAndChildren = - \ '^\(\s*\)\%('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\|' - \ . g:vimwiki_syntax_variables[a:syntax].rxListNumber.'\)\s\+\[[' - \ . g:vimwiki_syntax_variables[a:syntax].listsyms_list[-1] - \ . vimwiki#vars#get_global('listsym_rejected') . ']\]\s.*\%(\n\%(\1\s.*\|^$\)\)*' - endif - " 0. URL : free-standing links: keep URL UR(L) strip trailing punct: URL; URL) UR(L)) " let g:vimwiki_rxWeblink = '[\["(|]\@ Parent items should change when their child items change. If not, use |vimwiki_glr|. The symbol between [ ] depends on the percentage of toggled -child items (see also |g:vimwiki_listsyms|): > +child items (see also |vimwiki-listsyms|): > [ ] -- 0% [.] -- 1-33% [o] -- 34-66% @@ -2510,6 +2510,53 @@ Note: if you use Markdown or MediaWiki syntax, you probably would like to set this option to 0, because every indented line is considered verbatim text. +*vimwiki-bullet_types* +------------------------------------------------------------------------------ +Key Default value~ +bullet_types ['-', '*', '#'] (default-syntax) + ['-', '*', '+'] (markdown-syntax) + ['*', '#'] (mediawiki-syntax) + +List of the characters that can be used as bullets of lists. The default value +depends on the chosen syntax. + +You can set it to include more fancy symbols like this: +> + let g:vimwiki_list = [{'path': '~/path/', 'bullet_types' = ['-', '•', '→']}] + + +*vimwiki-listsyms* +------------------------------------------------------------------------------ +Key Default value~ +listsyms ' .oOX' + +String of at least two symbols to show the progression of todo list items. +Default value is ' .oOX'. This overwrites the global |g:vimwiki_listsyms| on a +per wiki base. + +The first char is for 0% done items. +The last is for 100% done items. + +You can set it to some more fancy symbols like this: +> + let g:vimwiki_list = [{'path': '~/path/', 'listsyms' = '✗○◐●✓'}] + + +*vimwiki-listsym_rejected* +------------------------------------------------------------------------------ + +Character that is used to show that an item of a todo list will not be done. +Default value is '-'. This overwrites the global |g:vimwiki_listsym_rejected| on a +per wiki base. + + +The character used here must not be part of |vimwiki-listsyms|. + +You can set it to a more fancy symbol like this: +> + let g:vimwiki_list = [{'path': '~/path/', 'listsym_rejected' = '✗'}] + + *vimwiki-option-auto_tags* ------------------------------------------------------------------------------ Key Default value Values~ @@ -2694,7 +2741,8 @@ Default: 'Vimwiki' *g:vimwiki_listsyms* String of at least two symbols to show the progression of todo list items. -Default value is ' .oOX'. +Default value is ' .oOX'. You can also set this on a per-wiki level with +|vimwiki-listsyms|. The first char is for 0% done items. The last is for 100% done items. @@ -2708,7 +2756,9 @@ You can set it to some more fancy symbols like this: *g:vimwiki_listsym_rejected* Character that is used to show that an item of a todo list will not be done. -Default value is '-'. +Default value is '-'. You can also set this on a per-wiki level with +|vimwiki-listsym_rejected|. + The character used here must not be part of |g:vimwiki_listsyms|. @@ -3682,6 +3732,9 @@ New:~ * glx on a list item marks a checkbox as won't do, see |vimwiki_glx|. * Add the option |g:vimwiki_listsym_rejected| to set the character used for won't-do list items. + * The effect of |g:vimwiki_listsyms| and |g:vimwiki_listsym_rejected| can + be set on a per wiki level, see |vimwiki-listsyms| and + |vimwili-listsym_rejected| * gln and glp change the "done" status of a checkbox, see |vimwiki_gln|. * |:VimwikiSplitLink| and |:VimwikiVSplitLink| can now reuse an existing split window and not move the cursor. diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim index d14201c..b2f7a01 100644 --- a/ftplugin/vimwiki.vim +++ b/ftplugin/vimwiki.vim @@ -127,7 +127,7 @@ setlocal formatoptions-=o setlocal formatoptions-=2 setlocal formatoptions+=n -let &formatlistpat = vimwiki#vars#get_syntaxlocal('rxListItem') +let &formatlistpat = vimwiki#vars#get_wikilocal('rxListItem') " ------------------------------------------------ diff --git a/syntax/vimwiki.vim b/syntax/vimwiki.vim index b8c9ac6..588954d 100644 --- a/syntax/vimwiki.vim +++ b/syntax/vimwiki.vim @@ -254,18 +254,18 @@ syntax match VimwikiCellSeparator " Lists -execute 'syntax match VimwikiList /'.vimwiki#vars#get_syntaxlocal('rxListItemWithoutCB').'/' +execute 'syntax match VimwikiList /'.vimwiki#vars#get_wikilocal('rxListItemWithoutCB').'/' execute 'syntax match VimwikiList /'.vimwiki#vars#get_syntaxlocal('rxListDefine').'/' -execute 'syntax match VimwikiListTodo /'.vimwiki#vars#get_syntaxlocal('rxListItem').'/' +execute 'syntax match VimwikiListTodo /'.vimwiki#vars#get_wikilocal('rxListItem').'/' if vimwiki#vars#get_global('hl_cb_checked') == 1 - execute 'syntax match VimwikiCheckBoxDone /'.vimwiki#vars#get_syntaxlocal('rxListItemWithoutCB') - \ . '\s*\[['.vimwiki#vars#get_syntaxlocal('listsyms_list')[-1] + execute 'syntax match VimwikiCheckBoxDone /'.vimwiki#vars#get_wikilocal('rxListItemWithoutCB') + \ . '\s*\[['.vimwiki#vars#get_wikilocal('listsyms_list')[-1] \ . vimwiki#vars#get_global('listsym_rejected') \ . ']\]\s.*$/ contains=VimwikiNoExistsLink,VimwikiLink,VimwikiWeblink1,VimwikiWikiLink1,@Spell' elseif vimwiki#vars#get_global('hl_cb_checked') == 2 execute 'syntax match VimwikiCheckBoxDone /' - \ . vimwiki#vars#get_syntaxlocal('rxListItemAndChildren') + \ . vimwiki#vars#get_wikilocal('rxListItemAndChildren') \ .'/ contains=VimwikiNoExistsLink,VimwikiLink,VimwikiWeblink1,VimwikiWikiLink1,@Spell' endif