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:
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