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