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