1071d4279SBram Moolenaar" Vim syntax file 2071d4279SBram Moolenaar" Language: XML 396f45c0bSBram Moolenaar" Maintainer: Christian Brabandt <[email protected]> 496f45c0bSBram Moolenaar" Repository: https://github.com/chrisbra/vim-xml-ftplugin 596f45c0bSBram Moolenaar" Previous Maintainer: Johannes Zellner <[email protected]> 696f45c0bSBram Moolenaar" Author: Paul Siegmann <[email protected]> 7*4ceaa3a6SBram Moolenaar" Last Changed: Nov 03, 2019 8071d4279SBram Moolenaar" Filenames: *.xml 996f45c0bSBram Moolenaar" Last Change: 1096f45c0bSBram Moolenaar" 20190923 - Fix xmlEndTag to match xmlTag (vim/vim#884) 1196f45c0bSBram Moolenaar" 20190924 - Fix xmlAttribute property (amadeus/vim-xml@d8ce1c946) 12*4ceaa3a6SBram Moolenaar" 20191103 - Enable spell checking globally 13071d4279SBram Moolenaar 14071d4279SBram Moolenaar" CONFIGURATION: 15071d4279SBram Moolenaar" syntax folding can be turned on by 16071d4279SBram Moolenaar" 17071d4279SBram Moolenaar" let g:xml_syntax_folding = 1 18071d4279SBram Moolenaar" 19071d4279SBram Moolenaar" before the syntax file gets loaded (e.g. in ~/.vimrc). 20071d4279SBram Moolenaar" This might slow down syntax highlighting significantly, 21071d4279SBram Moolenaar" especially for large files. 22071d4279SBram Moolenaar" 23071d4279SBram Moolenaar" CREDITS: 24071d4279SBram Moolenaar" The original version was derived by Paul Siegmann from 25071d4279SBram Moolenaar" Claudio Fleiner's html.vim. 26071d4279SBram Moolenaar" 27071d4279SBram Moolenaar" REFERENCES: 28071d4279SBram Moolenaar" [1] http://www.w3.org/TR/2000/REC-xml-20001006 29071d4279SBram Moolenaar" [2] http://www.w3.org/XML/1998/06/xmlspec-report-19980910.htm 30071d4279SBram Moolenaar" 31071d4279SBram Moolenaar" as <[email protected]> pointed out according to reference [1] 32071d4279SBram Moolenaar" 33071d4279SBram Moolenaar" 2.3 Common Syntactic Constructs 34071d4279SBram Moolenaar" [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender 35071d4279SBram Moolenaar" [5] Name ::= (Letter | '_' | ':') (NameChar)* 36071d4279SBram Moolenaar" 37071d4279SBram Moolenaar" NOTE: 38071d4279SBram Moolenaar" 1) empty tag delimiters "/>" inside attribute values (strings) 39071d4279SBram Moolenaar" confuse syntax highlighting. 40071d4279SBram Moolenaar" 2) for large files, folding can be pretty slow, especially when 41071d4279SBram Moolenaar" loading a file the first time and viewoptions contains 'folds' 42071d4279SBram Moolenaar" so that folds of previous sessions are applied. 43071d4279SBram Moolenaar" Don't use 'foldmethod=syntax' in this case. 44071d4279SBram Moolenaar 45071d4279SBram Moolenaar 46071d4279SBram Moolenaar" Quit when a syntax file was already loaded 47071d4279SBram Moolenaarif exists("b:current_syntax") 48071d4279SBram Moolenaar finish 49071d4279SBram Moolenaarendif 50071d4279SBram Moolenaar 51071d4279SBram Moolenaarlet s:xml_cpo_save = &cpo 52071d4279SBram Moolenaarset cpo&vim 53071d4279SBram Moolenaar 54071d4279SBram Moolenaarsyn case match 55071d4279SBram Moolenaar 56*4ceaa3a6SBram Moolenaar" Allow spell checking in tag values, 57*4ceaa3a6SBram Moolenaar" there is no syntax region for that, 58*4ceaa3a6SBram Moolenaar" so enable spell checking in top-level elements 59*4ceaa3a6SBram Moolenaar" <tag>This text is spell checked</tag> 60*4ceaa3a6SBram Moolenaarsyn spell toplevel 61*4ceaa3a6SBram Moolenaar 62071d4279SBram Moolenaar" mark illegal characters 63071d4279SBram Moolenaarsyn match xmlError "[<&]" 64071d4279SBram Moolenaar 65071d4279SBram Moolenaar" strings (inside tags) aka VALUES 66071d4279SBram Moolenaar" 67071d4279SBram Moolenaar" EXAMPLE: 68071d4279SBram Moolenaar" 69071d4279SBram Moolenaar" <tag foo.attribute = "value"> 70071d4279SBram Moolenaar" ^^^^^^^ 714c3f536fSBram Moolenaarsyn region xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display 724c3f536fSBram Moolenaarsyn region xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display 73071d4279SBram Moolenaar 74071d4279SBram Moolenaar 75071d4279SBram Moolenaar" punctuation (within attributes) e.g. <tag xml:foo.attribute ...> 76071d4279SBram Moolenaar" ^ ^ 77071d4279SBram Moolenaar" syn match xmlAttribPunct +[-:._]+ contained display 78071d4279SBram Moolenaarsyn match xmlAttribPunct +[:.]+ contained display 79071d4279SBram Moolenaar 80071d4279SBram Moolenaar" no highlighting for xmlEqual (xmlEqual has no highlighting group) 81071d4279SBram Moolenaarsyn match xmlEqual +=+ display 82071d4279SBram Moolenaar 83071d4279SBram Moolenaar 84071d4279SBram Moolenaar" attribute, everything before the '=' 85071d4279SBram Moolenaar" 86071d4279SBram Moolenaar" PROVIDES: @xmlAttribHook 87071d4279SBram Moolenaar" 88071d4279SBram Moolenaar" EXAMPLE: 89071d4279SBram Moolenaar" 90071d4279SBram Moolenaar" <tag foo.attribute = "value"> 91071d4279SBram Moolenaar" ^^^^^^^^^^^^^ 92071d4279SBram Moolenaar" 93071d4279SBram Moolenaarsyn match xmlAttrib 9496f45c0bSBram Moolenaar \ +[-'"<]\@1<!\<[a-zA-Z:_][-.0-9a-zA-Z:_]*\>\%(['"]\@!\|$\)+ 95071d4279SBram Moolenaar \ contained 96071d4279SBram Moolenaar \ contains=xmlAttribPunct,@xmlAttribHook 97071d4279SBram Moolenaar \ display 98071d4279SBram Moolenaar 99071d4279SBram Moolenaar 100071d4279SBram Moolenaar" namespace spec 101071d4279SBram Moolenaar" 102071d4279SBram Moolenaar" PROVIDES: @xmlNamespaceHook 103071d4279SBram Moolenaar" 104071d4279SBram Moolenaar" EXAMPLE: 105071d4279SBram Moolenaar" 106071d4279SBram Moolenaar" <xsl:for-each select = "lola"> 107071d4279SBram Moolenaar" ^^^ 108071d4279SBram Moolenaar" 109071d4279SBram Moolenaarif exists("g:xml_namespace_transparent") 110071d4279SBram Moolenaarsyn match xmlNamespace 111543b7ef7SBram Moolenaar \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+ 112071d4279SBram Moolenaar \ contained 113071d4279SBram Moolenaar \ contains=@xmlNamespaceHook 114071d4279SBram Moolenaar \ transparent 115071d4279SBram Moolenaar \ display 116071d4279SBram Moolenaarelse 117071d4279SBram Moolenaarsyn match xmlNamespace 118543b7ef7SBram Moolenaar \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+ 119071d4279SBram Moolenaar \ contained 120071d4279SBram Moolenaar \ contains=@xmlNamespaceHook 121071d4279SBram Moolenaar \ display 122071d4279SBram Moolenaarendif 123071d4279SBram Moolenaar 124071d4279SBram Moolenaar 125071d4279SBram Moolenaar" tag name 126071d4279SBram Moolenaar" 127071d4279SBram Moolenaar" PROVIDES: @xmlTagHook 128071d4279SBram Moolenaar" 129071d4279SBram Moolenaar" EXAMPLE: 130071d4279SBram Moolenaar" 131071d4279SBram Moolenaar" <tag foo.attribute = "value"> 132071d4279SBram Moolenaar" ^^^ 133071d4279SBram Moolenaar" 134071d4279SBram Moolenaarsyn match xmlTagName 13596f45c0bSBram Moolenaar \ +\%(<\|</\)\@2<=[^ /!?<>"']\++ 136071d4279SBram Moolenaar \ contained 137071d4279SBram Moolenaar \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook 138071d4279SBram Moolenaar \ display 139071d4279SBram Moolenaar 140071d4279SBram Moolenaar 141071d4279SBram Moolenaarif exists('g:xml_syntax_folding') 142071d4279SBram Moolenaar 143071d4279SBram Moolenaar " start tag 144071d4279SBram Moolenaar " use matchgroup=xmlTag to skip over the leading '<' 145071d4279SBram Moolenaar " 146071d4279SBram Moolenaar " PROVIDES: @xmlStartTagHook 147071d4279SBram Moolenaar " 148071d4279SBram Moolenaar " EXAMPLE: 149071d4279SBram Moolenaar " 150071d4279SBram Moolenaar " <tag id="whoops"> 151071d4279SBram Moolenaar " s^^^^^^^^^^^^^^^e 152071d4279SBram Moolenaar " 153071d4279SBram Moolenaar syn region xmlTag 154071d4279SBram Moolenaar \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+ 155071d4279SBram Moolenaar \ matchgroup=xmlTag end=+>+ 156071d4279SBram Moolenaar \ contained 157071d4279SBram Moolenaar \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook 158071d4279SBram Moolenaar 159071d4279SBram Moolenaar 160071d4279SBram Moolenaar " highlight the end tag 161071d4279SBram Moolenaar " 162071d4279SBram Moolenaar " PROVIDES: @xmlTagHook 163071d4279SBram Moolenaar " (should we provide a separate @xmlEndTagHook ?) 164071d4279SBram Moolenaar " 165071d4279SBram Moolenaar " EXAMPLE: 166071d4279SBram Moolenaar " 167071d4279SBram Moolenaar " </tag> 168071d4279SBram Moolenaar " ^^^^^^ 169071d4279SBram Moolenaar " 17096f45c0bSBram Moolenaar syn region xmlEndTag 17196f45c0bSBram Moolenaar \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+ 17296f45c0bSBram Moolenaar \ matchgroup=xmlTag end=+>+ 173071d4279SBram Moolenaar \ contained 17496f45c0bSBram Moolenaar \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook 175071d4279SBram Moolenaar 176071d4279SBram Moolenaar " tag elements with syntax-folding. 177071d4279SBram Moolenaar " NOTE: NO HIGHLIGHTING -- highlighting is done by contained elements 178071d4279SBram Moolenaar " 179071d4279SBram Moolenaar " PROVIDES: @xmlRegionHook 180071d4279SBram Moolenaar " 181071d4279SBram Moolenaar " EXAMPLE: 182071d4279SBram Moolenaar " 183071d4279SBram Moolenaar " <tag id="whoops"> 184071d4279SBram Moolenaar " <!-- comment --> 185071d4279SBram Moolenaar " <another.tag></another.tag> 186071d4279SBram Moolenaar " <empty.tag/> 187071d4279SBram Moolenaar " some data 188071d4279SBram Moolenaar " </tag> 189071d4279SBram Moolenaar " 190071d4279SBram Moolenaar syn region xmlRegion 191071d4279SBram Moolenaar \ start=+<\z([^ /!?<>"']\+\)+ 192071d4279SBram Moolenaar \ skip=+<!--\_.\{-}-->+ 193071d4279SBram Moolenaar \ end=+</\z1\_\s\{-}>+ 19496f45c0bSBram Moolenaar \ end=+/>+ 195071d4279SBram Moolenaar \ fold 1964c3f536fSBram Moolenaar \ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell 197071d4279SBram Moolenaar \ keepend 198071d4279SBram Moolenaar \ extend 199071d4279SBram Moolenaar 200071d4279SBram Moolenaarelse 201071d4279SBram Moolenaar 202071d4279SBram Moolenaar " no syntax folding: 203071d4279SBram Moolenaar " - contained attribute removed 204071d4279SBram Moolenaar " - xmlRegion not defined 205071d4279SBram Moolenaar " 206071d4279SBram Moolenaar syn region xmlTag 207071d4279SBram Moolenaar \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+ 208071d4279SBram Moolenaar \ matchgroup=xmlTag end=+>+ 209071d4279SBram Moolenaar \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook 210071d4279SBram Moolenaar 21196f45c0bSBram Moolenaar syn region xmlEndTag 21296f45c0bSBram Moolenaar \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+ 21396f45c0bSBram Moolenaar \ matchgroup=xmlTag end=+>+ 21496f45c0bSBram Moolenaar \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook 215071d4279SBram Moolenaar 216071d4279SBram Moolenaarendif 217071d4279SBram Moolenaar 218071d4279SBram Moolenaar 219071d4279SBram Moolenaar" &entities; compare with dtd 220071d4279SBram Moolenaarsyn match xmlEntity "&[^; \t]*;" contains=xmlEntityPunct 221071d4279SBram Moolenaarsyn match xmlEntityPunct contained "[&.;]" 222071d4279SBram Moolenaar 223071d4279SBram Moolenaarif exists('g:xml_syntax_folding') 224071d4279SBram Moolenaar 225071d4279SBram Moolenaar " The real comments (this implements the comments as defined by xml, 226071d4279SBram Moolenaar " but not all xml pages actually conform to it. Errors are flagged. 227071d4279SBram Moolenaar syn region xmlComment 228071d4279SBram Moolenaar \ start=+<!+ 229071d4279SBram Moolenaar \ end=+>+ 2305c73622aSBram Moolenaar \ contains=xmlCommentStart,xmlCommentError 231071d4279SBram Moolenaar \ extend 232071d4279SBram Moolenaar \ fold 233071d4279SBram Moolenaar 234071d4279SBram Moolenaarelse 235071d4279SBram Moolenaar 236071d4279SBram Moolenaar " no syntax folding: 237071d4279SBram Moolenaar " - fold attribute removed 238071d4279SBram Moolenaar " 239071d4279SBram Moolenaar syn region xmlComment 240071d4279SBram Moolenaar \ start=+<!+ 241071d4279SBram Moolenaar \ end=+>+ 2425c73622aSBram Moolenaar \ contains=xmlCommentStart,xmlCommentError 243071d4279SBram Moolenaar \ extend 244071d4279SBram Moolenaar 245071d4279SBram Moolenaarendif 246071d4279SBram Moolenaar 2475c73622aSBram Moolenaarsyn match xmlCommentStart contained "<!" nextgroup=xmlCommentPart 248402d2feaSBram Moolenaarsyn keyword xmlTodo contained TODO FIXME XXX 249071d4279SBram Moolenaarsyn match xmlCommentError contained "[^><!]" 250071d4279SBram Moolenaarsyn region xmlCommentPart 251071d4279SBram Moolenaar \ start=+--+ 252071d4279SBram Moolenaar \ end=+--+ 253071d4279SBram Moolenaar \ contained 2544c3f536fSBram Moolenaar \ contains=xmlTodo,@xmlCommentHook,@Spell 255071d4279SBram Moolenaar 256071d4279SBram Moolenaar 257071d4279SBram Moolenaar" CData sections 258071d4279SBram Moolenaar" 259071d4279SBram Moolenaar" PROVIDES: @xmlCdataHook 260071d4279SBram Moolenaar" 261071d4279SBram Moolenaarsyn region xmlCdata 262071d4279SBram Moolenaar \ start=+<!\[CDATA\[+ 263071d4279SBram Moolenaar \ end=+]]>+ 2644c3f536fSBram Moolenaar \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell 265071d4279SBram Moolenaar \ keepend 266071d4279SBram Moolenaar \ extend 267071d4279SBram Moolenaar 268071d4279SBram Moolenaar" using the following line instead leads to corrupt folding at CDATA regions 269071d4279SBram Moolenaar" syn match xmlCdata +<!\[CDATA\[\_.\{-}]]>+ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook 270071d4279SBram Moolenaarsyn match xmlCdataStart +<!\[CDATA\[+ contained contains=xmlCdataCdata 271071d4279SBram Moolenaarsyn keyword xmlCdataCdata CDATA contained 272071d4279SBram Moolenaarsyn match xmlCdataEnd +]]>+ contained 273071d4279SBram Moolenaar 274071d4279SBram Moolenaar 275071d4279SBram Moolenaar" Processing instructions 276071d4279SBram Moolenaar" This allows "?>" inside strings -- good idea? 277071d4279SBram Moolenaarsyn region xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString 278071d4279SBram Moolenaar 279071d4279SBram Moolenaar 280071d4279SBram Moolenaarif exists('g:xml_syntax_folding') 281071d4279SBram Moolenaar 282071d4279SBram Moolenaar " DTD -- we use dtd.vim here 283071d4279SBram Moolenaar syn region xmlDocType matchgroup=xmlDocTypeDecl 284071d4279SBram Moolenaar \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">" 285071d4279SBram Moolenaar \ fold 286071d4279SBram Moolenaar \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString 287071d4279SBram Moolenaarelse 288071d4279SBram Moolenaar 289071d4279SBram Moolenaar " no syntax folding: 290071d4279SBram Moolenaar " - fold attribute removed 291071d4279SBram Moolenaar " 292071d4279SBram Moolenaar syn region xmlDocType matchgroup=xmlDocTypeDecl 293071d4279SBram Moolenaar \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">" 294071d4279SBram Moolenaar \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString 295071d4279SBram Moolenaar 296071d4279SBram Moolenaarendif 297071d4279SBram Moolenaar 298071d4279SBram Moolenaarsyn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM 299071d4279SBram Moolenaarsyn region xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD 300071d4279SBram Moolenaarsyn include @xmlDTD <sfile>:p:h/dtd.vim 301071d4279SBram Moolenaarunlet b:current_syntax 302071d4279SBram Moolenaar 303071d4279SBram Moolenaar 304071d4279SBram Moolenaar" synchronizing 305071d4279SBram Moolenaar" TODO !!! to be improved !!! 306071d4279SBram Moolenaar 307071d4279SBram Moolenaarsyn sync match xmlSyncDT grouphere xmlDocType +\_.\(<!DOCTYPE\)\@=+ 308071d4279SBram Moolenaar" syn sync match xmlSyncDT groupthere NONE +]>+ 309071d4279SBram Moolenaar 310071d4279SBram Moolenaarif exists('g:xml_syntax_folding') 311071d4279SBram Moolenaar syn sync match xmlSync grouphere xmlRegion +\_.\(<[^ /!?<>"']\+\)\@=+ 312071d4279SBram Moolenaar " syn sync match xmlSync grouphere xmlRegion "<[^ /!?<>"']*>" 313071d4279SBram Moolenaar syn sync match xmlSync groupthere xmlRegion +</[^ /!?<>"']\+>+ 314071d4279SBram Moolenaarendif 315071d4279SBram Moolenaar 316071d4279SBram Moolenaarsyn sync minlines=100 317071d4279SBram Moolenaar 318071d4279SBram Moolenaar 319071d4279SBram Moolenaar" The default highlighting. 320071d4279SBram Moolenaarhi def link xmlTodo Todo 321071d4279SBram Moolenaarhi def link xmlTag Function 322071d4279SBram Moolenaarhi def link xmlTagName Function 323071d4279SBram Moolenaarhi def link xmlEndTag Identifier 324071d4279SBram Moolenaarif !exists("g:xml_namespace_transparent") 325071d4279SBram Moolenaar hi def link xmlNamespace Tag 326071d4279SBram Moolenaarendif 327071d4279SBram Moolenaarhi def link xmlEntity Statement 328071d4279SBram Moolenaarhi def link xmlEntityPunct Type 329071d4279SBram Moolenaar 330071d4279SBram Moolenaarhi def link xmlAttribPunct Comment 331071d4279SBram Moolenaarhi def link xmlAttrib Type 332071d4279SBram Moolenaar 333071d4279SBram Moolenaarhi def link xmlString String 334071d4279SBram Moolenaarhi def link xmlComment Comment 3355c73622aSBram Moolenaarhi def link xmlCommentStart xmlComment 336071d4279SBram Moolenaarhi def link xmlCommentPart Comment 337071d4279SBram Moolenaarhi def link xmlCommentError Error 338071d4279SBram Moolenaarhi def link xmlError Error 339071d4279SBram Moolenaar 340071d4279SBram Moolenaarhi def link xmlProcessingDelim Comment 341071d4279SBram Moolenaarhi def link xmlProcessing Type 342071d4279SBram Moolenaar 343071d4279SBram Moolenaarhi def link xmlCdata String 344071d4279SBram Moolenaarhi def link xmlCdataCdata Statement 345071d4279SBram Moolenaarhi def link xmlCdataStart Type 346071d4279SBram Moolenaarhi def link xmlCdataEnd Type 347071d4279SBram Moolenaar 348071d4279SBram Moolenaarhi def link xmlDocTypeDecl Function 349071d4279SBram Moolenaarhi def link xmlDocTypeKeyword Statement 350071d4279SBram Moolenaarhi def link xmlInlineDTD Function 351071d4279SBram Moolenaar 352071d4279SBram Moolenaarlet b:current_syntax = "xml" 353071d4279SBram Moolenaar 354071d4279SBram Moolenaarlet &cpo = s:xml_cpo_save 355071d4279SBram Moolenaarunlet s:xml_cpo_save 356071d4279SBram Moolenaar 357071d4279SBram Moolenaar" vim: ts=8 358