xml.vim 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. " Vim syntax file
  2. " 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: Nov 03, 2019
  8. " Filenames: *.xml
  9. " Last Change:
  10. " 20190923 - Fix xmlEndTag to match xmlTag (vim/vim#884)
  11. " 20190924 - Fix xmlAttribute property (amadeus/vim-xml@d8ce1c946)
  12. " 20191103 - Enable spell checking globally
  13. " 20210428 - Improve syntax synchronizing
  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. " Quit when a syntax file was already loaded
  45. if exists("b:current_syntax")
  46. finish
  47. endif
  48. let s:xml_cpo_save = &cpo
  49. set cpo&vim
  50. syn case match
  51. " Allow spell checking in tag values,
  52. " there is no syntax region for that,
  53. " so enable spell checking in top-level elements
  54. " <tag>This text is spell checked</tag>
  55. syn spell toplevel
  56. " mark illegal characters
  57. syn match xmlError "[<&]"
  58. " strings (inside tags) aka VALUES
  59. "
  60. " EXAMPLE:
  61. "
  62. " <tag foo.attribute = "value">
  63. " ^^^^^^^
  64. syn region xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display
  65. syn region xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display
  66. " punctuation (within attributes) e.g. <tag xml:foo.attribute ...>
  67. " ^ ^
  68. " syn match xmlAttribPunct +[-:._]+ contained display
  69. syn match xmlAttribPunct +[:.]+ contained display
  70. " no highlighting for xmlEqual (xmlEqual has no highlighting group)
  71. syn match xmlEqual +=+ display
  72. " attribute, everything before the '='
  73. "
  74. " PROVIDES: @xmlAttribHook
  75. "
  76. " EXAMPLE:
  77. "
  78. " <tag foo.attribute = "value">
  79. " ^^^^^^^^^^^^^
  80. "
  81. syn match xmlAttrib
  82. \ +[-'"<]\@1<!\<[a-zA-Z:_][-.0-9a-zA-Z:_]*\>\%(['"]\@!\|$\)+
  83. \ contained
  84. \ contains=xmlAttribPunct,@xmlAttribHook
  85. \ display
  86. " namespace spec
  87. "
  88. " PROVIDES: @xmlNamespaceHook
  89. "
  90. " EXAMPLE:
  91. "
  92. " <xsl:for-each select = "lola">
  93. " ^^^
  94. "
  95. if exists("g:xml_namespace_transparent")
  96. syn match xmlNamespace
  97. \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
  98. \ contained
  99. \ contains=@xmlNamespaceHook
  100. \ transparent
  101. \ display
  102. else
  103. syn match xmlNamespace
  104. \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
  105. \ contained
  106. \ contains=@xmlNamespaceHook
  107. \ display
  108. endif
  109. " tag name
  110. "
  111. " PROVIDES: @xmlTagHook
  112. "
  113. " EXAMPLE:
  114. "
  115. " <tag foo.attribute = "value">
  116. " ^^^
  117. "
  118. syn match xmlTagName
  119. \ +\%(<\|</\)\@2<=[^ /!?<>"']\++
  120. \ contained
  121. \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
  122. \ display
  123. if exists('g:xml_syntax_folding')
  124. " start tag
  125. " use matchgroup=xmlTag to skip over the leading '<'
  126. "
  127. " PROVIDES: @xmlStartTagHook
  128. "
  129. " EXAMPLE:
  130. "
  131. " <tag id="whoops">
  132. " s^^^^^^^^^^^^^^^e
  133. "
  134. syn region xmlTag
  135. \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
  136. \ matchgroup=xmlTag end=+>+
  137. \ contained
  138. \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
  139. " highlight the end tag
  140. "
  141. " PROVIDES: @xmlTagHook
  142. " (should we provide a separate @xmlEndTagHook ?)
  143. "
  144. " EXAMPLE:
  145. "
  146. " </tag>
  147. " ^^^^^^
  148. "
  149. syn region xmlEndTag
  150. \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
  151. \ matchgroup=xmlTag end=+>+
  152. \ contained
  153. \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
  154. " tag elements with syntax-folding.
  155. " NOTE: NO HIGHLIGHTING -- highlighting is done by contained elements
  156. "
  157. " PROVIDES: @xmlRegionHook
  158. "
  159. " EXAMPLE:
  160. "
  161. " <tag id="whoops">
  162. " <!-- comment -->
  163. " <another.tag></another.tag>
  164. " <empty.tag/>
  165. " some data
  166. " </tag>
  167. "
  168. syn region xmlRegion
  169. \ start=+<\z([^ /!?<>"']\+\)+
  170. \ skip=+<!--\_.\{-}-->+
  171. \ end=+</\z1\_\s\{-}>+
  172. \ end=+/>+
  173. \ fold
  174. \ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell
  175. \ keepend
  176. \ extend
  177. else
  178. " no syntax folding:
  179. " - contained attribute removed
  180. " - xmlRegion not defined
  181. "
  182. syn region xmlTag
  183. \ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
  184. \ matchgroup=xmlTag end=+>+
  185. \ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
  186. syn region xmlEndTag
  187. \ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
  188. \ matchgroup=xmlTag end=+>+
  189. \ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
  190. endif
  191. " &entities; compare with dtd
  192. syn match xmlEntity "&[^; \t]*;" contains=xmlEntityPunct
  193. syn match xmlEntityPunct contained "[&.;]"
  194. if exists('g:xml_syntax_folding')
  195. " The real comments (this implements the comments as defined by xml,
  196. " but not all xml pages actually conform to it. Errors are flagged.
  197. syn region xmlComment
  198. \ start=+<!+
  199. \ end=+>+
  200. \ contains=xmlCommentStart,xmlCommentError
  201. \ extend
  202. \ fold
  203. else
  204. " no syntax folding:
  205. " - fold attribute removed
  206. "
  207. syn region xmlComment
  208. \ start=+<!+
  209. \ end=+>+
  210. \ contains=xmlCommentStart,xmlCommentError
  211. \ extend
  212. endif
  213. syn match xmlCommentStart contained "<!" nextgroup=xmlCommentPart
  214. syn keyword xmlTodo contained TODO FIXME XXX
  215. syn match xmlCommentError contained "[^><!]"
  216. syn region xmlCommentPart
  217. \ start=+--+
  218. \ end=+--+
  219. \ contained
  220. \ contains=xmlTodo,@xmlCommentHook,@Spell
  221. " CData sections
  222. "
  223. " PROVIDES: @xmlCdataHook
  224. "
  225. syn region xmlCdata
  226. \ start=+<!\[CDATA\[+
  227. \ end=+]]>+
  228. \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell
  229. \ keepend
  230. \ extend
  231. " using the following line instead leads to corrupt folding at CDATA regions
  232. " syn match xmlCdata +<!\[CDATA\[\_.\{-}]]>+ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook
  233. syn match xmlCdataStart +<!\[CDATA\[+ contained contains=xmlCdataCdata
  234. syn keyword xmlCdataCdata CDATA contained
  235. syn match xmlCdataEnd +]]>+ contained
  236. " Processing instructions
  237. " This allows "?>" inside strings -- good idea?
  238. syn region xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString
  239. if exists('g:xml_syntax_folding')
  240. " DTD -- we use dtd.vim here
  241. syn region xmlDocType matchgroup=xmlDocTypeDecl
  242. \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
  243. \ fold
  244. \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
  245. else
  246. " no syntax folding:
  247. " - fold attribute removed
  248. "
  249. syn region xmlDocType matchgroup=xmlDocTypeDecl
  250. \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
  251. \ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
  252. endif
  253. syn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
  254. syn region xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD
  255. syn include @xmlDTD <sfile>:p:h/dtd.vim
  256. unlet b:current_syntax
  257. " synchronizing
  258. syn sync match xmlSyncComment grouphere xmlComment +<!--+
  259. syn sync match xmlSyncComment groupthere NONE +-->+
  260. " The following is slow on large documents (and the doctype is optional
  261. " syn sync match xmlSyncDT grouphere xmlDocType +\_.\(<!DOCTYPE\)\@=+
  262. " syn sync match xmlSyncDT groupthere NONE +]>+
  263. if exists('g:xml_syntax_folding')
  264. syn sync match xmlSync grouphere xmlRegion +\_.\(<[^ /!?<>"']\+\)\@=+
  265. " syn sync match xmlSync grouphere xmlRegion "<[^ /!?<>"']*>"
  266. syn sync match xmlSync groupthere xmlRegion +</[^ /!?<>"']\+>+
  267. endif
  268. syn sync minlines=100 maxlines=200
  269. " The default highlighting.
  270. hi def link xmlTodo Todo
  271. hi def link xmlTag Function
  272. hi def link xmlTagName Function
  273. hi def link xmlEndTag Identifier
  274. if !exists("g:xml_namespace_transparent")
  275. hi def link xmlNamespace Tag
  276. endif
  277. hi def link xmlEntity Statement
  278. hi def link xmlEntityPunct Type
  279. hi def link xmlAttribPunct Comment
  280. hi def link xmlAttrib Type
  281. hi def link xmlString String
  282. hi def link xmlComment Comment
  283. hi def link xmlCommentStart xmlComment
  284. hi def link xmlCommentPart Comment
  285. hi def link xmlCommentError Error
  286. hi def link xmlError Error
  287. hi def link xmlProcessingDelim Comment
  288. hi def link xmlProcessing Type
  289. hi def link xmlCdata String
  290. hi def link xmlCdataCdata Statement
  291. hi def link xmlCdataStart Type
  292. hi def link xmlCdataEnd Type
  293. hi def link xmlDocTypeDecl Function
  294. hi def link xmlDocTypeKeyword Statement
  295. hi def link xmlInlineDTD Function
  296. let b:current_syntax = "xml"
  297. let &cpo = s:xml_cpo_save
  298. unlet s:xml_cpo_save
  299. " vim: ts=4