vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit 188ead55db340fc10e9d5facf40f0ecb42b81985
parent dede5a1eeaa13474beedd07427ad2869ebe4ca7a
Author: Tinmarino <tinmarino@gmail.com>
Date:   Sat,  8 Aug 2020 04:02:15 -0400

Config: Permit tag configuration for syntax, search and match (Issue #922 #928)

Affects: (via user configurated regexp)

- VimwikiGenerateTagLinks
- follow_link
- completion
- Syntax Highlighting

Diffstat:
Mautoload/vimwiki/base.vim | 146+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mautoload/vimwiki/tags.vim | 55++++++++++++++++++++++++++++++-------------------------
Mautoload/vimwiki/vars.vim | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mdoc/vimwiki.txt | 34++++++++++++++++++++++++++++++++++
Mftplugin/vimwiki.vim | 29++++++++++++++++++++---------
Msyntax/vimwiki.vim | 38+++++++++++++++++++++++---------------
Msyntax/vimwiki_default.vim | 4----
Msyntax/vimwiki_markdown.vim | 4----
Msyntax/vimwiki_media.vim | 4----
Dtest/command_generate_tags.vader | 96-------------------------------------------------------------------------------
Atest/tag.vader | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 462 insertions(+), 235 deletions(-)

diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim @@ -453,7 +453,7 @@ function! vimwiki#base#generate_links(create, ...) abort endfunction " Update buffer with generator super power - let links_rx = '\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)' + let links_rx = '\%(^\s*$\)\|^\s*\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)' call vimwiki#base#update_listing_in_buffer( \ GeneratorLinks, \ vimwiki#vars#get_global('links_header'), @@ -617,6 +617,7 @@ endfunction " Parse file. Returns list of all anchors +" Called: vimwiki#base#check_links() for all wiki files function! vimwiki#base#get_anchors(filename, syntax) abort " Clause: if not readable if !filereadable(a:filename) @@ -637,7 +638,7 @@ function! vimwiki#base#get_anchors(filename, syntax) abort " Collect: headers let h_match = matchlist(line, rxheader) if !empty(h_match) - let header = vimwiki#u#trim(h_match[2]) + let header = vimwiki#base#normalize_anchor(h_match[2]) " Mesure: header level let level = len(h_match[1]) call add(anchors, header) @@ -654,8 +655,8 @@ function! vimwiki#base#get_anchors(filename, syntax) abort let current_complete_anchor .= anchor_level[l].'#' endif endfor - " TODO: should not that be out of the if branch ? let current_complete_anchor .= header + " TODO: should not that be out of the if branch ? call add(anchors, current_complete_anchor) endif endif @@ -681,7 +682,8 @@ function! vimwiki#base#get_anchors(filename, syntax) abort if tag_group_text ==? '' break endif - for tag_text in split(tag_group_text, ':') + let sep = vimwiki#vars#get_syntaxlocal('tag_format', a:syntax).sep + for tag_text in split(tag_group_text, sep) call add(anchors, tag_text) if current_complete_anchor !=? '' call add(anchors, current_complete_anchor.'#'.tag_text) @@ -712,7 +714,8 @@ endfunction " :param: (1) previous_anchors <dic[IN/OUT]> of previous normalized anchor " -- to know if must append -2, updated on the fly " Return: anchor <string> => link in TOC -function! s:normalize_anchor(anchor, ...) abort +" Called: vimwiki#base#table_of_contents +function! vimwiki#base#normalize_anchor(anchor, ...) abort " Note: See unormalize " 0 Get in let anchor = a:anchor @@ -756,7 +759,7 @@ endfunction " -- with or without suffix " -- Ex: ['toto", 2] => search for the second occurrence of toto " Called: jump_to_anchor -function! s:unnormalize_anchor(anchor) abort +function! vimwiki#base#unnormalize_anchor(anchor) abort " Note: " -- Pandoc keep the '_' in anchor " -- Done after: Add spaces leading and trailing => Later with the template @@ -832,84 +835,85 @@ function! s:jump_to_anchor(anchor) abort for segment in segments " Craft segment pattern so that it is case insensitive and also matches dashes " in anchor link with spaces in heading - let [segment_re, segment_nb, segment_suffix] = s:unnormalize_anchor(segment) + let [segment_norm_re, segment_nb, segment_suffix] = vimwiki#base#unnormalize_anchor(segment) " Try once with suffix (If header ends with number) - let res = s:jump_to_segment(segment_re . segment_suffix, 1) + let res = s:jump_to_segment(segment, segment_norm_re . segment_suffix, 1) " Try segment_nb times otherwise if res != 0 - let res = s:jump_to_segment(segment_re, segment_nb) + let res = s:jump_to_segment(segment, segment_norm_re, segment_nb) endif endfor endfunction " Called: jump_to_anchor with suffix and withtou suffix -function! s:jump_to_segment(segment_re, segment_nb) abort - " Save cursor %% Initialize at top of line - let oldpos = getpos('.') - call cursor(1, 1) - - let anchor_header = s:safesubstitute( - \ vimwiki#vars#get_syntaxlocal('header_match'), - \ '__Header__', a:segment_re, 'g') - let anchor_bold = s:safesubstitute( - \ vimwiki#vars#get_syntaxlocal('bold_match'), - \ '__Text__', a:segment_re, 'g') - let anchor_tag = s:safesubstitute( - \ vimwiki#vars#get_syntaxlocal('tag_match'), - \ '__Tag__', a:segment_re, 'g') - - " Go: Move cursor: maybe more than onces (see markdown suffix) - let success_nb = 0 - let is_last_segment = 0 - for i in range(a:segment_nb) - " Search - let pos = 0 - let pos = pos != 0 ? pos : search(anchor_tag, 'Wc') - let pos = pos != 0 ? pos : search(anchor_header, 'Wc') - let pos = pos != 0 ? pos : search(anchor_bold, 'Wc') - - " Succed: Get the result and reloop or leave - if pos != 0 - " Avance, one line more to not rematch the same pattern if not last segment_nb - if success_nb < a:segment_nb-1 - let pos += 1 - let is_last_segment = -1 - endif - call cursor(pos, 1) - let success_nb += 1 - - " Break if last line (avoid infinite loop) - " Anyway leave the loop: (Imagine heading # 7271212 at last line) - if pos >= line('$') - return 0 - endif - " Fail: - " Do not move - " But maybe suffix -2 is not the segment number but the real header suffix - else - " If fail at first: do not move - if i == 0 - call setpos('.', oldpos) - endif - " Anyway leave the loop: (Imagine heading # 7271212, you do not want to loop all that) - " Go one line back: if I advanced too much - if is_last_segment == -1 | call cursor(line('.')-1, 1) | endif - return 1 +function! s:jump_to_segment(segment, segment_norm_re, segment_nb) abort + " Save cursor %% Initialize at top of line + let oldpos = getpos('.') + call cursor(1, 1) + + " Get anchor regex + let anchor_header = s:safesubstitute( + \ vimwiki#vars#get_syntaxlocal('header_match'), + \ '__Header__', a:segment_norm_re, 'g') + let anchor_bold = s:safesubstitute( + \ vimwiki#vars#get_syntaxlocal('bold_match'), + \ '__Text__', a:segment, 'g') + let anchor_tag = s:safesubstitute( + \ vimwiki#vars#get_syntaxlocal('tag_match'), + \ '__Tag__', a:segment, 'g') + + " Go: Move cursor: maybe more than onces (see markdown suffix) + let success_nb = 0 + let is_last_segment = 0 + for i in range(a:segment_nb) + " Search + let pos = 0 + let pos = pos != 0 ? pos : search(anchor_tag, 'Wc') + let pos = pos != 0 ? pos : search(anchor_header, 'Wc') + let pos = pos != 0 ? pos : search(anchor_bold, 'Wc') + + " Succeed: Get the result and reloop or leave + if pos != 0 + " Avance, one line more to not rematch the same pattern if not last segment_nb + if success_nb < a:segment_nb-1 + let pos += 1 + let is_last_segment = -1 endif - endfor + call cursor(pos, 1) + let success_nb += 1 - " Check if happy - if success_nb == a:segment_nb - return 0 + " Break if last line (avoid infinite loop) + " Anyway leave the loop: (Imagine heading # 7271212 at last line) + if pos >= line('$') + return 0 + endif + " Fail: + " Do not move + " But maybe suffix -2 is not the segment number but the real header suffix + else + " If fail at first: do not move + if i == 0 + call setpos('.', oldpos) + endif + " Anyway leave the loop: (Imagine heading # 7271212, you do not want to loop all that) + " Go one line back: if I advanced too much + if is_last_segment == -1 | call cursor(line('.')-1, 1) | endif + return 1 endif + endfor + + " Check if happy + if success_nb == a:segment_nb + return 0 + endif - " Or keep on (i.e more than once segment) - let oldpos = getpos('.') + " Or keep on (i.e more than once segment) + let oldpos = getpos('.') - " Said 'fail' to caller - return 1 + " Said 'fail' to caller + return 1 endfunction @@ -2482,7 +2486,7 @@ function! vimwiki#base#table_of_contents(create) abort endif " Normalize anchor - let anchor = s:normalize_anchor(anchor, previous_anchors) + let anchor = vimwiki#base#normalize_anchor(anchor, previous_anchors) " Insert link in template let link = s:safesubstitute(link_tpl, '__LinkUrl__', @@ -2494,7 +2498,7 @@ function! vimwiki#base#table_of_contents(create) abort return lines endfunction - let links_rx = '\%(^\s*$\)\|\%(^\s*\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)\)' + let links_rx = '\%(^\s*$\)\|^\s*\%(\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)\)' call vimwiki#base#update_listing_in_buffer( \ GeneratorTOC, \ toc_header_text, diff --git a/autoload/vimwiki/tags.vim b/autoload/vimwiki/tags.vim @@ -70,14 +70,15 @@ endfunction " Scan the list of text lines (argument) and produces tags metadata as a list of tag entries. function! s:scan_tags(lines, page_name) abort - - let entries = [] - " Code wireframe to scan for headers -- borrowed from " vimwiki#base#get_anchors(), with minor modifications. + let entries = [] + + " Get syntax wide regex let rxheader = vimwiki#vars#get_syntaxlocal('header_search') - let rxtag = vimwiki#vars#get_syntaxlocal('tag_search') + let tag_search_rx = vimwiki#vars#get_syntaxlocal('tag_search') + let tag_format = vimwiki#vars#get_syntaxlocal('tag_format') let anchor_level = ['', '', '', '', '', '', ''] let current_complete_anchor = '' @@ -97,7 +98,7 @@ function! s:scan_tags(lines, page_name) abort let h_match = matchlist(line, rxheader) if !empty(h_match) " got a header let header_line_nr = line_nr - let header = vimwiki#u#trim(h_match[2]) + let header = vimwiki#base#normalize_anchor(h_match[2]) let level = len(h_match[1]) let anchor_level[level-1] = header for l in range(level, 6) @@ -120,28 +121,32 @@ function! s:scan_tags(lines, page_name) abort " Scan line for tags. There can be many of them. let str = line while 1 - let tag_group = matchstr(str, rxtag) - if tag_group ==? '' + " Get all matches + let tag_groups = [] + call substitute(str, tag_search_rx, '\=add(tag_groups, submatch(0))', 'g') + if tag_groups == [] break endif - let tagend = matchend(str, rxtag) + let tagend = matchend(str, tag_search_rx) let str = str[(tagend):] - for tag in split(tag_group, ':') - " Create metadata entry - let entry = {} - let entry.tagname = tag - let entry.lineno = line_nr - if line_nr <= PROXIMITY_LINES_NR && header_line_nr < 0 - " Tag appeared at the top of the file - let entry.link = a:page_name - elseif line_nr <= (header_line_nr + PROXIMITY_LINES_NR) - " Tag appeared right below a header - let entry.link = a:page_name . '#' . current_complete_anchor - else - " Tag stands on its own - let entry.link = a:page_name . '#' . tag - endif - call add(entries, entry) + for tag_group in tag_groups + for tag in split(tag_group, tag_format.sep) + " Create metadata entry + let entry = {} + let entry.tagname = tag + let entry.lineno = line_nr + if line_nr <= PROXIMITY_LINES_NR && header_line_nr < 0 + " Tag appeared at the top of the file + let entry.link = a:page_name + elseif line_nr <= (header_line_nr + PROXIMITY_LINES_NR) + " Tag appeared right below a header + let entry.link = a:page_name . '#' . current_complete_anchor + else + " Tag stands on its own + let entry.link = a:page_name . '#' . tag + endif + call add(entries, entry) + endfor endfor endwhile @@ -391,7 +396,7 @@ function! vimwiki#tags#generate_tags(create, ...) abort let tag_match = printf('rxH%d', header_level + 1) let links_rx = '^\%('.vimwiki#vars#get_syntaxlocal(tag_match).'\)\|'. - \ '\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)' + \ '\%(^\s*$\)\|^\s*\%('.vimwiki#vars#get_syntaxlocal('rxListBullet').'\)' call vimwiki#base#update_listing_in_buffer( \ GeneratorTags, diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim @@ -38,7 +38,7 @@ endfunction " ---------------------------------------------------------- -" 1. Global +" 1. Global {{{1 " ---------------------------------------------------------- " Populate global variable <- user & default @@ -337,12 +337,15 @@ endfunction " ---------------------------------------------------------- -" 2. Buffer local +" 2. Buffer local {{{1 " ---------------------------------------------------------- " Populate local variable <- user & default " Called: s:vimwiki#vars#init function! s:populate_wikilocal_options() abort + " Warning Dev: if type is dict, + " -- the default dict gets extended and not replaced: keys are not deleted + " Init local variable container let g:vimwiki_wikilocal_vars = [] @@ -393,6 +396,14 @@ function! s:populate_wikilocal_options() abort \ 'template_ext': {'type': type(''), 'default': '.tpl'}, \ 'template_path': {'type': type(''), 'default': $HOME . '/vimwiki/templates/'}, \ 'text_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, + \ 'tag_format': {'type': type({}), 'default': { + \ 'pre': '^\|\s', + \ 'pre_mark': ':', + \ 'in': '[^:''[:space:]]\+', + \ 'sep': ':', + \ 'post_mark': ':', + \ 'post': '\s\|$', + \ 'conceal': 0, 'cchar':''}}, \ 'toc_header': {'type': type(''), 'default': 'Contents', 'min_length': 1}, \ 'toc_header_level': {'type': type(0), 'default': 1, 'min': 1, 'max': 6}, \ 'toc_link_format': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, @@ -402,8 +413,16 @@ function! s:populate_wikilocal_options() abort let default_wiki_settings = {} for key in keys(default_values) if exists('g:vimwiki_'.key) + " Check type call s:check_users_value(key, g:vimwiki_{key}, default_values[key], 1) - let default_wiki_settings[key] = g:vimwiki_{key} + " Update if dict + if default_values[key]['type'] == type({}) + let default_wiki_settings[key] = default_values[key].default + call extend(default_wiki_settings[key], g:vimwiki_{key}) + " Set if other var + else + let default_wiki_settings[key] = g:vimwiki_{key} + endif else let default_wiki_settings[key] = default_values[key].default endif @@ -419,7 +438,14 @@ function! s:populate_wikilocal_options() abort if key ==# 'list_margin' let s:margin_set_by_user = 1 endif - let new_wiki_settings[key] = users_wiki_settings[key] + " Update if dict + if default_values[key]['type'] == type({}) + let new_wiki_settings[key] = extend({}, default_values[key].default) + let new_wiki_settings[key] = extend(new_wiki_settings.key, users_wiki_settings[key]) + " Set if other var + else + let new_wiki_settings[key] = users_wiki_settings[key] + endif else let new_wiki_settings[key] = default_wiki_settings[key] endif @@ -578,7 +604,7 @@ endfunction " ---------------------------------------------------------- -" 3. Syntax specific +" 3. Syntax specific {{{1 " ---------------------------------------------------------- " Populate syntax variable @@ -615,6 +641,42 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort let syntax_dic['cycle_bullets'] = \ vimwiki#vars#get_wikilocal('cycle_bullets') + " Tag: get var + let syntax_dic.tag_format = {} + let tf = syntax_dic.tag_format + call extend(tf, vimwiki#vars#get_wikilocal('tag_format')) + + " Tag: Close regex + for key in ['pre', 'pre_mark', 'in', 'sep', 'post_mark', 'post'] + let tf[key] = '\%(' . tf[key] . '\)' + endfor + + " Match \s<tag[:tag:tag:tag...]>\s + " Tag: highlighting + " Used: syntax/vimwiki.vim + let syntax_dic.rxTags = + \ tf.pre . '\@<=' . tf.pre_mark . tf.in + \ . '\%(' . tf.sep . tf.in . '\)*' + \ . tf.post_mark . tf.post . '\@=' + + " Tag: searching for all + " Used: vimwiki#base#get_anchors <- GenerateTagLinks + let syntax_dic.tag_search = + \ tf.pre . tf.pre_mark . '\zs' + \ . tf.in . '\%(' . tf.sep . tf.in . '\)*' + \ . '\ze' . tf.post_mark . tf.post + + " Tag: matching a specific: when goto tag + " Used: tags.vim->s:scan_tags + " Match <[tag:tag:...tag:]__TAG__[:tag...:tag]> + let syntax_dic.tag_match = + \ tf.pre . tf.pre_mark + \ . '\%(' . tf.in . tf.sep . '\)*' + \ . '__Tag__' + \ . '\%(' . tf.sep . tf.in . '\)*' + \ . tf.post_mark . tf.post + + " Populate generic stuff let header_symbol = syntax_dic.rxH if syntax_dic.symH @@ -771,7 +833,7 @@ function! s:populate_list_vars(wiki) abort let a:wiki.multiple_bullet_chars = \ recurring_bullets \ ? a:wiki.bullet_types : [] - + " Create regexp for bulleted list items if !empty(a:wiki.bullet_types) let rxListBullet = @@ -1007,7 +1069,7 @@ endfunction " ---------------------------------------------------------- -" 4. Getter, Setter (exported) +" 4. Getter, Setter (exported) {{{1 " ---------------------------------------------------------- " Get syntax variable diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt @@ -3598,6 +3598,39 @@ Value Description~ Default: 3 +------------------------------------------------------------------------------ +*g:vimwiki_tag_format* + +Dictionary to describe the format of the tags vimwiki uses to highlight, +generate and follow_link + +| Key | Default | Description +----------------------------------------------------- ReGeX +| pre | '^\|\s' | Limitations to tag precedence +| pre_mark | ':' | Tag list opener +| in | '[:space:]]\+' | Tag permitted characters +| sep | ':' | Tag separators in a tag list +| post_mark | ':' | Tag list closer +| post | '\s\|$' | Limitations to tag following +----------------------------------------------------- Number +| conceal | 0 | Do conceal the tag +----------------------------------------------------- Character +| cchar | '' | If conceal, the conceal char + + +The default dictionary gets |extends| with the user provided dictionary. So it +is only necessary to provide the values to change. For Example, to use a: +- Tag like: > + <<tag1|tag2>> +- Set: > + let g:vimwiki_tag_format = {'pre_mark': '<<', 'post_mark': '>>', 'sep': '|'} +- Tag like: > + tags: @tag1 @tag2 +- Set: > + let g:vimwiki_tag_format = {'pre': '\(^[ -]*tags\s*: .*\)\@<=', + \ 'pre_mark': '@', 'post_mark': '', 'sep': '>><<'} + + ============================================================================== 13. Getting help *vimwiki-help* @@ -3741,6 +3774,7 @@ http://code.google.com/p/vimwiki/issues/list. They may be accessible from https://github.com/vimwiki-backup/vimwiki/issues. New:~ + * Feature: #922 #928: g:vimwiki_tag_format to change the tag format * Feature: Support Emoji (Conceal and Complete) * Issue #209: Feature: Markdown: Support SetExt Heading * Issue #847 #640: Feature: Markdown anchor diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim @@ -22,26 +22,38 @@ exe 'setlocal tags+=' . escape(vimwiki#tags#metadata_file_path(), ' \|"') " Help for omnicompletion function! Complete_wikifiles(findstart, base) abort + " s:line_context = link | tag | '' if a:findstart == 1 + " Find line context + " Called: first time let column = col('.')-2 let line = getline('.')[:column] + + " Check Link: + " -- WikiLink let startoflink = match(line, '\[\[\zs[^\\[\]]*$') if startoflink != -1 - let s:line_context = '[' + let s:line_context = 'link' return startoflink endif + " -- WebLink if vimwiki#vars#get_wikilocal('syntax') ==? 'markdown' let startofinlinelink = match(line, '\[.*\](\zs[^)]*$') if startofinlinelink != -1 - let s:line_context = '[' + let s:line_context = 'link' return startofinlinelink endif endif - let startoftag = match(line, ':\zs[^:[:space:]]*$') + + " Check Tag: + let tf = vimwiki#vars#get_syntaxlocal('tag_format') + let startoftag = match(line, tf.pre_mark . '\zs' . tf.in . '*$') if startoftag != -1 - let s:line_context = ':' + let s:line_context = 'tag' return startoftag endif + + " Nothing can do ... let s:line_context = '' return -1 else @@ -50,8 +62,8 @@ function! Complete_wikifiles(findstart, base) abort " solution, because calling col('.') here returns garbage. if s:line_context ==? '' return [] - elseif s:line_context ==# ':' - " Tags completion + elseif s:line_context ==# 'tag' + " Look Tags: completion let tags = vimwiki#tags#get_tags() if a:base !=? '' call filter(tags, @@ -59,8 +71,7 @@ function! Complete_wikifiles(findstart, base) abort endif return tags elseif a:base !~# '#' - " we look for wiki files - + " Look Wiki: files if a:base =~# '\m^wiki\d\+:' let wikinumber = eval(matchstr(a:base, '\m^wiki\zs\d\+')) if wikinumber >= vimwiki#vars#number_of_wikis() @@ -88,7 +99,7 @@ function! Complete_wikifiles(findstart, base) abort return result else - " we look for anchors in the given wikifile + " Look Anchor: in the given wikifile let segments = split(a:base, '#', 1) let given_wikifile = segments[0] ==? '' ? expand('%:t:r') : segments[0] diff --git a/syntax/vimwiki.vim b/syntax/vimwiki.vim @@ -141,11 +141,11 @@ else endif -" Weblink [DESCRIPTION](FILE) +" Weblink: [DESCRIPTION](FILE) call s:add_target_syntax_ON(vimwiki#vars#get_syntaxlocal('rxWeblink'), 'VimwikiLink') -" WikiLink +" WikiLink: " All remaining schemes are highlighted automatically let s:rxSchemes = '\%('. \ vimwiki#vars#get_global('schemes') . '\|'. @@ -180,7 +180,7 @@ call s:add_target_syntax_ON(s:target, 'VimwikiLink') -" Header levels, 1-6 +" Header Level: 1..6 for s:i in range(1,6) execute 'syntax match VimwikiHeader'.s:i \ . ' /'.vimwiki#vars#get_syntaxlocal('rxH'.s:i, s:current_syntax). @@ -192,7 +192,7 @@ for s:i in range(1,6) \ '/me=s-1 transparent fold' endfor -" SetExt header +" SetExt Header: " TODO mutualise SetExt Regexp let setex_header1_re = '^\s\{0,3}[^>].*\n\s\{0,3}==\+$' let setex_header2_re = '^\s\{0,3}[^>].*\n\s\{0,3}--\+$' @@ -244,7 +244,7 @@ execute 'syntax match VimwikiTodo /'. vimwiki#vars#get_global('rxTodo') .'/' -" Tables +" Table: syntax match VimwikiTableRow /^\s*|.\+|\s*$/ \ transparent contains=VimwikiCellSeparator, \ VimwikiLinkT, @@ -265,12 +265,12 @@ syntax match VimwikiTableRow /^\s*|.\+|\s*$/ syntax match VimwikiCellSeparator /\%(|\)\|\%(-\@<=+\-\@=\)\|\%([|+]\@<=-\+\)/ contained -" Lists +" List: 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_wikilocal('rxListItem').'/' -" Task list done +" Task List Done: if vimwiki#vars#get_global('hl_cb_checked') == 1 execute 'syntax match VimwikiCheckBoxDone /'.vimwiki#vars#get_wikilocal('rxListItemWithoutCB') \ . '\s*\[['.vimwiki#vars#get_wikilocal('listsyms_list')[-1] @@ -284,7 +284,7 @@ elseif vimwiki#vars#get_global('hl_cb_checked') == 2 endif -" <hr> horizontal rule +" Horizontal Rule: <hr> execute 'syntax match VimwikiHR /'.vimwiki#vars#get_syntaxlocal('rxHR').'/' let concealpre = vimwiki#vars#get_global('conceal_pre') ? ' concealends' : '' @@ -295,7 +295,7 @@ execute 'syntax region VimwikiMath start=/'.vimwiki#vars#get_syntaxlocal('rxMath \ '/ end=/'.vimwiki#vars#get_syntaxlocal('rxMathEnd').'/ contains=@NoSpell' -" placeholders +" Placeholder: syntax match VimwikiPlaceholder /^\s*%nohtml\s*$/ syntax match VimwikiPlaceholder \ /^\s*%title\ze\%(\s.*\)\?$/ nextgroup=VimwikiPlaceholderParam skipwhite @@ -306,17 +306,25 @@ syntax match VimwikiPlaceholder syntax match VimwikiPlaceholderParam /.*/ contained -" html tags <u> +" Html Tag: <u> if vimwiki#vars#get_global('valid_html_tags') !=? '' " Include: Source html file here execute 'source ' . expand('<sfile>:h') . '/vimwiki_html.vim' endif -" tags -execute 'syntax match VimwikiTag /'.vimwiki#vars#get_syntaxlocal('rxTags').'/' +" Tag: +let tag_cmd = 'syntax match VimwikiTag /'.vimwiki#vars#get_syntaxlocal('rxTags').'/' +let tf = vimwiki#vars#get_wikilocal('tag_format') +if exists('+conceallevel') && tf.conceal != 0 + let tag_cmd .= ' conceal' + if tf.cchar !=# '' + let tag_cmd .= ' cchar=' . tf.cchar + endif +endif +execute tag_cmd -" header groups highlighting +" Header Groups: highlighting if vimwiki#vars#get_global('hl_headers') == 0 " Strangely in default colorscheme Title group is not set to bold for cterm... if !exists('g:colors_name') @@ -334,12 +342,12 @@ else endif -" Highlight Typefaces -> u.vim +" Typeface: -> u.vim let s:typeface_dic = vimwiki#vars#get_syntaxlocal('dTypeface') call vimwiki#u#hi_typeface(s:typeface_dic) -" Emoji :dog: (after tags to take precedence) +" Emoji: :dog: (after tags to take precedence) if and(vimwiki#vars#get_global('emoji_enable'), 1) != 0 && has('conceal') call vimwiki#emoji#apply_conceal() endif diff --git a/syntax/vimwiki_default.vim b/syntax/vimwiki_default.vim @@ -68,7 +68,6 @@ let s:default_syntax.rxMathEnd = '}}\$' let s:default_syntax.rxMultilineCommentStart = '%%+' let s:default_syntax.rxMultilineCommentEnd = '+%%' let s:default_syntax.rxComment = '^\s*%%.*$' -let s:default_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:''[:space:]]\+:\)\+\%(\s\|$\)\@=' let s:default_syntax.header_search = '^\s*\(=\{1,6}\)\([^=].*[^=]\)\1\s*$' let s:default_syntax.header_match = '^\s*\(=\{1,6}\)=\@!\s*__Header__\s*\1=\@!\s*$' @@ -77,6 +76,3 @@ let s:default_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs\%([^*`[:spa let s:default_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'. \ '\%([[:punct:]]\|\s\|$\)\@=' let s:default_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]' -let s:default_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)' -let s:default_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'. - \ '\([^:[:space:]]\+:\)*\(\s\|$\)' diff --git a/syntax/vimwiki_markdown.vim b/syntax/vimwiki_markdown.vim @@ -61,7 +61,6 @@ let s:markdown_syntax.rxMathEnd = '\$\$' let s:markdown_syntax.rxMultilineCommentStart = '' let s:markdown_syntax.rxMultilineCommentEnd = '' let s:markdown_syntax.rxComment = '^\s*%%.*$\|<!--[^>]*-->' -let s:markdown_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@=' " Used in code (base.vim) @@ -87,6 +86,3 @@ let s:markdown_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs'. let s:markdown_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'. \ '\%([[:punct:]]\|\s\|$\)\@=' let s:markdown_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]' -let s:markdown_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)' -let s:markdown_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'. - \ '\([^:[:space:]]\+:\)*\(\s\|$\)' diff --git a/syntax/vimwiki_media.vim b/syntax/vimwiki_media.vim @@ -58,7 +58,6 @@ let s:media_syntax.rxMathEnd = '}}\$' let s:media_syntax.rxMultilineCommentStart = '' let s:media_syntax.rxMultilineCommentEnd = '' let s:media_syntax.rxComment = '^\s*%%.*$' -let s:media_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@=' let s:media_syntax.header_search = '^\s*\(=\{1,6}\)\([^=].*[^=]\)\1\s*$' let s:media_syntax.header_match = '^\s*\(=\{1,6}\)=\@!\s*__Header__\s*\1=\@!\s*$' @@ -67,6 +66,3 @@ let s:media_syntax.bold_match = '''''''__Text__''''''' " ^- this strange looking thing is equivalent to "'''__Text__'''" but since we later " want to call escape() on this string, we must keep it in single quotes let s:media_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]' -let s:media_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)' -let s:media_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'. - \ '\([^:[:space:]]\+:\)*\(\s\|$\)' diff --git a/test/command_generate_tags.vader b/test/command_generate_tags.vader @@ -1,96 +0,0 @@ -# Tag generation - -Execute (Copy Wiki's Resources): - Log "Start: Copy Resources" - call CopyResources() - -Execute (Setup): - set sw=4 - AssertEqual 4, &sw - -Execute (Edit Test-Tag.md): - edit $HOME/testmarkdown/Test-Tag.md - AssertEqual $HOME . '/testmarkdown/Test-Tag.md', expand('%') - AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax') - AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr') - -Do (Create File Content): - :edit $HOME/testmarkdown/Test-Tag.md\<CR> - I - :top-tag:\<CR> - \<CR> - # A header\<CR> - \<CR> - :test-tag:\<CR> - \<CR> - # Another header\<CR> - \<CR> - Words here.\<CR> - If tag isn't within 2 lines of header then it has a direct link instead of\<CR> - a link to the header.\<CR> - \<CR> - :second-tag: - \<Esc> - :write\<CR> - :VimwikiRebuildTags\<CR> - -Execute (Edit tags file): - edit $HOME/testmarkdown/.vimwiki_tags - AssertEqual $HOME . '/testmarkdown/.vimwiki_tags', expand('%') - AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax') - AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr') - -# Note: tags file uses tabs -Expect (Correctly formatted tags file): - !_TAG_FILE_FORMAT 2 - !_TAG_FILE_SORTED 1 - !_TAG_OUTPUT_MODE vimwiki-tags - !_TAG_PROGRAM_AUTHOR Vimwiki - !_TAG_PROGRAM_NAME Vimwiki Tags - !_TAG_PROGRAM_URL https://github.com/vimwiki/vimwiki - !_TAG_PROGRAM_VERSION 2.5 - second-tag Test-Tag.md 13;" vimwiki:Test-Tag\tTest-Tag#second-tag - test-tag Test-Tag.md 5;" vimwiki:Test-Tag\tTest-Tag#A header - top-tag Test-Tag.md 1;" vimwiki:Test-Tag\tTest-Tag - -Execute (Generate tags): - edit $HOME/testmarkdown/Test-Tag.md - VimwikiGenerateTagLinks - -Expect (Correctly generated tags section): - :top-tag: - - # A header - - :test-tag: - - # Another header - - Words here. - If tag isn't within 2 lines of header then it has a direct link instead of - a link to the header. - - :second-tag: - - # Generated Tags - - ## second-tag - - - [second-tag](Test-Tag#second-tag) - - ## test-tag - - - [A header](Test-Tag#A header) - - ## top-tag - - - [Test-Tag](Test-Tag) - -Execute (Clean Test-Tag and .vimwiki_tags): - Log "End: Clean" - call system("rm $HOME/testmarkdown/Test.md") - call system("rm $HOME/testmarkdown/.vimwiki_tags") - call system("rm $HOME/testmarkdown/Test-Tag.md") - call DeleteHiddenBuffers() - -# vim: sw=2:foldlevel=30:foldmethod=indent: diff --git a/test/tag.vader b/test/tag.vader @@ -0,0 +1,211 @@ +# Tag generation and navigation +# Note: The Generate must be in Execute + +Execute (Copy Wiki's Resources): + Log "Start: Copy Resources" + call CopyResources() + +Execute (Setup): + set sw=4 + AssertEqual 4, &sw + + +###################################################################### +Execute (Change delimiter <tag1|tag2> {{{1): + let g:vimwiki_tag_format = {'pre_mark': '<', 'post_mark': '>', 'sep': '|'} + unlet g:vimwiki_syntax_variables + call vimwiki#vars#init() + edit $HOME/testmarkdown/Test-Tag.md + AssertEqual $HOME . '/testmarkdown/Test-Tag.md', expand('%') + AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax') + AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr') + +Do (Create File Content with <>): + :edit $HOME/testmarkdown/Test-Tag.md\<CR> + I + <tag-bar-1>\<CR> + \<CR> + # A header\<CR> + \<CR> + <tag-bar-2|tag-bar-3>\<CR> + \<CR> + # Another header\<CR> + \<CR> + Words here. + \<Esc> + :write\<CR> + :VimwikiRebuildTags!\<CR> + gg + + +Execute (Generate tags): + edit $HOME/testmarkdown/Test-Tag.md + AssertEqual 'VimwikiTag', SyntaxAt(1, 1) + VimwikiGenerateTagLinks + set tw=200 + +Expect (Correctly generated tags section {{{3): + <tag-bar-1> + + # A header + + <tag-bar-2|tag-bar-3> + + # Another header + + Words here. + + # Generated Tags + + ## tag-bar-1 + + - [Test-Tag](Test-Tag) + + ## tag-bar-2 + + - [a-header](Test-Tag#a-header) + + ## tag-bar-3 + + - [a-header](Test-Tag#a-header) + + +Do (Write a quick tag for a quick jump): + :edit $HOME/testmarkdown/Test-Tag.md\<CR> + ggdG + I + [go1](Test-Tag#tag-bar-1)\<Cr> + [go2](#tag-bar-1)\<Cr> + bla\<Cr> + <tag-bar-1>\<Esc> + ggl\<Cr>A __HERE1__\<Esc> + ggjl\<Cr>A __HERE2__\<Esc> + +Expect (Good jump {{{3): + [go1](Test-Tag#tag-bar-1) + [go2](#tag-bar-1) + bla + <tag-bar-1> __HERE1__ __HERE2__ + +Execute (Clean Test-Tag and .vimwiki_tags -2): + let g:vimwiki_tag_format = {} + unlet g:vimwiki_syntax_variables + call vimwiki#vars#init() + call system("rm $HOME/testmarkdown/Test.md") + call system("rm $HOME/testmarkdown/.vimwiki_tags") + call system("rm $HOME/testmarkdown/Test-Tag.md") + call DeleteHiddenBuffers() + + +###################################################################### +Execute (Default tag generation {{{1): + edit $HOME/testmarkdown/Test-Tag.md + AssertEqual $HOME . '/testmarkdown/Test-Tag.md', expand('%') + AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax') + AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr') + set tw=200 + +Do (Single file Part1): + :edit $HOME/testmarkdown/Test-Tag.md\<Cr> + ggdGO + :single-tag:\<Esc> + :write\<Cr> + :VimwikiRebuildTags!\<Cr> + +Execute (Generate tags): + edit $HOME/testmarkdown/Test-Tag.md + AssertEqual 'VimwikiTag', SyntaxAt(1, 1) + VimwikiGenerateTagLinks + write + +Expect (Single tags toc): + :single-tag: + + + # Generated Tags + + ## single-tag + + - [Test-Tag](Test-Tag) + + +Do (Create File Content): + :edit $HOME/testmarkdown/Test-Tag.md\<CR> + ggdGO + :top-tag:\<CR> + \<CR> + # A header\<CR> + \<CR> + :test-tag:\<CR> + \<CR> + # Another header\<CR> + \<CR> + Words here.\<CR> + If tag isn't within 2 lines of header then it has a direct link instead of\<CR> + a link to the header.\<CR> + \<CR> + :second-tag: + \<Esc> + :write\<CR> + :VimwikiRebuildTags\<CR> + +Execute (Edit tags file): + edit $HOME/testmarkdown/.vimwiki_tags + AssertEqual $HOME . '/testmarkdown/.vimwiki_tags', expand('%') + AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax') + AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr') + +# Note: tags file uses tabs +Expect (Correctly formatted tags file): + !_TAG_FILE_FORMAT 2 + !_TAG_FILE_SORTED 1 + !_TAG_OUTPUT_MODE vimwiki-tags + !_TAG_PROGRAM_AUTHOR Vimwiki + !_TAG_PROGRAM_NAME Vimwiki Tags + !_TAG_PROGRAM_URL https://github.com/vimwiki/vimwiki + !_TAG_PROGRAM_VERSION 2.5 + second-tag Test-Tag.md 13;" vimwiki:Test-Tag\tTest-Tag#second-tag + test-tag Test-Tag.md 5;" vimwiki:Test-Tag\tTest-Tag#a-header + top-tag Test-Tag.md 1;" vimwiki:Test-Tag\tTest-Tag + +Execute (Generate tags): + edit $HOME/testmarkdown/Test-Tag.md + VimwikiGenerateTagLinks + +Expect (Correctly generated tags section): + :top-tag: + + # A header + + :test-tag: + + # Another header + + Words here. + If tag isn't within 2 lines of header then it has a direct link instead of + a link to the header. + + :second-tag: + + + # Generated Tags + + ## second-tag + + - [second-tag](Test-Tag#second-tag) + + ## test-tag + + - [a-header](Test-Tag#a-header) + + ## top-tag + + - [Test-Tag](Test-Tag) + +Execute (Clean Test-Tag and .vimwiki_tags -1 ): + call system("rm $HOME/testmarkdown/Test.md") + call system("rm $HOME/testmarkdown/.vimwiki_tags") + call system("rm $HOME/testmarkdown/Test-Tag.md") + call DeleteHiddenBuffers() + +# vim: sw=2:foldlevel=30:foldmethod=marker: