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