diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index bfe700f8dd..bd55c97f15 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -612,6 +612,7 @@ local extension = { jsx = 'javascriptreact', clp = 'jess', jgr = 'jgraph', + jinja = 'jinja', jjdescription = 'jj', j73 = 'jovial', jov = 'jovial', @@ -1023,6 +1024,7 @@ local extension = { rake = 'ruby', rs = 'rust', sage = 'sage', + sls = 'salt', sas = 'sas', sass = 'sass', sa = 'sather', diff --git a/runtime/syntax/jinja.vim b/runtime/syntax/jinja.vim new file mode 100644 index 0000000000..6000855ff7 --- /dev/null +++ b/runtime/syntax/jinja.vim @@ -0,0 +1,86 @@ +" Vim syntax file +" Language: Jinja +" Maintainer: Gregory Anders +" Upstream: https://gitlab.com/HiPhish/jinja.vim + +if exists('b:current_syntax') + finish +endif + +syntax case match +syntax sync fromstart + +" Jinja template built-in tags and parameters (without filter, macro, is and raw, they +" have special threatment) +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained and if else in not or recursive as import + +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained is filter skipwhite nextgroup=jinjaFilter +syn keyword jinjaStatement containedin=jinjaTagBlock contained macro skipwhite nextgroup=jinjaFunction +syn keyword jinjaStatement containedin=jinjaTagBlock contained block skipwhite nextgroup=jinjaBlockName + +" Variable Names +syn match jinjaVariable containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn keyword jinjaSpecial containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained false true none False True None loop super caller varargs kwargs + +" Filters +syn match jinjaOperator "|" containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained skipwhite nextgroup=jinjaFilter +syn match jinjaFilter contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaFunction contained /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaBlockName contained /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template constants +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/"/ skip=/\(\\\)\@\)*\\"/ end=/"/ +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/'/ skip=/\(\\\)\@\)*\\'/ end=/'/ +syn match jinjaNumber containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[0-9]\+\(\.[0-9]\+\)\?/ + +" Operators +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[+\-*\/<>=!,:]/ +syn match jinjaPunctuation containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[()\[\]]/ +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /\./ nextgroup=jinjaAttribute +syn match jinjaAttribute contained /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template tag and variable blocks +syn region jinjaNested matchgroup=jinjaOperator start="(" end=")" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="\[" end="\]" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="{" end="}" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +" Jinja template 'raw' tag +syn region jinjaRaw matchgroup=jinjaRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,jinjaComment + +" Jinja comments +syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString + +" Block start keywords. A bit tricker. We only highlight at the start of a +" tag block and only if the name is not followed by a comma or equals sign +" which usually means that we have to deal with an assignment. +syn match jinjaStatement containedin=jinjaTagBlock contained /\({%-\?\s*\)\@<=\<[a-zA-Z_][a-zA-Z0-9_]*\>\(\s*[,=]\)\@!/ + +" and context modifiers +syn match jinjaStatement containedin=jinjaTagBlock contained /\/ + +hi def link jinjaPunctuation jinjaOperator +hi def link jinjaAttribute jinjaVariable +hi def link jinjaFunction jinjaFilter + +hi def link jinjaTagDelim jinjaTagBlock +hi def link jinjaVarDelim jinjaVarBlock +hi def link jinjaCommentDelim jinjaComment +hi def link jinjaRawDelim jinja + +hi def link jinjaSpecial Special +hi def link jinjaOperator Normal +hi def link jinjaRaw Normal +hi def link jinjaTagBlock PreProc +hi def link jinjaVarBlock PreProc +hi def link jinjaStatement Statement +hi def link jinjaFilter Function +hi def link jinjaBlockName Function +hi def link jinjaVariable Identifier +hi def link jinjaString Constant +hi def link jinjaNumber Constant +hi def link jinjaComment Comment + +let b:current_syntax = 'jinja' diff --git a/runtime/syntax/salt.vim b/runtime/syntax/salt.vim new file mode 100644 index 0000000000..fdbce2f677 --- /dev/null +++ b/runtime/syntax/salt.vim @@ -0,0 +1,16 @@ +" Vim syntax file +" Maintainer: Gregory Anders +" Last Changed: 2024-09-16 + +if exists('b:current_syntax') + finish +endif + +" Salt state files are just YAML with embedded Jinja +runtime! syntax/yaml.vim +unlet! b:current_syntax + +runtime! syntax/jinja.vim +unlet! b:current_syntax + +let b:current_syntax = 'salt' diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 33f8df4081..51b6f884f4 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -366,6 +366,7 @@ func s:GetFilenameChecks() abort \ 'javascriptreact': ['file.jsx'], \ 'jess': ['file.clp'], \ 'jgraph': ['file.jgr'], + \ 'jinja': ['file.jinja'], \ 'jj': ['file.jjdescription'], \ 'jq': ['file.jq'], \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], @@ -632,6 +633,7 @@ func s:GetFilenameChecks() abort \ 'rtf': ['file.rtf'], \ 'ruby': ['.irbrc', 'irbrc', '.irb_history', 'irb_history', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'], \ 'rust': ['file.rs'], + \ 'salt': ['file.sls'], \ 'samba': ['smb.conf'], \ 'sas': ['file.sas'], \ 'sass': ['file.sass'],