xref: /vim-8.2.3635/runtime/syntax/xml.vim (revision 4ceaa3a6)
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