neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

yaml.vim (15588B)


      1 " Vim syntax file
      2 " Language:         YAML (YAML Ain't Markup Language) 1.2
      3 " Maintainer:       Nikolai Pavlov <zyx.vim@gmail.com>
      4 " First author:     Nikolai Weibull <now@bitwi.se>
      5 " Latest Revision:  2024-04-01
      6 
      7 if exists('b:current_syntax')
      8    finish
      9 endif
     10 
     11 let s:cpo_save = &cpo
     12 set cpo&vim
     13 
     14 " Choose the schema to use
     15 " TODO: Validate schema
     16 if !exists('b:yaml_schema')
     17    if exists('g:yaml_schema')
     18        let b:yaml_schema = g:yaml_schema
     19    else
     20        let b:yaml_schema = 'core'
     21    endif
     22 endif
     23 
     24 let s:ns_char = '\%([\n\r\uFEFF \t]\@!\p\)'
     25 let s:ns_word_char = '[[:alnum:]_\-]'
     26 let s:ns_uri_char  = '\%(%\x\x\|'.s:ns_word_char.'\|[#/;?:@&=+$,.!~*''()[\]]\)'
     27 let s:ns_tag_char  = '\%(%\x\x\|'.s:ns_word_char.'\|[#/;?:@&=+$.~*''()]\)'
     28 let s:c_indicator      = '[\-?:,[\]{}#&*!|>''"%@`]'
     29 let s:c_flow_indicator = '[,[\]{}]'
     30 
     31 let s:ns_anchor_char = substitute(s:ns_char, '\v\C[\zs', '\=s:c_flow_indicator[1:-2]', '')
     32 let s:ns_char_without_c_indicator = substitute(s:ns_char, '\v\C[\zs', '\=s:c_indicator[1:-2]', '')
     33 
     34 let s:_collection = '[^\@!\(\%(\\\.\|\[^\\\]]\)\+\)]'
     35 let s:_neg_collection = '[^\(\%(\\\.\|\[^\\\]]\)\+\)]'
     36 function s:SimplifyToAssumeAllPrintable(p)
     37    return substitute(a:p, '\V\C\\%('.s:_collection.'\\@!\\p\\)', '[^\1]', '')
     38 endfunction
     39 let s:ns_char = s:SimplifyToAssumeAllPrintable(s:ns_char)
     40 let s:ns_anchor_char = s:SimplifyToAssumeAllPrintable(s:ns_anchor_char)
     41 let s:ns_char_without_c_indicator = s:SimplifyToAssumeAllPrintable(s:ns_char_without_c_indicator)
     42 
     43 function s:SimplifyAdjacentCollections(p)
     44    return substitute(a:p, '\V\C'.s:_collection.'\\|'.s:_collection, '[\1\2]', 'g')
     45 endfunction
     46 let s:ns_uri_char = s:SimplifyAdjacentCollections(s:ns_uri_char)
     47 let s:ns_tag_char = s:SimplifyAdjacentCollections(s:ns_tag_char)
     48 
     49 let s:c_verbatim_tag = '!<'.s:ns_uri_char.'\+>'
     50 let s:c_named_tag_handle     = '!'.s:ns_word_char.'\+!'
     51 let s:c_secondary_tag_handle = '!!'
     52 let s:c_primary_tag_handle   = '!'
     53 let s:c_tag_handle = '\%('.s:c_named_tag_handle.
     54            \         '\|'.s:c_secondary_tag_handle.
     55            \         '\|'.s:c_primary_tag_handle.'\)'
     56 let s:c_ns_shorthand_tag = s:c_tag_handle . s:ns_tag_char.'\+'
     57 let s:c_non_specific_tag = '!'
     58 let s:c_ns_tag_property = s:c_verbatim_tag.
     59            \        '\|'.s:c_ns_shorthand_tag.
     60            \        '\|'.s:c_non_specific_tag
     61 
     62 let s:c_ns_anchor_name = s:ns_anchor_char.'\+'
     63 let s:c_ns_anchor_property =  '&'.s:c_ns_anchor_name
     64 let s:c_ns_alias_node      = '\*'.s:c_ns_anchor_name
     65 let s:c_ns_properties      = '\%(\%('.s:c_ns_tag_property.'\|'.s:c_ns_anchor_property.'\)\s\+\)\+'
     66 
     67 let s:ns_directive_name = s:ns_char.'\+'
     68 
     69 let s:ns_local_tag_prefix  = '!'.s:ns_uri_char.'*'
     70 let s:ns_global_tag_prefix = s:ns_tag_char.s:ns_uri_char.'*'
     71 let s:ns_tag_prefix = s:ns_local_tag_prefix.
     72            \    '\|'.s:ns_global_tag_prefix
     73 
     74 let s:ns_plain_safe_out = s:ns_char
     75 let s:ns_plain_safe_in  = '\%('.s:c_flow_indicator.'\@!'.s:ns_char.'\)'
     76 
     77 let s:ns_plain_safe_in = substitute(s:ns_plain_safe_in, '\V\C\\%('.s:_collection.'\\@!'.s:_neg_collection.'\\)', '[^\1\2]', '')
     78 let s:ns_plain_safe_in_without_colhash = substitute(s:ns_plain_safe_in, '\V\C'.s:_neg_collection, '[^\1:#]', '')
     79 let s:ns_plain_safe_out_without_colhash = substitute(s:ns_plain_safe_out, '\V\C'.s:_neg_collection, '[^\1:#]', '')
     80 
     81 let s:ns_plain_first_in  = '\%('.s:ns_char_without_c_indicator.'\|[?:\-]\%('.s:ns_plain_safe_in.'\)\@=\)'
     82 let s:ns_plain_first_out = '\%('.s:ns_char_without_c_indicator.'\|[?:\-]\%('.s:ns_plain_safe_out.'\)\@=\)'
     83 
     84 let s:ns_plain_char_in  = '\%('.s:ns_char.'#\|:'.s:ns_plain_safe_in.'\|'.s:ns_plain_safe_in_without_colhash.'\)'
     85 let s:ns_plain_char_out = '\%('.s:ns_char.'#\|:'.s:ns_plain_safe_out.'\|'.s:ns_plain_safe_out_without_colhash.'\)'
     86 
     87 let s:ns_plain_out = s:ns_plain_first_out . s:ns_plain_char_out.'*'
     88 let s:ns_plain_in  = s:ns_plain_first_in  . s:ns_plain_char_in.'*'
     89 
     90 
     91 syn keyword yamlTodo            contained TODO FIXME XXX NOTE
     92 
     93 syn region  yamlComment         display oneline start='\%\(^\|\s\)#' end='$'
     94            \                   contains=yamlTodo
     95 
     96 execute 'syn region yamlDirective oneline start='.string('^\ze%'.s:ns_directive_name.'\s\+').' '.
     97            \                            'end="$" '.
     98            \                            'contains=yamlTAGDirective,'.
     99            \                                     'yamlYAMLDirective,'.
    100            \                                     'yamlReservedDirective '.
    101            \                            'keepend'
    102 
    103 syn match yamlTAGDirective /%TAG\ze\s/ contained nextgroup=yamlTagHandle skipwhite
    104 execute 'syn match yamlTagHandle' string(s:c_tag_handle)  'contained nextgroup=yamlTagPrefix skipwhite'
    105 execute 'syn match yamlTagPrefix' string(s:ns_tag_prefix) 'contained nextgroup=yamlComment skipwhite'
    106 
    107 syn match yamlYAMLDirective /%YAML\ze\s/ contained nextgroup=yamlYAMLVersion skipwhite
    108 syn match yamlYAMLVersion   /\d\+\.\d\+/ contained nextgroup=yamlComment skipwhite
    109 
    110 execute 'syn match yamlReservedDirective contained nextgroup=yamlComment '.
    111            \string('%\%(\%(TAG\|YAML\)\s\)\@!'.s:ns_directive_name)
    112 
    113 syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start='"' skip='\\"' end='"'
    114            \ contains=yamlEscape contained nextgroup=yamlFlowMappingDelimiter,yamlComment skipwhite
    115 syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start="'" skip="''"  end="'"
    116            \ contains=yamlSingleEscape contained nextgroup=yamlFlowMappingDelimiter,yamlComment skipwhite
    117 syn match  yamlEscape contained '\\\%([\\"abefnrtv\^0_ NLP\n]\|x\x\x\|u\x\{4}\|U\x\{8}\)'
    118 syn match  yamlSingleEscape contained "''"
    119 
    120 syn cluster yamlConstant contains=yamlBool,yamlNull
    121 
    122 syn cluster yamlFlowNode contains=yamlFlowString,yamlFlowMapping,yamlFlowCollection
    123 syn cluster yamlFlowNode      add=yamlFlowMappingKey,yamlFlowMappingKeyStart,yamlFlowMappingMerge
    124 syn cluster yamlFlowNode      add=@yamlConstant,yamlPlainScalar,yamlFloat,yamlComment
    125 syn cluster yamlFlowNode      add=yamlTimestamp,yamlInteger,yamlAlias,yamlFlowNodeProperties
    126 syn region yamlFlowMapping    matchgroup=yamlFlowIndicator start='{\@<!{{\@!' end='}' contains=@yamlFlowNode
    127 syn region yamlFlowCollection matchgroup=yamlFlowIndicator start='\[' end='\]' contains=@yamlFlowNode
    128 
    129 execute 'syn match yamlPlainScalar /'.s:ns_plain_out.'/'
    130 execute 'syn match yamlPlainScalar contained /'.s:ns_plain_in.'/'
    131 
    132 execute 'syn match yamlFlowMappingKey /'.s:ns_plain_in.'\%(\s\+'.s:ns_plain_in.'\)*\ze\s*:\%(\s\|$\)/ contained '.
    133            \'nextgroup=yamlFlowMappingDelimiter skipwhite'
    134 syn match yamlFlowMappingKeyStart      /?/ contained nextgroup=@yamlFlowNode skipwhite
    135 syn match yamlFlowMappingMerge /<<\ze\s*:/ contained nextgroup=yamlFlowMappingDelimiter skipwhite
    136 syn match yamlFlowMappingDelimiter     /:/ contained nextgroup=@yamlFlowNode skipwhite
    137 execute 'syn match yamlFlowNodeProperties' string(s:c_ns_properties)
    138            \ 'contained contains=yamlNodeTag,yamlAnchor nextgroup=@yamlFlowNode skipwhite'
    139 
    140 execute 'syn match yamlBlockMappingKey /^\s*\zs'.s:ns_plain_out.'\%(\s\+'.s:ns_plain_out.'\)*\ze\s*:\%(\s\|$\)/ '.
    141            \'nextgroup=yamlBlockMappingDelimiter skipwhite'
    142 execute 'syn match yamlBlockMappingKey        /'.s:ns_plain_out.'\%(\s\+'.s:ns_plain_out.'\)*\ze\s*:\%(\s\|$\)/ contained '.
    143            \'nextgroup=yamlBlockMappingDelimiter skipwhite'
    144 syn match yamlBlockMappingKeyString /^\s*\zs\%("\%([^"]\|\\"\)*"\|'\%([^']\|''\)*'\)\ze\s*:\%(\s\|$\)/
    145            \ contains=yamlFlowString nextgroup=yamlBlockMappingDelimiter skipwhite
    146 syn match yamlBlockMappingKeyString        /\%("\%([^"]\|\\"\)*"\|'\%([^']\|''\)*'\)\ze\s*:\%(\s\|$\)/ contained
    147            \ contains=yamlFlowString nextgroup=yamlBlockMappingDelimiter skipwhite
    148 syn match yamlBlockMappingMerge   /^\s*\zs<<\ze\s*:\%(\s\|$\)/           nextgroup=yamlBlockMappingDelimiter skipwhite
    149 syn match yamlBlockMappingMerge          /<<\ze\s*:\%(\s\|$\)/ contained nextgroup=yamlBlockMappingDelimiter skipwhite
    150 
    151 syn match yamlBlockMappingDelimiter    /^\s*\zs:\ze\%(\s\|$\)/           nextgroup=@yamlBlockNode skipwhite
    152 syn match yamlBlockMappingDelimiter           /:\ze\%(\s\|$\)/ contained nextgroup=@yamlBlockNode skipwhite
    153 syn match yamlBlockMappingKeyStart     /^\s*\zs?\ze\%(\s\|$\)/           nextgroup=@yamlBlockNode skipwhite
    154 syn match yamlBlockMappingKeyStart            /?\ze\%(\s\|$\)/ contained nextgroup=@yamlBlockNode skipwhite
    155 
    156 syn match yamlBlockCollectionItemStart /^\s*\zs-\ze\%(\s\|$\)/           nextgroup=@yamlBlockNode skipwhite
    157 syn match yamlBlockCollectionItemStart        /-\ze\%(\s\|$\)/ contained nextgroup=@yamlBlockNode skipwhite
    158 
    159 execute 'syn match yamlBlockNodeProperties' string(s:c_ns_properties)
    160            \ 'contained contains=yamlNodeTag,yamlAnchor nextgroup=@yamlFlowNode,yamlBlockScalarHeader skipwhite'
    161 syn match yamlBlockScalarHeader '[|>]\%([1-9][+-]\|[+-]\?[1-9]\?\)\%(\s\+#.*\)\?$' contained
    162            \ contains=yamlComment nextgroup=yamlBlockString skipnl
    163 syn region yamlBlockString start=/^\z(\s\+\)/ skip=/^$/ end=/^\%(\z1\)\@!/ contained
    164 
    165 syn cluster yamlBlockNode contains=@yamlFlowNode,yamlBlockMappingKey,yamlBlockMappingKeyString,
    166            \yamlBlockMappingMerge,yamlBlockMappingKeyStart,yamlBlockCollectionItemStart,
    167            \yamlBlockNodeProperties,yamlBlockScalarHeader
    168 
    169 syn cluster yamlScalarWithSpecials contains=yamlPlainScalar,yamlBlockMappingKey,yamlFlowMappingKey
    170 
    171 let s:_bounder = s:SimplifyToAssumeAllPrintable('\%([[\]{}, \t]\@!\p\)')
    172 if b:yaml_schema is# 'json'
    173    syn keyword yamlNull null contained containedin=@yamlScalarWithSpecials
    174    syn keyword yamlBool true false
    175    exe 'syn match   yamlInteger /'.s:_bounder.'\@1<!\%(0\|-\=[1-9][0-9]*\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    176    exe 'syn match   yamlFloat   /'.s:_bounder.'\@1<!\%(-\=[1-9][0-9]*\%(\.[0-9]*\)\=\(e[-+]\=[0-9]\+\)\=\|0\|-\=\.inf\|\.nan\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    177 elseif b:yaml_schema is# 'core'
    178    syn keyword yamlNull null Null NULL contained containedin=@yamlScalarWithSpecials
    179    syn keyword yamlBool true True TRUE false False FALSE contained containedin=@yamlScalarWithSpecials
    180    exe 'syn match   yamlNull /'.s:_bounder.'\@1<!\~'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    181    exe 'syn match   yamlInteger /'.s:_bounder.'\@1<!\%([-+]\=\%(\%(0\%(b[0-1_]\+\|o\?[0-7_]\+\|x[0-9a-fA-F_]\+\)\=\|\%([1-9][0-9_]*\%(:[0-5]\=\d\)\+\)\)\|[1-9][0-9_]*\)\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    182    exe 'syn match   yamlFloat /'.s:_bounder.'\@1<!\%([-+]\=\%(\%(\d[0-9_]*\)\.[0-9_]*\%([eE][-+]\=\d\+\)\=\|\.[0-9_]\+\%([eE][-+]\=[0-9]\+\)\=\|\d[0-9_]*\%(:[0-5]\=\d\)\+\.[0-9_]*\|\.\%(inf\|Inf\|INF\)\)\|\%(\.\%(nan\|NaN\|NAN\)\)\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    183 elseif b:yaml_schema is# 'pyyaml'
    184    syn keyword yamlNull null Null NULL contained containedin=@yamlScalarWithSpecials
    185    syn keyword yamlBool true True TRUE false False FALSE yes Yes YES no No NO on On ON off Off OFF contained containedin=@yamlScalarWithSpecials
    186    exe 'syn match   yamlNull /'.s:_bounder.'\@1<!\~'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    187    exe 'syn match  yamlFloat /'.s:_bounder.'\@1<!\%(\v[-+]?%(\d[0-9_]*)\.[0-9_]*%([eE][-+]\d+)?|\.[0-9_]+%([eE][-+]\d+)?|[-+]?\d[0-9_]*%(\:[0-5]?\d)+\.[0-9_]*|[-+]?\.%(inf|Inf|INF)|\.%(nan|NaN|NAN)\m\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    188    exe 'syn match  yamlInteger /'.s:_bounder.'\@1<!\%(\v[-+]?0b[0-1_]+|[-+]?0[0-7_]+|[-+]?%(0|[1-9][0-9_]*)|[-+]?0x[0-9a-fA-F_]+|[-+]?[1-9][0-9_]*%(:[0-5]?\d)+\m\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    189    exe 'syn match  yamlTimestamp /'.s:_bounder.'\@1<!\%(\v\d\d\d\d\-\d\d\-\d\d|\d\d\d\d \-\d\d? \-\d\d?%([Tt]|[ \t]+)\d\d?\:\d\d \:\d\d %(\.\d*)?%([ \t]*%(Z|[-+]\d\d?%(\:\d\d)?))?\m\)'.s:_bounder.'\@!/ contained containedin=@yamlScalarWithSpecials'
    190 elseif b:yaml_schema is# 'failsafe'
    191    " Nothing
    192 endif
    193 unlet s:_bounder
    194 
    195 
    196 execute 'syn match yamlNodeTag '.string(s:c_ns_tag_property)
    197 execute 'syn match yamlAnchor  '.string(s:c_ns_anchor_property)
    198 execute 'syn match yamlAlias   '.string(s:c_ns_alias_node)
    199 
    200 syn match yamlDocumentStart '^---\ze\%(\s\|$\)'
    201 syn match yamlDocumentEnd   '^\.\.\.\ze\%(\s\|$\)'
    202 
    203 hi def link yamlTodo                     Todo
    204 hi def link yamlComment                  Comment
    205 
    206 hi def link yamlDocumentStart            PreProc
    207 hi def link yamlDocumentEnd              PreProc
    208 
    209 hi def link yamlDirectiveName            Keyword
    210 
    211 hi def link yamlTAGDirective             yamlDirectiveName
    212 hi def link yamlTagHandle                String
    213 hi def link yamlTagPrefix                String
    214 
    215 hi def link yamlYAMLDirective            yamlDirectiveName
    216 hi def link yamlReservedDirective        Error
    217 hi def link yamlYAMLVersion              Number
    218 
    219 hi def link yamlString                   String
    220 hi def link yamlFlowString               yamlString
    221 hi def link yamlFlowStringDelimiter      yamlString
    222 hi def link yamlEscape                   SpecialChar
    223 hi def link yamlSingleEscape             SpecialChar
    224 
    225 hi def link yamlMappingKey               Identifier
    226 hi def link yamlMappingKeyStart          Special
    227 hi def link yamlMappingMerge             Special
    228 hi def link yamlKeyValueDelimiter        Special
    229 
    230 hi def link yamlFlowIndicator            Special
    231 hi def link yamlFlowMappingKey           yamlMappingKey
    232 hi def link yamlFlowMappingKeyStart      yamlMappingKeyStart
    233 hi def link yamlFlowMappingMerge         yamlMappingMerge
    234 hi def link yamlFlowMappingDelimiter     yamlKeyValueDelimiter
    235 
    236 hi def link yamlBlockMappingKey          yamlMappingKey
    237 hi def link yamlBlockMappingKeyStart     yamlMappingKeyStart
    238 hi def link yamlBlockMappingMerge        yamlMappingMerge
    239 hi def link yamlBlockMappingDelimiter    yamlKeyValueDelimiter
    240 hi def link yamlBlockCollectionItemStart Label
    241 hi def link yamlBlockScalarHeader        Special
    242 " We do not link yamlBlockString to yamlString, because yamlPlainScalar is
    243 " not highlighted as string neighter, and also due to historical reasons.
    244 " hi def link yamlBlockString              yamlString
    245 
    246 hi def link yamlConstant                 Constant
    247 
    248 hi def link yamlNull                     yamlConstant
    249 hi def link yamlBool                     yamlConstant
    250 
    251 hi def link yamlAnchor                   Type
    252 hi def link yamlAlias                    Type
    253 hi def link yamlNodeTag                  Type
    254 
    255 hi def link yamlInteger                  Number
    256 hi def link yamlFloat                    Float
    257 hi def link yamlTimestamp                Number
    258 
    259 let b:current_syntax = "yaml"
    260 
    261 unlet s:ns_char s:ns_word_char s:ns_uri_char s:ns_tag_char s:c_indicator s:c_flow_indicator
    262            \ s:ns_anchor_char s:ns_char_without_c_indicator s:_collection s:_neg_collection
    263            \ s:c_verbatim_tag s:c_named_tag_handle s:c_secondary_tag_handle s:c_primary_tag_handle
    264            \ s:c_tag_handle s:c_ns_shorthand_tag s:c_non_specific_tag s:c_ns_tag_property
    265            \ s:c_ns_anchor_name s:c_ns_anchor_property s:c_ns_alias_node s:c_ns_properties
    266            \ s:ns_directive_name s:ns_local_tag_prefix s:ns_global_tag_prefix s:ns_tag_prefix
    267            \ s:ns_plain_safe_out s:ns_plain_safe_in s:ns_plain_safe_in_without_colhash s:ns_plain_safe_out_without_colhash
    268            \ s:ns_plain_first_in s:ns_plain_first_out s:ns_plain_char_in s:ns_plain_char_out s:ns_plain_out s:ns_plain_in
    269 delfunction s:SimplifyAdjacentCollections
    270 delfunction s:SimplifyToAssumeAllPrintable
    271 
    272 let &cpo = s:cpo_save
    273 unlet s:cpo_save
    274 
    275 " vim: set et sw=4 sts=4 ts=8: