1" Vim syntax file 2" Language: XML 3" Maintainer: Christian Brabandt <[email protected]> 4" Repository: https://github.com/chrisbra/vim-xml-ftplugin 5" Previous Maintainer: Johannes Zellner <[email protected]> 6" Author: Paul Siegmann <[email protected]> 7" Last Changed: Sept 24, 2019 8" Filenames: *.xml 9" Last Change: 10" 20190923 - Fix xmlEndTag to match xmlTag (vim/vim#884) 11" 20190924 - Fix xmlAttribute property (amadeus/vim-xml@d8ce1c946) 12 13" CONFIGURATION: 14" syntax folding can be turned on by 15" 16" let g:xml_syntax_folding = 1 17" 18" before the syntax file gets loaded (e.g. in ~/.vimrc). 19" This might slow down syntax highlighting significantly, 20" especially for large files. 21" 22" CREDITS: 23" The original version was derived by Paul Siegmann from 24" Claudio Fleiner's html.vim. 25" 26" REFERENCES: 27" [1] http://www.w3.org/TR/2000/REC-xml-20001006 28" [2] http://www.w3.org/XML/1998/06/xmlspec-report-19980910.htm 29" 30" as <[email protected]> pointed out according to reference [1] 31" 32" 2.3 Common Syntactic Constructs 33" [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender 34" [5] Name ::= (Letter | '_' | ':') (NameChar)* 35" 36" NOTE: 37" 1) empty tag delimiters "/>" inside attribute values (strings) 38" confuse syntax highlighting. 39" 2) for large files, folding can be pretty slow, especially when 40" loading a file the first time and viewoptions contains 'folds' 41" so that folds of previous sessions are applied. 42" Don't use 'foldmethod=syntax' in this case. 43 44 45" Quit when a syntax file was already loaded 46if exists("b:current_syntax") 47 finish 48endif 49 50let s:xml_cpo_save = &cpo 51set cpo&vim 52 53syn case match 54 55" mark illegal characters 56syn match xmlError "[<&]" 57 58" strings (inside tags) aka VALUES 59" 60" EXAMPLE: 61" 62" <tag foo.attribute = "value"> 63" ^^^^^^^ 64syn region xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display 65syn region xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display 66 67 68" punctuation (within attributes) e.g. <tag xml:foo.attribute ...> 69" ^ ^ 70" syn match xmlAttribPunct +[-:._]+ contained display 71syn match xmlAttribPunct +[:.]+ contained display 72 73" no highlighting for xmlEqual (xmlEqual has no highlighting group) 74syn match xmlEqual +=+ display 75 76 77" attribute, everything before the '=' 78" 79" PROVIDES: @xmlAttribHook 80" 81" EXAMPLE: 82" 83" <tag foo.attribute = "value"> 84" ^^^^^^^^^^^^^ 85" 86syn match xmlAttrib 87 \ +[-'"<]\@1<!\<[a-zA-Z:_][-.0-9a-zA-Z:_]*\>\%(['"]\@!\|$\)+ 88 \ contained 89 \ contains=xmlAttribPunct,@xmlAttribHook 90 \ display 91 92 93" namespace spec 94" 95" PROVIDES: @xmlNamespaceHook 96" 97" EXAMPLE: 98" 99" <xsl:for-each select = "lola"> 100" ^^^ 101" 102if exists("g:xml_namespace_transparent") 103syn match xmlNamespace 104 \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+ 105 \ contained 106 \ contains=@xmlNamespaceHook 107 \ transparent 108 \ display 109else 110syn match xmlNamespace 111 \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+ 112 \ contained 113 \ contains=@xmlNamespaceHook 114 \ display 115endif 116 117 118" tag name 119" 120" PROVIDES: @xmlTagHook 121" 122" EXAMPLE: 123" 124" <tag foo.attribute = "value"> 125" ^^^ 126" 127syn match xmlTagName 128 \ +\%(<\|</\)\@2<=[^ /!?<>"']\++ 129 \ contained 130 \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook 131 \ display 132 133 134if exists('g:xml_syntax_folding') 135 136 " start tag 137 " use matchgroup=xmlTag to skip over the leading '<' 138 " 139 " PROVIDES: @xmlStartTagHook 140 " 141 " EXAMPLE: 142 " 143 " <tag id="whoops"> 144 " s^^^^^^^^^^^^^^^e 145 " 146 syn region xmlTag 147 \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+ 148 \ matchgroup=xmlTag end=+>+ 149 \ contained 150 \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook 151 152 153 " highlight the end tag 154 " 155 " PROVIDES: @xmlTagHook 156 " (should we provide a separate @xmlEndTagHook ?) 157 " 158 " EXAMPLE: 159 " 160 " </tag> 161 " ^^^^^^ 162 " 163 syn region xmlEndTag 164 \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+ 165 \ matchgroup=xmlTag end=+>+ 166 \ contained 167 \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook 168 169 " tag elements with syntax-folding. 170 " NOTE: NO HIGHLIGHTING -- highlighting is done by contained elements 171 " 172 " PROVIDES: @xmlRegionHook 173 " 174 " EXAMPLE: 175 " 176 " <tag id="whoops"> 177 " <!-- comment --> 178 " <another.tag></another.tag> 179 " <empty.tag/> 180 " some data 181 " </tag> 182 " 183 syn region xmlRegion 184 \ start=+<\z([^ /!?<>"']\+\)+ 185 \ skip=+<!--\_.\{-}-->+ 186 \ end=+</\z1\_\s\{-}>+ 187 \ end=+/>+ 188 \ fold 189 \ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell 190 \ keepend 191 \ extend 192 193else 194 195 " no syntax folding: 196 " - contained attribute removed 197 " - xmlRegion not defined 198 " 199 syn region xmlTag 200 \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+ 201 \ matchgroup=xmlTag end=+>+ 202 \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook 203 204 syn region xmlEndTag 205 \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+ 206 \ matchgroup=xmlTag end=+>+ 207 \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook 208 209endif 210 211 212" &entities; compare with dtd 213syn match xmlEntity "&[^; \t]*;" contains=xmlEntityPunct 214syn match xmlEntityPunct contained "[&.;]" 215 216if exists('g:xml_syntax_folding') 217 218 " The real comments (this implements the comments as defined by xml, 219 " but not all xml pages actually conform to it. Errors are flagged. 220 syn region xmlComment 221 \ start=+<!+ 222 \ end=+>+ 223 \ contains=xmlCommentStart,xmlCommentError 224 \ extend 225 \ fold 226 227else 228 229 " no syntax folding: 230 " - fold attribute removed 231 " 232 syn region xmlComment 233 \ start=+<!+ 234 \ end=+>+ 235 \ contains=xmlCommentStart,xmlCommentError 236 \ extend 237 238endif 239 240syn match xmlCommentStart contained "<!" nextgroup=xmlCommentPart 241syn keyword xmlTodo contained TODO FIXME XXX 242syn match xmlCommentError contained "[^><!]" 243syn region xmlCommentPart 244 \ start=+--+ 245 \ end=+--+ 246 \ contained 247 \ contains=xmlTodo,@xmlCommentHook,@Spell 248 249 250" CData sections 251" 252" PROVIDES: @xmlCdataHook 253" 254syn region xmlCdata 255 \ start=+<!\[CDATA\[+ 256 \ end=+]]>+ 257 \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell 258 \ keepend 259 \ extend 260 261" using the following line instead leads to corrupt folding at CDATA regions 262" syn match xmlCdata +<!\[CDATA\[\_.\{-}]]>+ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook 263syn match xmlCdataStart +<!\[CDATA\[+ contained contains=xmlCdataCdata 264syn keyword xmlCdataCdata CDATA contained 265syn match xmlCdataEnd +]]>+ contained 266 267 268" Processing instructions 269" This allows "?>" inside strings -- good idea? 270syn region xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString 271 272 273if exists('g:xml_syntax_folding') 274 275 " DTD -- we use dtd.vim here 276 syn region xmlDocType matchgroup=xmlDocTypeDecl 277 \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">" 278 \ fold 279 \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString 280else 281 282 " no syntax folding: 283 " - fold attribute removed 284 " 285 syn region xmlDocType matchgroup=xmlDocTypeDecl 286 \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">" 287 \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString 288 289endif 290 291syn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM 292syn region xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD 293syn include @xmlDTD <sfile>:p:h/dtd.vim 294unlet b:current_syntax 295 296 297" synchronizing 298" TODO !!! to be improved !!! 299 300syn sync match xmlSyncDT grouphere xmlDocType +\_.\(<!DOCTYPE\)\@=+ 301" syn sync match xmlSyncDT groupthere NONE +]>+ 302 303if exists('g:xml_syntax_folding') 304 syn sync match xmlSync grouphere xmlRegion +\_.\(<[^ /!?<>"']\+\)\@=+ 305 " syn sync match xmlSync grouphere xmlRegion "<[^ /!?<>"']*>" 306 syn sync match xmlSync groupthere xmlRegion +</[^ /!?<>"']\+>+ 307endif 308 309syn sync minlines=100 310 311 312" The default highlighting. 313hi def link xmlTodo Todo 314hi def link xmlTag Function 315hi def link xmlTagName Function 316hi def link xmlEndTag Identifier 317if !exists("g:xml_namespace_transparent") 318 hi def link xmlNamespace Tag 319endif 320hi def link xmlEntity Statement 321hi def link xmlEntityPunct Type 322 323hi def link xmlAttribPunct Comment 324hi def link xmlAttrib Type 325 326hi def link xmlString String 327hi def link xmlComment Comment 328hi def link xmlCommentStart xmlComment 329hi def link xmlCommentPart Comment 330hi def link xmlCommentError Error 331hi def link xmlError Error 332 333hi def link xmlProcessingDelim Comment 334hi def link xmlProcessing Type 335 336hi def link xmlCdata String 337hi def link xmlCdataCdata Statement 338hi def link xmlCdataStart Type 339hi def link xmlCdataEnd Type 340 341hi def link xmlDocTypeDecl Function 342hi def link xmlDocTypeKeyword Statement 343hi def link xmlInlineDTD Function 344 345let b:current_syntax = "xml" 346 347let &cpo = s:xml_cpo_save 348unlet s:xml_cpo_save 349 350" vim: ts=8 351