vimwiki

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

commit 8bf4d6363cc51367bcd4180f1efc84528ebf0049
parent 34ceee8aaa760d2afc2b220916c8844575fd8d17
Author: Tinmarino <tinmarino@gmail.com>
Date:   Mon, 13 Mar 2023 16:52:57 -0300

Syntax: Add highlithing for YAML metadata block (#1287)

Diffstat:
Mautoload/vimwiki/vars.vim | 14++++++++++++++
Mdoc/vimwiki.txt | 19++++++++++++++++++-
Msyntax/vimwiki.vim | 11+++++++++++
Atest/issue_1287_yaml_header.vader | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/vimrc | 28++++++++++++++++++++++------
5 files changed, 160 insertions(+), 7 deletions(-)

diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim @@ -673,6 +673,7 @@ endfunction function! s:get_default_syntaxlocal() abort " Get default syntaxlocal variable dictionary " type, default, min, max, possible_values, min_length + return extend(s:get_common_syntaxlocal(), { \ 'bold_match': {'type': type(''), 'default': '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*\%([[:punct:]]\|\s\|$\)\@='}, \ 'bold_search': {'type': type(''), 'default': '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)\ze\*\%([[:punct:]]\|\s\|$\)\@='}, @@ -815,10 +816,23 @@ endfunction function! s:get_common_syntaxlocal() abort let res = {} + + " Declare helper: a line with only --- or ... + let rx_yaml_start_pre = '\%(^\%(\%1l\|^$\n\)\@<=\)' + let rx_yaml_start_post = '\%(\%(\n^$\)\@!$\)' + let a_yaml_region = [] + for rx_yaml_delimiter in ['---', '\.\.\.'] + let rx_yaml_start = rx_yaml_start_pre . rx_yaml_delimiter . rx_yaml_start_post + let rx_yaml_stop = '^' . rx_yaml_delimiter . '$' + call add(a_yaml_region, [rx_yaml_start, rx_yaml_stop]) + endfor + let res.nested_extended = {'type': type(''), 'default': 'VimwikiError,VimwikiPre,VimwikiCode,VimwikiEqIn,VimwikiSuperScript,VimwikiSubScript,textSnipTEX'} let res.nested_typeface = {'type': type(''), 'default': 'VimwikiBold,VimwikiItalic,VimwikiUnderline,VimwikiDelText'} let res.nested = {'type': type(''), 'default': res.nested_extended.default . ',' . res.nested_typeface.default} let res.rxTableSep = {'type': type(''), 'default': '|'} + " See issue #1287 + let res.yaml_metadata_block = {'type': type([]), 'default': a_yaml_region} return res endfunction diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt @@ -2938,7 +2938,9 @@ color. (See autoload/vimwiki/vars.vim) Syntax options are configured using the following pattern: > - let g:vimwiki_syntax_list['markdown']['bullet_type'] = ['*', '-', '+'] + let g:vimwiki_syntaxlocal_vars = {} + let g:vimwiki_syntaxlocal_vars['markdown'] = [] + let g:vimwiki_syntaxlocal_vars['markdown']['bullet_type'] = ['*', '-', '+'] Where: - `markdown` is the syntax name. It can be (`default`, `markdown` or `media`) @@ -2947,6 +2949,16 @@ Where: ------------------------------------------------------------------------------ +*yaml_metadata_block* + +List of (start, end) regex region delimiters to define the YAML header +More information in #1287 and https://pandoc.org/MANUAL.html#extension-yaml_metadata_block + +Default: [['^---$', '^---$'], ['^\.\.\.$', '^\.\.\.$']] +or similar with stricter anchors + + +------------------------------------------------------------------------------ 12.5 Global Options *vimwiki-global-options* @@ -3999,6 +4011,11 @@ master is retained as a legacy mirror of the dev branch. This is somewhat experimental, and will probably be refined over time. +New:~ + * Issue #1287 Highlight YAML header with |yaml_metadata_block| + configuration variable holding region delimiters + + 2022.12.02~ New:~ diff --git a/syntax/vimwiki.vim b/syntax/vimwiki.vim @@ -508,6 +508,17 @@ if !empty(s:nested) endfor endif +" Include: Yaml metadata block for pandoc +let a_yaml_delimiter = vimwiki#vars#get_syntaxlocal('yaml_metadata_block') +for [rx_start, rx_end] in a_yaml_delimiter + call vimwiki#base#nested_syntax( + \ 'yaml', + \ rx_start, + \ rx_end, + \ 'VimwikiPre') +endfor + + " LaTex: Load if !empty(globpath(&runtimepath, 'syntax/tex.vim')) execute 'syntax include @textGrouptex syntax/tex.vim' diff --git a/test/issue_1287_yaml_header.vader b/test/issue_1287_yaml_header.vader @@ -0,0 +1,95 @@ +# Non regression tests for issue: #1287 + + +Before(Define function for yaml inspection): + function! Issue1287Yaml(line) + " The line where the yaml delimiter is: 1 if at top + let l = a:line + AssertEqual 'textSnipYAML', GetSyntaxStack(l + 0, 2)[0] + AssertEqual 'VimwikiPre', GetSyntaxStack(l + 0, 2)[1] + + AssertEqual 'textSnipYAML', GetSyntaxStack(l + 1, 2)[0] + AssertEqual 'textSnipYAML', GetSyntaxStack(l + 2, 2)[0] + AssertEqual 'textSnipYAML', GetSyntaxStack(l + 2, 20)[0] + + AssertEqual 'VimwikiPre', GetSyntaxStack(l + 3, 2)[-1] + endfunction + + +Given vimwiki (Yaml with --- at top): + --- + title: my title + description: my description + --- + +Execute (Assert delimiter with --- at top): + call Issue1287Yaml(1) + +Given vimwiki (Yaml with ... at top): + ... + title: my title + description: my description + ... + +Execute (Assert delimiter with ... at top): + call Issue1287Yaml(1) + +Given vimwiki (Yaml with --- after empty line): + A stupid block + of 2 lines + + --- + title: my title + description: my description + --- + +Execute (Assert delimiter with --- after empty line): + call Issue1287Yaml(4) + + +Given vimwiki (Yaml with --- mixed with ...): + --- + title: my title + ... + comment: my comment + description: my description + --- + + And a text follows + +Execute (Assert all is yaml except after the closing ---): + AssertEqual 'textSnipYAML1', GetSyntaxStack(1, 2)[0] . 1 + AssertEqual 'VimwikiPre1', GetSyntaxStack(1, 2)[1] . 1 + + AssertEqual 'textSnipYAML1', GetSyntaxStack(1, 2)[0] . 1 + AssertEqual 'textSnipYAML2', GetSyntaxStack(2, 2)[0] . 2 + AssertEqual 'textSnipYAML3', GetSyntaxStack(3, 2)[0] . 3 + AssertEqual 'textSnipYAML4', GetSyntaxStack(4, 2)[0] . 4 + AssertEqual 'textSnipYAML5', GetSyntaxStack(5, 2)[0] . 5 + AssertEqual 'textSnipYAML6', GetSyntaxStack(5, 2)[0] . 6 + + AssertEqual 0, len(GetSyntaxStack(7, 2)) + AssertEqual 0, len(GetSyntaxStack(8, 2)) + + +Given vimwiki (Yaml with --- with a --- not a start of line): + --- + title: my title + comment: my comment --- + description: my description + --- + + And a text follows + +Execute (Assert all is yaml except after the closing ---): + AssertEqual 'textSnipYAML1', GetSyntaxStack(1, 2)[0] . 1 + AssertEqual 'VimwikiPre1', GetSyntaxStack(1, 2)[1] . 1 + + AssertEqual 'textSnipYAML1', GetSyntaxStack(1, 2)[0] . 1 + AssertEqual 'textSnipYAML2', GetSyntaxStack(2, 2)[0] . 2 + AssertEqual 'textSnipYAML3', GetSyntaxStack(3, 2)[0] . 3 + AssertEqual 'textSnipYAML4', GetSyntaxStack(4, 2)[0] . 4 + AssertEqual 'VimwikiPre5', GetSyntaxStack(5, 2)[-1] . 5 + + AssertEqual 0, len(GetSyntaxStack(6, 2)) + AssertEqual 0, len(GetSyntaxStack(7, 2)) diff --git a/test/vimrc b/test/vimrc @@ -343,21 +343,37 @@ 0d endfunction - function! GetSyntaxGroup(line, col) + function! GetSyntaxGroup(...) " Get normalized syntax group: usefull for boldItalic Vs italicBold + " Arg1: line + " Arg2: column " -- Here, Vader's SyntaxAt is not enough " From: https://stackoverflow.com/questions/9464844 - let l:s = synID(a:line, a:col, 1) + let line = a:0 >= 1 ? a:1 : '.' + let col = a:0 >= 2 ? a:2 : '.' + + let l:s = synID(line, col, 1) return synIDattr(synIDtrans(l:s), 'name') endfun - function! GetSyntaxStack() + function! GetSyntaxStack(...) " Debug helper + " Arg1: line + " Arg2: column + let line = a:0 >= 1 ? a:1 : '.' + let col = a:0 >= 2 ? a:2 : '.' if !exists('*synstack') - return + return [] + endif + let res = map(synstack(line, col), 'synIDattr(v:val, "name")') + + " For old vim version returning 0 + if type(res) == type(0) && res == 0 + return [] endif - return map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') - endfunc + + return res + endfunction function! AssertIfVersion(version, one, two) " Run Assert only if vim version is high enough