blob: 87919790a59333ceda914fb954bcac35a12672db [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim syntax file
Bram Moolenaar96f45c02019-10-26 19:53:45 +02002" 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>
Bram Moolenaar4ceaa3a2019-12-03 22:49:09 +01007" Last Changed: Nov 03, 2019
Bram Moolenaar071d4272004-06-13 20:20:40 +00008" Filenames: *.xml
Bram Moolenaar96f45c02019-10-26 19:53:45 +02009" Last Change:
10" 20190923 - Fix xmlEndTag to match xmlTag (vim/vim#884)
11" 20190924 - Fix xmlAttribute property (amadeus/vim-xml@d8ce1c946)
Bram Moolenaar4ceaa3a2019-12-03 22:49:09 +010012" 20191103 - Enable spell checking globally
Bram Moolenaarfa3b7232021-12-24 13:18:38 +000013" 20210428 - Improve syntax synchronizing
Bram Moolenaar071d4272004-06-13 20:20:40 +000014
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
48if exists("b:current_syntax")
49 finish
50endif
51
52let s:xml_cpo_save = &cpo
53set cpo&vim
54
55syn case match
56
Bram Moolenaar4ceaa3a2019-12-03 22:49:09 +010057" 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>
61syn spell toplevel
62
Bram Moolenaar071d4272004-06-13 20:20:40 +000063" mark illegal characters
64syn match xmlError "[<&]"
65
66" strings (inside tags) aka VALUES
67"
68" EXAMPLE:
69"
70" <tag foo.attribute = "value">
71" ^^^^^^^
Bram Moolenaar4c3f5362006-04-11 21:38:50 +000072syn region xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display
73syn region xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display
Bram Moolenaar071d4272004-06-13 20:20:40 +000074
75
76" punctuation (within attributes) e.g. <tag xml:foo.attribute ...>
77" ^ ^
78" syn match xmlAttribPunct +[-:._]+ contained display
79syn match xmlAttribPunct +[:.]+ contained display
80
81" no highlighting for xmlEqual (xmlEqual has no highlighting group)
82syn 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"
94syn match xmlAttrib
Bram Moolenaar96f45c02019-10-26 19:53:45 +020095 \ +[-'"<]\@1<!\<[a-zA-Z:_][-.0-9a-zA-Z:_]*\>\%(['"]\@!\|$\)+
Bram Moolenaar071d4272004-06-13 20:20:40 +000096 \ 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"
110if exists("g:xml_namespace_transparent")
111syn match xmlNamespace
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200112 \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
Bram Moolenaar071d4272004-06-13 20:20:40 +0000113 \ contained
114 \ contains=@xmlNamespaceHook
115 \ transparent
116 \ display
117else
118syn match xmlNamespace
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200119 \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120 \ contained
121 \ contains=@xmlNamespaceHook
122 \ display
123endif
124
125
126" tag name
127"
128" PROVIDES: @xmlTagHook
129"
130" EXAMPLE:
131"
132" <tag foo.attribute = "value">
133" ^^^
134"
135syn match xmlTagName
Bram Moolenaar96f45c02019-10-26 19:53:45 +0200136 \ +\%(<\|</\)\@2<=[^ /!?<>"']\++
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137 \ contained
138 \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
139 \ display
140
141
142if 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 "
Bram Moolenaar96f45c02019-10-26 19:53:45 +0200171 syn region xmlEndTag
172 \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
173 \ matchgroup=xmlTag end=+>+
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174 \ contained
Bram Moolenaar96f45c02019-10-26 19:53:45 +0200175 \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
Bram Moolenaar071d4272004-06-13 20:20:40 +0000176
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\{-}>+
Bram Moolenaar96f45c02019-10-26 19:53:45 +0200195 \ end=+/>+
Bram Moolenaar071d4272004-06-13 20:20:40 +0000196 \ fold
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000197 \ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell
Bram Moolenaar071d4272004-06-13 20:20:40 +0000198 \ keepend
199 \ extend
200
201else
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
Bram Moolenaar96f45c02019-10-26 19:53:45 +0200212 syn region xmlEndTag
213 \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
214 \ matchgroup=xmlTag end=+>+
215 \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
Bram Moolenaar071d4272004-06-13 20:20:40 +0000216
217endif
218
219
220" &entities; compare with dtd
221syn match xmlEntity "&[^; \t]*;" contains=xmlEntityPunct
222syn match xmlEntityPunct contained "[&.;]"
223
224if 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=+>+
Bram Moolenaar5c736222010-01-06 20:54:52 +0100231 \ contains=xmlCommentStart,xmlCommentError
Bram Moolenaar071d4272004-06-13 20:20:40 +0000232 \ extend
233 \ fold
234
235else
236
237 " no syntax folding:
238 " - fold attribute removed
239 "
240 syn region xmlComment
241 \ start=+<!+
242 \ end=+>+
Bram Moolenaar5c736222010-01-06 20:54:52 +0100243 \ contains=xmlCommentStart,xmlCommentError
Bram Moolenaar071d4272004-06-13 20:20:40 +0000244 \ extend
245
246endif
247
Bram Moolenaar5c736222010-01-06 20:54:52 +0100248syn match xmlCommentStart contained "<!" nextgroup=xmlCommentPart
Bram Moolenaar402d2fe2005-04-15 21:00:38 +0000249syn keyword xmlTodo contained TODO FIXME XXX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000250syn match xmlCommentError contained "[^><!]"
251syn region xmlCommentPart
252 \ start=+--+
253 \ end=+--+
254 \ contained
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000255 \ contains=xmlTodo,@xmlCommentHook,@Spell
Bram Moolenaar071d4272004-06-13 20:20:40 +0000256
257
258" CData sections
259"
260" PROVIDES: @xmlCdataHook
261"
262syn region xmlCdata
263 \ start=+<!\[CDATA\[+
264 \ end=+]]>+
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000265 \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell
Bram Moolenaar071d4272004-06-13 20:20:40 +0000266 \ 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
271syn match xmlCdataStart +<!\[CDATA\[+ contained contains=xmlCdataCdata
272syn keyword xmlCdataCdata CDATA contained
273syn match xmlCdataEnd +]]>+ contained
274
275
276" Processing instructions
277" This allows "?>" inside strings -- good idea?
278syn region xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString
279
280
281if 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
288else
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
297endif
298
299syn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
300syn region xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD
Bram Moolenaar071d4272004-06-13 20:20:40 +0000301
Tanguy Pruvot502656a2016-11-24 00:27:24 +0100302if exists('g:xml_syntax_folding')
303 syn include @xmlDTD <sfile>:p:h/dtd.vim
304 unlet b:current_syntax
305endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000306
307" synchronizing
Bram Moolenaar071d4272004-06-13 20:20:40 +0000308
Bram Moolenaarfa3b7232021-12-24 13:18:38 +0000309syn sync match xmlSyncComment grouphere xmlComment +<!--+
310syn sync match xmlSyncComment groupthere NONE +-->+
311
312" The following is slow on large documents (and the doctype is optional
313" syn sync match xmlSyncDT grouphere xmlDocType +\_.\(<!DOCTYPE\)\@=+
Bram Moolenaar071d4272004-06-13 20:20:40 +0000314" syn sync match xmlSyncDT groupthere NONE +]>+
315
316if exists('g:xml_syntax_folding')
317 syn sync match xmlSync grouphere xmlRegion +\_.\(<[^ /!?<>"']\+\)\@=+
318 " syn sync match xmlSync grouphere xmlRegion "<[^ /!?<>"']*>"
319 syn sync match xmlSync groupthere xmlRegion +</[^ /!?<>"']\+>+
320endif
321
Bram Moolenaarfa3b7232021-12-24 13:18:38 +0000322syn sync minlines=100 maxlines=200
Bram Moolenaar071d4272004-06-13 20:20:40 +0000323
324
325" The default highlighting.
326hi def link xmlTodo Todo
327hi def link xmlTag Function
328hi def link xmlTagName Function
329hi def link xmlEndTag Identifier
330if !exists("g:xml_namespace_transparent")
331 hi def link xmlNamespace Tag
332endif
333hi def link xmlEntity Statement
334hi def link xmlEntityPunct Type
335
336hi def link xmlAttribPunct Comment
337hi def link xmlAttrib Type
338
339hi def link xmlString String
340hi def link xmlComment Comment
Bram Moolenaar5c736222010-01-06 20:54:52 +0100341hi def link xmlCommentStart xmlComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000342hi def link xmlCommentPart Comment
343hi def link xmlCommentError Error
344hi def link xmlError Error
345
346hi def link xmlProcessingDelim Comment
347hi def link xmlProcessing Type
348
349hi def link xmlCdata String
350hi def link xmlCdataCdata Statement
351hi def link xmlCdataStart Type
352hi def link xmlCdataEnd Type
353
354hi def link xmlDocTypeDecl Function
355hi def link xmlDocTypeKeyword Statement
356hi def link xmlInlineDTD Function
357
358let b:current_syntax = "xml"
359
360let &cpo = s:xml_cpo_save
361unlet s:xml_cpo_save
362
Bram Moolenaarfa3b7232021-12-24 13:18:38 +0000363" vim: ts=4