2026-05-12 01:04:23 +00:00
|
|
|
" syntax/vimwiki.vim — default highlight groups for nuwiki.
|
2026-05-11 00:38:09 +00:00
|
|
|
"
|
|
|
|
|
" Two responsibilities:
|
2026-05-30 15:25:51 -03:00
|
|
|
" 1. Default `@vimwiki*` highlight groups for the LSP semantic tokens.
|
|
|
|
|
" Loaded eagerly so the very first hover/highlight
|
2026-05-11 00:38:09 +00:00
|
|
|
" cycle after server startup already has colours.
|
|
|
|
|
" 2. A small regex-based fallback so static highlighting works on
|
|
|
|
|
" buffers where the LSP isn't running yet.
|
2026-05-12 01:04:23 +00:00
|
|
|
"
|
|
|
|
|
" The `@group.modifier` group names are Neovim's Tree-sitter convention
|
|
|
|
|
" — plain Vim rejects `@` and `.` with W18, so the LSP-token defaults
|
|
|
|
|
" are gated behind `has('nvim')`. The static fallback below works
|
|
|
|
|
" everywhere.
|
2026-05-11 00:38:09 +00:00
|
|
|
|
|
|
|
|
if exists('b:current_syntax')
|
|
|
|
|
finish
|
|
|
|
|
endif
|
|
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
" ===== Semantic-token defaults (Neovim only — uses TS-style @group names) =====
|
2026-05-11 00:38:09 +00:00
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
if has('nvim')
|
|
|
|
|
" Headings — level modifiers map to progressively softer accents.
|
|
|
|
|
highlight default link @vimwikiHeading Title
|
|
|
|
|
highlight default link @vimwikiHeading.level1 Title
|
|
|
|
|
highlight default link @vimwikiHeading.level2 Function
|
|
|
|
|
highlight default link @vimwikiHeading.level3 Identifier
|
|
|
|
|
highlight default link @vimwikiHeading.level4 Type
|
|
|
|
|
highlight default link @vimwikiHeading.level5 Constant
|
|
|
|
|
highlight default link @vimwikiHeading.level6 PreProc
|
|
|
|
|
highlight default link @vimwikiHeading.centered Title
|
2026-05-11 00:38:09 +00:00
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
" Inline text styling.
|
2026-05-26 22:02:32 -03:00
|
|
|
" Use @markup.* (nvim 0.9+ treesitter standard groups, defined by all
|
|
|
|
|
" colorschemes) instead of markdownBold/Italic which only exist when the
|
|
|
|
|
" markdown treesitter parser is loaded — never the case in a vimwiki buffer.
|
|
|
|
|
highlight default link @vimwikiBold @markup.strong
|
|
|
|
|
highlight default link @vimwikiItalic @markup.italic
|
|
|
|
|
highlight default link @vimwikiBoldItalic @markup.strong
|
|
|
|
|
highlight default link @vimwikiStrikethrough @markup.strikethrough
|
|
|
|
|
highlight default link @vimwikiSuperscript Special
|
|
|
|
|
highlight default link @vimwikiSubscript Special
|
2026-05-11 00:38:09 +00:00
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
" Code + math.
|
2026-05-26 22:02:32 -03:00
|
|
|
highlight default link @vimwikiCode @markup.raw.inline
|
|
|
|
|
highlight default link @vimwikiCodeBlock @markup.raw.block
|
2026-05-12 01:04:23 +00:00
|
|
|
highlight default link @vimwikiMath Number
|
|
|
|
|
highlight default link @vimwikiMathBlock Number
|
2026-05-11 00:38:09 +00:00
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
" Links + transclusions.
|
2026-05-26 22:02:32 -03:00
|
|
|
highlight default link @vimwikiWikilink @markup.link
|
|
|
|
|
highlight default link @vimwikiExternalLink @markup.link.url
|
|
|
|
|
highlight default link @vimwikiUrl @markup.link.url
|
2026-05-12 01:04:23 +00:00
|
|
|
highlight default link @vimwikiTransclusion Identifier
|
2026-05-11 00:38:09 +00:00
|
|
|
|
2026-05-12 01:04:23 +00:00
|
|
|
" Misc.
|
|
|
|
|
highlight default link @vimwikiKeyword Todo
|
|
|
|
|
highlight default link @vimwikiColor Constant
|
|
|
|
|
highlight default link @vimwikiComment Comment
|
|
|
|
|
highlight default link @vimwikiDefinitionTerm Statement
|
|
|
|
|
endif
|
2026-05-11 00:38:09 +00:00
|
|
|
|
|
|
|
|
" ===== Static fallback (no LSP required) =====
|
|
|
|
|
|
|
|
|
|
syntax case match
|
|
|
|
|
|
2026-05-26 22:03:51 -03:00
|
|
|
" One match per heading level so colorschemes can style each differently.
|
|
|
|
|
" Each pattern requires whitespace immediately after the equals run, which
|
|
|
|
|
" makes the levels mutually exclusive (`==` won't match `===`).
|
|
|
|
|
syntax match nuwikiHeading1 /^\s*=\s.\{-}\s=\s*$/
|
|
|
|
|
syntax match nuwikiHeading2 /^\s*==\s.\{-}\s==\s*$/
|
|
|
|
|
syntax match nuwikiHeading3 /^\s*===\s.\{-}\s===\s*$/
|
|
|
|
|
syntax match nuwikiHeading4 /^\s*====\s.\{-}\s====\s*$/
|
|
|
|
|
syntax match nuwikiHeading5 /^\s*=====\s.\{-}\s=====\s*$/
|
|
|
|
|
syntax match nuwikiHeading6 /^\s*======\s.\{-}\s======\s*$/
|
2026-05-11 00:38:09 +00:00
|
|
|
syntax match nuwikiHorizontal /^-\{4,}\s*$/
|
|
|
|
|
syntax match nuwikiCommentLine /^%%.*$/
|
|
|
|
|
syntax region nuwikiCommentBlock start=/^%%+/ end=/+%%/ keepend
|
2026-05-28 22:24:27 -03:00
|
|
|
syntax region nuwikiPreformatted matchgroup=nuwikiPreDelim start=/^\s*{{{/ end=/^\s*}}}\s*$/ keepend
|
2026-05-11 00:38:09 +00:00
|
|
|
syntax region nuwikiMathBlock start=/^{{\$/ end=/^}}\$/ keepend
|
|
|
|
|
syntax match nuwikiPlaceholder /^%\(title\|nohtml\|template\|date\)\>.*$/
|
|
|
|
|
|
2026-05-26 22:01:55 -03:00
|
|
|
syntax match nuwikiBold /\*[^*]\+\*/ contains=nuwikiBoldDelim
|
|
|
|
|
syntax match nuwikiBoldDelim /\*/ contained conceal
|
|
|
|
|
|
|
|
|
|
syntax match nuwikiItalic /\<_[^_]\+_\>/ contains=nuwikiItalicDelim
|
|
|
|
|
syntax match nuwikiItalicDelim /_/ contained conceal
|
|
|
|
|
|
|
|
|
|
syntax match nuwikiCode /`[^`]\+`/ contains=nuwikiCodeDelim
|
|
|
|
|
syntax match nuwikiCodeDelim /`/ contained conceal
|
|
|
|
|
|
2026-05-11 00:38:09 +00:00
|
|
|
syntax match nuwikiMathInline /\$[^$]\+\$/
|
2026-05-28 21:49:36 -03:00
|
|
|
" Two keyword groups so the editor can colour them like the HTML export:
|
|
|
|
|
" attention/pending (red) vs resolved/in-progress (green).
|
2026-05-28 22:05:23 -03:00
|
|
|
syntax match nuwikiKeywordAttn /\<\(TODO\|FIXME\|XXX\|STOPPED\)\>/
|
2026-05-28 21:49:36 -03:00
|
|
|
syntax match nuwikiKeywordDone /\<\(DONE\|FIXED\|STARTED\)\>/
|
2026-05-26 22:01:55 -03:00
|
|
|
|
|
|
|
|
" Wikilink conceal: hide [[ / ]], and for [[target|desc]] hide target|.
|
|
|
|
|
syntax region nuwikiWikilink start=/\[\[/ end=/\]\]/ keepend contains=nuwikiWikilinkBracket,nuwikiWikilinkTarget
|
|
|
|
|
syntax match nuwikiWikilinkBracket /\[\[/ contained conceal
|
|
|
|
|
syntax match nuwikiWikilinkBracket /\]\]/ contained conceal
|
|
|
|
|
syntax match nuwikiWikilinkTarget /[^|\]]*|/ contained conceal
|
|
|
|
|
|
2026-05-11 00:38:09 +00:00
|
|
|
syntax region nuwikiTransclusion start=/{{[^{]/ end=/}}/ keepend
|
|
|
|
|
syntax match nuwikiUrl /\<\(https\?\|ftp\|mailto\|file\):\/\?\/\?\S\+/
|
|
|
|
|
|
2026-05-26 22:03:51 -03:00
|
|
|
" Heading levels map to progressively softer accents — matches the Neovim
|
|
|
|
|
" semantic-token mapping above so static fallback and LSP-driven highlights
|
|
|
|
|
" agree. Colorschemes that don't differentiate Title vs Function vs etc.
|
|
|
|
|
" will still show all six as the same colour, but most do.
|
|
|
|
|
highlight default link nuwikiHeading1 Title
|
|
|
|
|
highlight default link nuwikiHeading2 Function
|
|
|
|
|
highlight default link nuwikiHeading3 Identifier
|
|
|
|
|
highlight default link nuwikiHeading4 Type
|
|
|
|
|
highlight default link nuwikiHeading5 Constant
|
|
|
|
|
highlight default link nuwikiHeading6 PreProc
|
2026-05-11 00:38:09 +00:00
|
|
|
highlight default link nuwikiHorizontal Comment
|
|
|
|
|
highlight default link nuwikiCommentLine Comment
|
|
|
|
|
highlight default link nuwikiCommentBlock Comment
|
|
|
|
|
highlight default link nuwikiPreformatted String
|
2026-05-28 22:24:27 -03:00
|
|
|
highlight default link nuwikiPreDelim Comment
|
2026-05-11 00:38:09 +00:00
|
|
|
highlight default link nuwikiMathBlock Number
|
|
|
|
|
highlight default link nuwikiPlaceholder PreProc
|
2026-05-26 22:02:32 -03:00
|
|
|
" Bold / Italic use explicit attributes so they work in plain Vim too (no
|
|
|
|
|
" dependency on the 'Bold' / 'Italic' groups which are Neovim-only).
|
|
|
|
|
highlight default nuwikiBold gui=bold cterm=bold term=bold
|
|
|
|
|
highlight default nuwikiItalic gui=italic cterm=italic term=italic
|
2026-05-11 00:38:09 +00:00
|
|
|
highlight default link nuwikiCode String
|
|
|
|
|
highlight default link nuwikiMathInline Number
|
2026-05-28 21:49:36 -03:00
|
|
|
" Explicit colours (not a `Todo` link) so the red/green split is visible in any
|
|
|
|
|
" colorscheme. Matches the HTML export: TODO/FIXME/XXX red, DONE/FIXED/STARTED
|
|
|
|
|
" green.
|
|
|
|
|
highlight default nuwikiKeywordAttn gui=bold cterm=bold term=bold guifg=#F44747 ctermfg=203
|
|
|
|
|
highlight default nuwikiKeywordDone gui=bold cterm=bold term=bold guifg=#2EA043 ctermfg=35
|
2026-05-11 00:38:09 +00:00
|
|
|
highlight default link nuwikiWikilink Underlined
|
|
|
|
|
highlight default link nuwikiTransclusion Identifier
|
|
|
|
|
highlight default link nuwikiUrl Underlined
|
|
|
|
|
|
2026-05-28 22:24:27 -03:00
|
|
|
" ===== Nested syntax for code blocks =====
|
|
|
|
|
"
|
|
|
|
|
" Highlight `{{{lang … }}}` fences with the embedded language's syntax, like
|
|
|
|
|
" vimwiki's automatic nested syntaxes. We scan the buffer for the languages
|
|
|
|
|
" actually used, `:syntax include` each one under a cluster, then define a
|
|
|
|
|
" contained region per language. Defined *after* nuwikiPreformatted so the
|
|
|
|
|
" language regions win for tagged fences (Vim gives later items priority),
|
|
|
|
|
" while bare `{{{` / `{{{class="…"` fences fall back to nuwikiPreformatted.
|
|
|
|
|
|
|
|
|
|
" Labels that don't match a Vim filetype name 1:1.
|
|
|
|
|
let s:nuwiki_nested_aliases = {
|
|
|
|
|
\ 'bash': 'sh', 'shell': 'sh', 'zsh': 'sh', 'console': 'sh',
|
|
|
|
|
\ 'js': 'javascript', 'ts': 'typescript', 'py': 'python',
|
|
|
|
|
\ 'rs': 'rust', 'yml': 'yaml', 'md': 'markdown', 'c++': 'cpp',
|
|
|
|
|
\ }
|
|
|
|
|
|
|
|
|
|
" The language label of a fence line: the first whitespace-separated token
|
|
|
|
|
" after `{{{` that isn't a `key=val` attribute (mirrors the Rust lexer).
|
|
|
|
|
function! s:nuwiki_fence_label(line) abort
|
|
|
|
|
let l:after = matchstr(a:line, '^\s*{{{\zs.*$')
|
|
|
|
|
for l:tok in split(l:after, '\s\+')
|
|
|
|
|
if l:tok !~# '='
|
|
|
|
|
return l:tok
|
|
|
|
|
endif
|
|
|
|
|
endfor
|
|
|
|
|
return ''
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:nuwiki_setup_nested() abort
|
|
|
|
|
let l:included = {}
|
|
|
|
|
let l:defined = {}
|
|
|
|
|
for l:lnum in range(1, line('$'))
|
|
|
|
|
let l:line = getline(l:lnum)
|
|
|
|
|
if l:line !~# '^\s*{{{'
|
|
|
|
|
continue
|
|
|
|
|
endif
|
|
|
|
|
let l:label = s:nuwiki_fence_label(l:line)
|
|
|
|
|
if l:label ==# '' || has_key(l:defined, l:label)
|
|
|
|
|
continue
|
|
|
|
|
endif
|
|
|
|
|
let l:defined[l:label] = 1
|
|
|
|
|
let l:ft = get(s:nuwiki_nested_aliases, tolower(l:label), tolower(l:label))
|
|
|
|
|
let l:cluster = 'nuwikiNested_' . substitute(l:ft, '[^a-zA-Z0-9]', '_', 'g')
|
|
|
|
|
if !has_key(l:included, l:cluster)
|
|
|
|
|
if exists('b:current_syntax')
|
|
|
|
|
unlet b:current_syntax
|
|
|
|
|
endif
|
|
|
|
|
try
|
|
|
|
|
execute 'syntax include @' . l:cluster . ' syntax/' . l:ft . '.vim'
|
|
|
|
|
catch
|
|
|
|
|
" No syntax file for this language — leave it to nuwikiPreformatted.
|
|
|
|
|
continue
|
|
|
|
|
endtry
|
|
|
|
|
if exists('b:current_syntax')
|
|
|
|
|
unlet b:current_syntax
|
|
|
|
|
endif
|
|
|
|
|
let l:included[l:cluster] = 1
|
|
|
|
|
endif
|
|
|
|
|
let l:region = 'nuwikiNestedRegion_' . substitute(l:label, '[^a-zA-Z0-9]', '_', 'g')
|
|
|
|
|
execute 'syntax region ' . l:region
|
|
|
|
|
\ . ' matchgroup=nuwikiPreDelim'
|
|
|
|
|
\ . ' start=/^\s*{{{\s*' . escape(l:label, '/\.*$^~[]') . '\>.*$/'
|
|
|
|
|
\ . ' end=/^\s*}}}\s*$/'
|
|
|
|
|
\ . ' contains=@' . l:cluster
|
|
|
|
|
\ . ' keepend'
|
|
|
|
|
endfor
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
call s:nuwiki_setup_nested()
|
|
|
|
|
|
2026-05-11 00:38:09 +00:00
|
|
|
let b:current_syntax = 'vimwiki'
|