Skip to content

Instantly share code, notes, and snippets.

@MattDMo
Created January 21, 2016 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MattDMo/39a9669b76f4a7529e3e to your computer and use it in GitHub Desktop.
Save MattDMo/39a9669b76f4a7529e3e to your computer and use it in GitHub Desktop.
Unicode-compatible XML syntax definition for Sublime Text 2/3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>xml</string>
<string>tld</string>
<string>jsp</string>
<string>pt</string>
<string>cpt</string>
<string>dtml</string>
<string>rss</string>
<string>opml</string>
</array>
<key>firstLineMatch</key>
<string>^&lt;\?xml </string>
<key>foldingStartMarker</key>
<string>^\s*(&lt;[^!?%/](?!.+?(/&gt;|&lt;/.+?&gt;))|&lt;[!%]--(?!.+?--%?&gt;)|&lt;%[!]?(?!.+?%&gt;))</string>
<key>foldingStopMarker</key>
<string>^\s*(&lt;/[^&gt;]+&gt;|[/%]&gt;|--&gt;)\s*$</string>
<key>keyEquivalent</key>
<string>^~X</string>
<key>name</key>
<string>XML</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(&lt;\?)\s*([-_\p{Alnum}]+)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
</dict>
<key>end</key>
<string>(\?&gt;)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.preprocessor.xml</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string> ([a-zA-Z-]+)</string>
<key>name</key>
<string>entity.other.attribute-name.xml</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(&lt;!)(DOCTYPE)\s+([:\p{Alpha}_][:\p{Alnum}_.-]*)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.doctype.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>variable.documentroot.xml</string>
</dict>
</dict>
<key>end</key>
<string>\s*(&gt;)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.sgml.doctype.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#internalSubset</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>&lt;[!%]--</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.xml</string>
</dict>
</dict>
<key>end</key>
<string>--%?&gt;</string>
<key>name</key>
<string>comment.block.xml</string>
</dict>
<dict>
<key>begin</key>
<string>(&lt;)((?:([-_\p{Alnum}]+)((:)))?([-_\p{Alnum}:]+))(?=(\s[^&gt;]*)?&gt;&lt;/\2&gt;)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
</dict>
<key>end</key>
<string>(&gt;)(&lt;)(/)(?:([-_\p{Alnum}]+)((:)))?([-_\p{Alnum}:]+)(&gt;)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml meta.scope.between-tag-pair.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.no-content.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#tagStuff</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(&lt;/?)(?:([-_\p{Alnum}]+)((:)))?([-_\p{Alnum}:]+)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
</dict>
<key>end</key>
<string>(/?&gt;)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#tagStuff</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
<dict>
<key>begin</key>
<string>&lt;%@</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.embedded.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>%&gt;</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.embedded.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>source.java-props.embedded.xml</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>page|include|taglib</string>
<key>name</key>
<string>keyword.other.page-props.xml</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>&lt;%[!=]?(?!--)</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.embedded.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>(?!--)%&gt;</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.embedded.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>source.java.embedded.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>source.java</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>&lt;!\[CDATA\[</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>]]&gt;</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.unquoted.cdata.xml</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>EntityDecl</key>
<dict>
<key>begin</key>
<string>(&lt;!)(ENTITY)\s+(%\s+)?([:\p{Alpha}_][:\p{Alnum}_.-]*)(\s+(?:SYSTEM|PUBLIC)\s+)?</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.entity.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>variable.entity.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>keyword.entitytype.xml</string>
</dict>
</dict>
<key>end</key>
<string>(&gt;)</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
</array>
</dict>
<key>bare-ampersand</key>
<dict>
<key>match</key>
<string>&amp;</string>
<key>name</key>
<string>invalid.illegal.bad-ampersand.xml</string>
</dict>
<key>doublequotedString</key>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
</array>
</dict>
<key>entity</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>match</key>
<string>(&amp;)([:\p{Alpha}_][:\p{Alnum}_.-]*|#[0-9]+|#x\h+)(;)</string>
<key>name</key>
<string>constant.character.entity.xml</string>
</dict>
<key>internalSubset</key>
<dict>
<key>begin</key>
<string>(\[)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>end</key>
<string>(\])</string>
<key>name</key>
<string>meta.internalsubset.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#EntityDecl</string>
</dict>
<dict>
<key>include</key>
<string>#parameterEntity</string>
</dict>
</array>
</dict>
<key>parameterEntity</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>match</key>
<string>(%)([:\p{Alpha}_][:\p{Alnum}_.-]*)(;)</string>
<key>name</key>
<string>constant.character.parameter-entity.xml</string>
</dict>
<key>singlequotedString</key>
<dict>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
</array>
</dict>
<key>tagStuff</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.namespace.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.localname.xml</string>
</dict>
</dict>
<key>match</key>
<string> (?:([-_\p{Alnum}]+)((:)))?([-_\p{Alnum}]+)=</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>text.xml</string>
<key>uuid</key>
<string>D3C4E6DA-6B1C-11D9-8CC2-000D93589AF6</string>
</dict>
</plist>
@MattDMo
Copy link
Author

MattDMo commented Jan 21, 2016

Background

The XML syntax highlighting language definition that ships with Sublime Text 2/3 does not recognize non-ASCII tags:

Note: The Neon Color Scheme is used for syntax highlighting

Current XML

However, replacing it with the file in this gist fixes that problem, along with a few minor things:

New XML

## How to install ### Sublime Text 2

In Sublime, open a new file and paste in the contents of this gist. Save the file to your Desktop as XML.tmLanguage. Open your Packages folder by selecting Preferences -> Browse Packages..., then close Sublime. Scroll down to the XML folder and rename XML.tmLanguage as XML.tmLanguage.old. If it exists, delete XML.tmLanguage.cache. Now, copy the new XML.tmLanguage from your Desktop to Packages/XML. The next time you open an XML file in Sublime, it will use the new syntax.

Sublime Text 3 Build <= 3083 (public beta)

In Sublime, open a new file and paste in the contents of this gist. Save the file to your Desktop as XML.tmLanguage. Open your Packages folder by selecting Preferences -> Browse Packages..., then close Sublime. Create a new folder in Packages named XML and copy the new XML.tmLanguage from your Desktop to Packages/XML. The next time you open an XML file in Sublime, it will use the new syntax.

Sublime Text 3 Build > 3083 (dev builds)

In Sublime, open a new file and paste in the contents of this gist. Save the file to your Desktop as XML.tmLanguage. Create another new file in Sublime with the following contents:

%YAML 1.2

---
name: XML-ss
file_extensions:
first_line_match: '^<\?xml '
scope: text.xml
contexts:
  main:
    - match: ''

---

Save this file to your Desktop as XML.sublime-syntax. Open your Packages folder by selecting Preferences -> Browse Packages..., then close Sublime. Create a new folder in Packages named XML and copy the new XML.tmLanguage and XML.sublime-syntax files from your Desktop to Packages/XML. The next time you open an XML file in Sublime, it will use the new syntax. There will be a new entry in the syntax menu called XML-ss (for sublime-syntax), just ignore it.

How it works

Sublime Text 2

Here, we simply replace the old language definition (.tmLanguage file) with the new one.

Sublime Text 3

In Sublime Text 3, the default packages (and many that you install with Package Control) are stored in a separate directory as zipped .sublime-package files. However, if you create a folder and file in the Packages folder with the same name as a package (XML in this case) and file contained within it, the version in Packages will override the version in the sublime-package archive. For ST3 builds 3083 and before, the same XML-based .tmLanguage format as ST2 was used.

However, starting with dev build 3084 and beyond, a new YAML-based .sublime-syntax format was introduced, and all of the default syntax definitions were converted. The .tmLanguage format is still supported, however, but we needed to override the XML/XML.sublime-syntax file first in order for our new .tmLanguage file to be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment