├── .gitignore
├── LICENSE
├── README.md
├── demo
├── index.html
├── index.ts
├── modeSamples
│ ├── html.ts
│ ├── javascript.ts
│ └── typescript.ts
├── package.json
├── tm
│ ├── grammars
│ │ ├── JavaScript.tmLanguage.json
│ │ ├── TypeScript.tmLanguage.json
│ │ ├── css.styled.tmLanguage.json
│ │ ├── css.tmLanguage.json
│ │ ├── html.tmLanguage.json
│ │ ├── python.tmLanguage.json
│ │ ├── smarty.tmLanguage.json
│ │ └── styled.tmLanguage.json
│ └── themes
│ │ └── OneDark.tmTheme.json
├── tsconfig.json
└── webpack.config.js
├── package.json
├── src
├── Highlighter.ts
├── index.ts
└── tmToCm.ts
├── tsconfig.json
└── tslint.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Build output
40 | dist/
41 |
42 | # TypeScript v1 declaration files
43 | typings/
44 |
45 | # Optional npm cache directory
46 | .npm
47 |
48 | # Optional eslint cache
49 | .eslintcache
50 |
51 | # Optional REPL history
52 | .node_repl_history
53 |
54 | # Output of 'npm pack'
55 | *.tgz
56 |
57 | # npm/yarn lock files
58 | package-lock.json
59 | yarn.lock
60 |
61 | # Yarn Integrity file
62 | .yarn-integrity
63 |
64 | # dotenv environment variables file
65 | .env
66 |
67 | # parcel-bundler cache (https://parceljs.org/)
68 | .cache
69 |
70 | # next.js build output
71 | .next
72 |
73 | # nuxt.js build output
74 | .nuxt
75 |
76 | # vuepress build output
77 | .vuepress/dist
78 |
79 | # Serverless directories
80 | .serverless
81 |
82 | # FuseBox cache
83 | .fusebox/
84 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Neek Sandhu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Textmate grammars support for CodeMirror
2 |
3 | Bring TM grammar driven tokenization to your CodeMirror editors.
4 |
5 | Say goodbye to the not-so-cool and not-so-accurate syntax highlighting you've been living with and up your game with ease!
6 |
7 | ### WARNING
8 |
9 | This package will only work in browsers with `WebAssembly` support. Here's a recommended way to deal with it:
10 |
11 | ```javascript
12 | // 95% of your target audience (developers)
13 | if ('WebAssembly' in window) {
14 | const [{
15 | loadWASM
16 | },
17 | {
18 | activateLanguage,
19 | addGrammar
20 | }
21 | ] = await Promise.all([
22 | import('onigasm'),
23 | import('codemirror-textmate'),
24 | ])
25 |
26 | // ... (see https://www.npmjs.com/package/onigasm#light-it-up)
27 | // ... (see example code below)
28 | }
29 | // Fallback for rest 5%
30 | else {
31 | await Promise.all([
32 | import('codemirror/mode/javascript/javascript'),
33 | import( 'codemirror/mode/htmlmixed/htmlmixed'),
34 | ])
35 | }
36 |
37 | const editor = CodeMirror.fromTextArea( /* ... */ )
38 | // ... (go on as usual)
39 | ```
40 |
41 | ## Usage
42 |
43 | ### Install
44 |
45 | ```bash
46 | $ npm i codemirror-textmate
47 |
48 | # Install peer dependencies if you haven't already
49 | npm i onigasm codemirror
50 | ```
51 |
52 | See `./demo/index.ts` for instructions on how to light it up!
53 |
54 | ## API
55 |
56 | This package is written in TypeScript and is published with TS declaration files. Once you install the package
57 | see `node_modules/codemirror-textmate/dist/typings/index.d.ts` for available stuff along with expected data types.
58 |
59 | VSCode's intellisense will also pick up the declaration files and guide you nicely with auto-complete and errors.
60 |
61 | ## License
62 |
63 | MIT
64 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CodeMirror TextMate Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/demo/index.ts:
--------------------------------------------------------------------------------
1 | import * as CodeMirror from 'codemirror'
2 | import { loadWASM } from 'onigasm'
3 |
4 | import 'codemirror/lib/codemirror.css'
5 |
6 | import {
7 | activateLanguage,
8 | addGrammar,
9 |
10 | // [ optional | recommended ] Textmate themes in CodeMirror
11 | addTheme,
12 | ITextmateThemePlus,
13 | // [ optional ] Grammar injections
14 | linkInjections,
15 | } from 'codemirror-textmate'
16 |
17 | (async () => {
18 | await loadWASM(
19 | // webpack has been configured to resolve `.wasm` files to actual 'paths" as opposed to using the built-in wasm-loader
20 | // oniguruma is a low-level library and stock wasm-loader isn't equipped with advanced low-level API's to interact with libonig
21 | require('onigasm/lib/onigasm.wasm'))
22 |
23 | const grammars = {
24 | // loading `source.js` as a standalone grammar and as dependency of `text.html.basic`
25 | 'source.js': {
26 | /**
27 | * This the most resource efficient way to load grammars as of yet
28 | */
29 | loader: () => import('./tm/grammars/Javascript.tmLanguage.json'),
30 |
31 | /**
32 | * Language ID is only necessary for languages you want to use as CodeMirror mode (eg: cm.setOption('mode', 'javascript'))
33 | * To do that, we use `activatelanguage`, which will link one scope name to a language ID (also known as "mode")
34 | *
35 | * Grammar dependencies don't need to be "activated", just "adding/registering" them is enough (using `addGrammar`)
36 | */
37 | language: 'javascript',
38 |
39 | /**
40 | * Third parameter accepted by `activateLanguage` to specify language loading priority
41 | * Loading priority can be 'now' | 'asap' | 'defer' (default)
42 | *
43 | * - [HIGH] 'now' will cause the language (and it's grammars) to load/compile right away (most likely in the next event loop)
44 | * - [MED] 'asap' is like 'now' but will use `requestIdleCallback` if available (fallbacks to `setTimeout`, 10 seconds).
45 | * - [LOW] 'defer' will only do registeration and loading/compiling is deferred until needed (⚠ WILL CAUSE FOUC IN CODEMIRROR) (DEFAULT)
46 | */
47 | priority: 'now'
48 | },
49 |
50 | // loading `source.css` as a standalone grammar and as dependency of `text.html.basic`
51 | 'source.ts': {
52 | loader: () => import('./tm/grammars/TypeScript.tmLanguage.json'),
53 | language: 'typescript',
54 | priority: 'asap'
55 | },
56 |
57 | // loading `source.css` as a standalone grammar and as dependency of `text.html.basic`
58 | 'source.css': {
59 | loader: () => import('./tm/grammars/css.tmLanguage.json'),
60 | language: 'css',
61 | priority: 'now'
62 | },
63 |
64 | // Secondary dependency of `text.html.basic`
65 | 'source.smarty': {
66 | loader: () => import('./tm/grammars/smarty.tmLanguage.json'),
67 | // priority of dependenices like this one are regulated by dependent grammars
68 | },
69 | // Secondary dependency of `text.html.basic`
70 | // (can be also be used for tokenizing python source code, just add `language` property below)
71 | 'source.python': {
72 | loader: () => import('./tm/grammars/python.tmLanguage.json'),
73 | },
74 |
75 | // Some grammars have other grammars as dependencies. You must register those deps with `addGrammar` or it will throw an Error
76 | 'text.html.basic': {
77 | loader: () => import('./tm/grammars/html.tmLanguage.json'),
78 | language: 'html',
79 | priority: 'asap',
80 | }
81 |
82 | }
83 |
84 | // To avoid FOUC, await for high priority languages to get ready (loading/compiling takes time, and it's an async process for which CM won't wait)
85 | await Promise.all(Object.keys(grammars).map(async scopeName => {
86 | const { loader, language, priority } = grammars[scopeName]
87 |
88 | addGrammar(scopeName, loader)
89 |
90 | if (language) {
91 | const prom = activateLanguage(scopeName, language, priority)
92 |
93 | // We must "wait" for high priority languages to load/compile before we render editor to avoid FOUC (Flash of Unstyled Content)
94 | if (priority === 'now') {
95 | await prom
96 | }
97 |
98 | // 'asap' although "awaitable", is a medium priority, and doesn't need to be waited for
99 | // 'defer' doesn't support awaiting at all
100 | return
101 | }
102 | }))
103 |
104 | const editor = CodeMirror.fromTextArea(document.getElementById('cm-host') as HTMLTextAreaElement, {
105 | lineNumbers: true,
106 | // If you know in advance a language is going to be set on CodeMirror editor and it isn't preloaded by setting the third argument
107 | // to `activateLanguage` to 'now', the contents of the editor would start of and remain as unhighlighted text, until loading is complete
108 | mode: 'typescript'
109 | })
110 | editor.setValue((await import('./modeSamples/typescript')).default)
111 |
112 | // Everything should be working now!
113 |
114 | //////////////////////////////////////////////////////
115 |
116 | // ____ __ _ __
117 | // / __ \____ / /_(_)___ ____ ____ _/ /
118 | // / / / / __ \/ __/ / __ \/ __ \/ __ `/ /
119 | // / /_/ / /_/ / /_/ / /_/ / / / / /_/ / /
120 | // \____/ .___/\__/_/\____/_/ /_/\__,_/_/
121 | // /_/
122 |
123 | // Using Textmate theme in CodeMirror
124 | const themeX: ITextmateThemePlus = {
125 | ...(await import('./tm/themes/OneDark.tmTheme.json')),
126 | gutterSettings: {
127 | background: '#1d1f25',
128 | divider: '#1d1f25'
129 | }
130 | }
131 | addTheme(themeX)
132 | editor.setOption('theme', themeX.name)
133 |
134 | // Grammar injections, example code below will highlight css-in-js (styled-components, emotion)
135 | // injections are "injections", they are not standalone-grammars, therefore no `activateLanguage`
136 | addGrammar('source.css.styled', () => import('./tm/grammars/css.styled.tmLanguage.json') as any)
137 | addGrammar('styled', () => import('./tm/grammars/styled.tmLanguage.json') as any)
138 |
139 | const affectedLanguages = await linkInjections('styled', ['source.ts', 'source.tsx', 'source.js', 'source.jsx'])
140 |
141 | // You must re-trigger tokenization to apply the update above (if applicable)
142 | const activeMode = editor.getOption('mode')
143 | if (affectedLanguages.indexOf(activeMode) > -1) {
144 | // Resetting cm's mode re-triggers tokenization of entire document
145 | editor.setOption('mode', activeMode)
146 | }
147 | })()
148 |
--------------------------------------------------------------------------------
/demo/modeSamples/html.ts:
--------------------------------------------------------------------------------
1 | export default `\
2 |
3 |
4 |
5 |
6 |
7 | CodeMirror TextMate Demo
8 |
9 |
10 |
11 |
12 |
13 | `
--------------------------------------------------------------------------------
/demo/modeSamples/javascript.ts:
--------------------------------------------------------------------------------
1 | export default `\
2 | function test() {
3 | const string = 'nice'
4 | const number = 1243
5 | const boolean = false
6 | const templateLiteral = \`noice${12} mate\`
7 | const func = (a, b) => a + b
8 | }
9 |
10 | class AwesomeMap extends Map {
11 | isKeyOfType(key, type) {
12 | return typeof this.get(key) === type
13 | }
14 | }
15 | `
--------------------------------------------------------------------------------
/demo/modeSamples/typescript.ts:
--------------------------------------------------------------------------------
1 | export default `\
2 | interface IEatable {
3 | chew(speed?: number): Promise
4 | swallow(ensureChewed?: boolean): Promise
5 | }
6 |
7 | function test() {
8 | const string: string = 'nice'
9 | const number: number = 1243
10 | const boolean: boolean = false
11 | const templateLiteral: string = \`noice ${'${12}'} mate\`
12 | const func = (a: number, b: number) => a + b
13 | }
14 |
15 | class AwesomeMap extends Map {
16 | public isKeyOfType(key: string, type: string) {
17 | return typeof this.get(key) === type
18 | }
19 | }
20 | `
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "start": "npm run __build-cm-tm && webpack-dev-server .",
4 | "__build-cm-tm": "tsc --build ../tsconfig.json"
5 | },
6 | "private": true,
7 | "license": "MIT",
8 | "dependencies": {
9 | "codemirror": "^5.43.0",
10 | "codemirror-textmate": "file:..",
11 | "onigasm": "^2.2.1"
12 | },
13 | "devDependencies": {
14 | "@types/node": "^10.12.21",
15 | "css-loader": "^2.1.0",
16 | "file-loader": "^3.0.1",
17 | "html-webpack-plugin": "^3.2.0",
18 | "style-loader": "^0.23.1",
19 | "ts-loader": "^5.3.3",
20 | "typescript": "^3.3.1",
21 | "webpack": "^4.29.0",
22 | "webpack-cli": "^3.2.1",
23 | "webpack-dev-server": "^3.1.14"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/demo/tm/grammars/css.styled.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "name": "CSS (Styled Components)",
4 | "patterns": [
5 | {
6 | "include": "#general"
7 | },
8 | {
9 | "include": "#rules"
10 | },
11 | {
12 | "include": "#property_list"
13 | },
14 | {
15 | "include": "#at_rule_media"
16 | },
17 | {
18 | "include": "#at_rule_import"
19 | },
20 | {
21 | "include": "#at_rule_fontface"
22 | },
23 | {
24 | "include": "#at_rule_page"
25 | },
26 | {
27 | "include": "#at_rule_keyframes"
28 | },
29 | {
30 | "include": "#at_rule_supports"
31 | },
32 | {
33 | "match": ";",
34 | "name": "punctuation.terminator.rule.css"
35 | },
36 | {
37 | "include": "#properties"
38 | }
39 | ],
40 | "repository": {
41 | "at_rule_fontface": {
42 | "patterns": [
43 | {
44 | "begin": "^\\s*((@)font-face\\b)",
45 | "beginCaptures": {
46 | "1": {
47 | "name": "keyword.control.at-rule.fontface.scss"
48 | },
49 | "2": {
50 | "name": "punctuation.definition.keyword.scss"
51 | }
52 | },
53 | "end": "\\s*(?={)",
54 | "name": "meta.at-rule.fontface.scss",
55 | "patterns": [
56 | {
57 | "include": "#function_attributes"
58 | }
59 | ]
60 | }
61 | ]
62 | },
63 | "at_rule_import": {
64 | "begin": "\\s*((@)import\\b)\\s*",
65 | "captures": {
66 | "1": {
67 | "name": "keyword.control.at-rule.import.scss"
68 | },
69 | "2": {
70 | "name": "punctuation.definition.keyword.scss"
71 | }
72 | },
73 | "end": "\\s*((?=;)|(?=}))",
74 | "name": "meta.at-rule.import.scss",
75 | "patterns": [
76 | {
77 | "include": "#interpolation"
78 | },
79 | {
80 | "include": "#string_single"
81 | },
82 | {
83 | "include": "#string_double"
84 | },
85 | {
86 | "include": "#functions"
87 | }
88 | ]
89 | },
90 | "at_rule_keyframes": {
91 | "begin": "(?<=^|\\s)(@)(?:-(?:webkit|moz)-)?keyframes\\b",
92 | "beginCaptures": {
93 | "0": {
94 | "name": "keyword.control.at-rule.keyframes.scss"
95 | },
96 | "1": {
97 | "name": "punctuation.definition.keyword.scss"
98 | }
99 | },
100 | "end": "(?<=})",
101 | "name": "meta.at-rule.keyframes.scss",
102 | "patterns": [
103 | {
104 | "match": "(?<=@keyframes)\\s+((?:[_A-Za-z][-\\w]|-[_A-Za-z])[-\\w]*)",
105 | "captures": {
106 | "1": {
107 | "name": "entity.name.function.scss"
108 | }
109 | }
110 | },
111 | {
112 | "begin": "(?<=@keyframes)\\s+(\")",
113 | "beginCaptures": {
114 | "1": {
115 | "name": "punctuation.definition.string.begin.scss"
116 | }
117 | },
118 | "end": "\"",
119 | "endCaptures": {
120 | "0": {
121 | "name": "punctuation.definition.string.end.scss"
122 | }
123 | },
124 | "name": "string.quoted.double.scss",
125 | "contentName": "entity.name.function.scss",
126 | "patterns": [
127 | {
128 | "match": "\\\\(\\h{1,6}|.)",
129 | "name": "constant.character.escape.scss"
130 | },
131 | {
132 | "include": "#interpolation"
133 | }
134 | ]
135 | },
136 | {
137 | "begin": "(?<=@keyframes)\\s+(')",
138 | "beginCaptures": {
139 | "1": {
140 | "name": "punctuation.definition.string.begin.scss"
141 | }
142 | },
143 | "end": "'",
144 | "endCaptures": {
145 | "0": {
146 | "name": "punctuation.definition.string.end.scss"
147 | }
148 | },
149 | "name": "string.quoted.single.scss",
150 | "contentName": "entity.name.function.scss",
151 | "patterns": [
152 | {
153 | "match": "\\\\(\\h{1,6}|.)",
154 | "name": "constant.character.escape.scss"
155 | },
156 | {
157 | "include": "#interpolation"
158 | }
159 | ]
160 | },
161 | {
162 | "begin": "{",
163 | "beginCaptures": {
164 | "0": {
165 | "name": "punctuation.section.keyframes.begin.scss"
166 | }
167 | },
168 | "end": "}",
169 | "endCaptures": {
170 | "0": {
171 | "name": "punctuation.section.keyframes.end.scss"
172 | }
173 | },
174 | "patterns": [
175 | {
176 | "match": "\\b(?:(?:100|[1-9]\\d|\\d)%|from|to)(?=\\s*{)",
177 | "name": "entity.other.attribute-name.scss"
178 | },
179 | {
180 | "include": "#interpolation"
181 | },
182 | {
183 | "include": "#property_list"
184 | },
185 | {
186 | "include": "#rules"
187 | }
188 | ]
189 | }
190 | ]
191 | },
192 | "at_rule_media": {
193 | "patterns": [
194 | {
195 | "begin": "^\\s*((@)media)\\b",
196 | "beginCaptures": {
197 | "1": {
198 | "name": "keyword.control.at-rule.media.scss"
199 | },
200 | "2": {
201 | "name": "punctuation.definition.keyword.scss"
202 | }
203 | },
204 | "end": "\\s*(?={)",
205 | "name": "meta.at-rule.media.scss",
206 | "patterns": [
207 | {
208 | "include": "#comment_block"
209 | },
210 | {
211 | "match": "\\b(only)\\b",
212 | "name": "keyword.control.operator.css.scss"
213 | },
214 | {
215 | "begin": "\\(",
216 | "beginCaptures": {
217 | "0": {
218 | "name": "punctuation.definition.media-query.begin.bracket.round.scss"
219 | }
220 | },
221 | "end": "\\)",
222 | "endCaptures": {
223 | "0": {
224 | "name": "punctuation.definition.media-query.end.bracket.round.scss"
225 | }
226 | },
227 | "name": "meta.property-list.media-query.scss",
228 | "patterns": [
229 | {
230 | "begin": "(?=|<|>",
676 | "name": "keyword.operator.comparison.scss"
677 | },
678 | "logical_operators": {
679 | "match": "\\b(not|or|and)\\b",
680 | "name": "keyword.operator.logical.scss"
681 | },
682 | "operators": {
683 | "match": "[-+*/](?!\\s*[-+*/])",
684 | "name": "keyword.operator.css"
685 | },
686 | "properties": {
687 | "patterns": [
688 | {
689 | "begin": "(?+~|] # - Another selector\n | /\\* # - A block comment\n)",
915 | "name": "entity.other.attribute-name.class.css",
916 | "captures": {
917 | "1": {
918 | "name": "punctuation.definition.entity.css"
919 | },
920 | "2": {
921 | "patterns": [
922 | {
923 | "include": "#interpolation"
924 | },
925 | {
926 | "match": "\\\\([0-9a-fA-F]{1,6}|.)",
927 | "name": "constant.character.escape.scss"
928 | },
929 | {
930 | "match": "\\$|}",
931 | "name": "invalid.illegal.scss"
932 | }
933 | ]
934 | }
935 | }
936 | },
937 | "selector_custom": {
938 | "match": "\\b([a-zA-Z0-9]+(-[a-zA-Z0-9]+)+)(?=\\.|\\s++[^:]|\\s*[,\\[{]|:(link|visited|hover|active|focus|target|lang|disabled|enabled|checked|indeterminate|root|nth-(child|last-child|of-type|last-of-type)|first-child|last-child|first-of-type|last-of-type|only-child|only-of-type|empty|not|valid|invalid)(\\([0-9A-Za-z]*\\))?)",
939 | "name": "entity.name.tag.custom.scss"
940 | },
941 | "selector_id": {
942 | "match": "(?x)\n(\\#) # Valid id-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n|\\$\\{[^{}]*\\} # Interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)",
943 | "name": "entity.other.attribute-name.id.css",
944 | "captures": {
945 | "1": {
946 | "name": "punctuation.definition.entity.css"
947 | },
948 | "2": {
949 | "patterns": [
950 | {
951 | "include": "#interpolation"
952 | },
953 | {
954 | "match": "\\\\([0-9a-fA-F]{1,6}|.)",
955 | "name": "constant.character.escape.scss"
956 | },
957 | {
958 | "match": "\\$|}",
959 | "name": "invalid.illegal.identifier.scss"
960 | }
961 | ]
962 | }
963 | }
964 | },
965 | "parent_selector_suffix": {
966 | "match": "(?x)\n(?<=&)\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n|\\$\\{[^{}]*\\} # Interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)",
967 | "name": "entity.other.attribute-name.parent-selector-suffix.css",
968 | "captures": {
969 | "1": {
970 | "name": "punctuation.definition.entity.css"
971 | },
972 | "2": {
973 | "patterns": [
974 | {
975 | "include": "#interpolation"
976 | },
977 | {
978 | "match": "\\\\([0-9a-fA-F]{1,6}|.)",
979 | "name": "constant.character.escape.scss"
980 | },
981 | {
982 | "match": "\\$|}",
983 | "name": "invalid.illegal.identifier.scss"
984 | }
985 | ]
986 | }
987 | }
988 | },
989 | "selector_pseudo_class": {
990 | "patterns": [
991 | {
992 | "begin": "((:)\\bnth-(?:child|last-child|of-type|last-of-type))(\\()",
993 | "beginCaptures": {
994 | "1": {
995 | "name": "entity.other.attribute-name.pseudo-class.css"
996 | },
997 | "2": {
998 | "name": "punctuation.definition.entity.css"
999 | },
1000 | "3": {
1001 | "name": "punctuation.definition.pseudo-class.begin.bracket.round.css"
1002 | }
1003 | },
1004 | "end": "\\)",
1005 | "endCaptures": {
1006 | "0": {
1007 | "name": "punctuation.definition.pseudo-class.end.bracket.round.css"
1008 | }
1009 | },
1010 | "patterns": [
1011 | {
1012 | "include": "#interpolation"
1013 | },
1014 | {
1015 | "match": "\\d+",
1016 | "name": "constant.numeric.css"
1017 | },
1018 | {
1019 | "match": "(?<=\\d)n\\b|\\b(n|even|odd)\\b",
1020 | "name": "constant.other.scss"
1021 | },
1022 | {
1023 | "match": "\\w+",
1024 | "name": "invalid.illegal.scss"
1025 | }
1026 | ]
1027 | },
1028 | {
1029 | "include": "source.css#pseudo-classes"
1030 | },
1031 | {
1032 | "include": "source.css#pseudo-elements"
1033 | },
1034 | {
1035 | "include": "source.css#functional-pseudo-classes"
1036 | }
1037 | ]
1038 | },
1039 | "selectors": {
1040 | "patterns": [
1041 | {
1042 | "include": "#interpolation"
1043 | },
1044 | {
1045 | "include": "source.css#tag-names"
1046 | },
1047 | {
1048 | "include": "#selector_custom"
1049 | },
1050 | {
1051 | "include": "#selector_class"
1052 | },
1053 | {
1054 | "include": "#selector_id"
1055 | },
1056 | {
1057 | "include": "#selector_pseudo_class"
1058 | },
1059 | {
1060 | "include": "#tag_wildcard"
1061 | },
1062 | {
1063 | "include": "#tag_parent_reference"
1064 | },
1065 | {
1066 | "include": "source.css#pseudo-elements"
1067 | },
1068 | {
1069 | "include": "#selector_attribute"
1070 | },
1071 | {
1072 | "include": "#parent_selector_suffix"
1073 | }
1074 | ]
1075 | },
1076 | "string_double": {
1077 | "begin": "\"",
1078 | "beginCaptures": {
1079 | "0": {
1080 | "name": "punctuation.definition.string.begin.scss"
1081 | }
1082 | },
1083 | "end": "\"",
1084 | "endCaptures": {
1085 | "0": {
1086 | "name": "punctuation.definition.string.end.scss"
1087 | }
1088 | },
1089 | "name": "string.quoted.double.scss",
1090 | "patterns": [
1091 | {
1092 | "match": "\\\\(\\h{1,6}|.)",
1093 | "name": "constant.character.escape.scss"
1094 | },
1095 | {
1096 | "include": "#interpolation"
1097 | }
1098 | ]
1099 | },
1100 | "string_single": {
1101 | "begin": "'",
1102 | "beginCaptures": {
1103 | "0": {
1104 | "name": "punctuation.definition.string.begin.scss"
1105 | }
1106 | },
1107 | "end": "'",
1108 | "endCaptures": {
1109 | "0": {
1110 | "name": "punctuation.definition.string.end.scss"
1111 | }
1112 | },
1113 | "name": "string.quoted.single.scss",
1114 | "patterns": [
1115 | {
1116 | "match": "\\\\(\\h{1,6}|.)",
1117 | "name": "constant.character.escape.scss"
1118 | },
1119 | {
1120 | "include": "#interpolation"
1121 | }
1122 | ]
1123 | },
1124 | "tag_parent_reference": {
1125 | "match": "&",
1126 | "name": "entity.name.tag.reference.scss"
1127 | },
1128 | "tag_wildcard": {
1129 | "match": "\\*",
1130 | "name": "entity.name.tag.wildcard.scss"
1131 | }
1132 | },
1133 |
1134 | "scopeName": "source.css.styled"
1135 | }
--------------------------------------------------------------------------------
/demo/tm/grammars/css.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/atom/language-css/blob/master/grammars/css.cson",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/atom/language-css/commit/2bc1e294e2440ad91197263cd9f95dc4b00bab2f",
8 | "name": "CSS",
9 | "scopeName": "source.css",
10 | "patterns": [
11 | {
12 | "include": "#comment-block"
13 | },
14 | {
15 | "include": "#escapes"
16 | },
17 | {
18 | "include": "#combinators"
19 | },
20 | {
21 | "include": "#selector"
22 | },
23 | {
24 | "include": "#at-rules"
25 | },
26 | {
27 | "include": "#rule-list"
28 | }
29 | ],
30 | "repository": {
31 | "at-rules": {
32 | "patterns": [
33 | {
34 | "begin": "\\A(?:\\xEF\\xBB\\xBF)?(?i:(?=\\s*@charset\\b))",
35 | "end": ";|(?=$)",
36 | "endCaptures": {
37 | "0": {
38 | "name": "punctuation.terminator.rule.css"
39 | }
40 | },
41 | "name": "meta.at-rule.charset.css",
42 | "patterns": [
43 | {
44 | "captures": {
45 | "1": {
46 | "name": "invalid.illegal.not-lowercase.charset.css"
47 | },
48 | "2": {
49 | "name": "invalid.illegal.leading-whitespace.charset.css"
50 | },
51 | "3": {
52 | "name": "invalid.illegal.no-whitespace.charset.css"
53 | },
54 | "4": {
55 | "name": "invalid.illegal.whitespace.charset.css"
56 | },
57 | "5": {
58 | "name": "invalid.illegal.not-double-quoted.charset.css"
59 | },
60 | "6": {
61 | "name": "invalid.illegal.unclosed-string.charset.css"
62 | },
63 | "7": {
64 | "name": "invalid.illegal.unexpected-characters.charset.css"
65 | }
66 | },
67 | "match": "(?x) # Possible errors:\n\\G\n((?!@charset)@\\w+) # Not lowercase (@charset is case-sensitive)\n|\n\\G(\\s+) # Preceding whitespace\n|\n(@charset\\S[^;]*) # No whitespace after @charset\n|\n(?<=@charset) # Before quoted charset name\n(\\x20{2,}|\\t+) # More than one space used, or a tab\n|\n(?<=@charset\\x20) # Beginning of charset name\n([^\";]+) # Not double-quoted\n|\n(\"[^\"]+$) # Unclosed quote\n|\n(?<=\") # After charset name\n([^;]+) # Unexpected junk instead of semicolon"
68 | },
69 | {
70 | "captures": {
71 | "1": {
72 | "name": "keyword.control.at-rule.charset.css"
73 | },
74 | "2": {
75 | "name": "punctuation.definition.keyword.css"
76 | }
77 | },
78 | "match": "((@)charset)(?=\\s)"
79 | },
80 | {
81 | "begin": "\"",
82 | "beginCaptures": {
83 | "0": {
84 | "name": "punctuation.definition.string.begin.css"
85 | }
86 | },
87 | "end": "\"|$",
88 | "endCaptures": {
89 | "0": {
90 | "name": "punctuation.definition.string.end.css"
91 | }
92 | },
93 | "name": "string.quoted.double.css",
94 | "patterns": [
95 | {
96 | "begin": "(?:\\G|^)(?=(?:[^\"])+$)",
97 | "end": "$",
98 | "name": "invalid.illegal.unclosed.string.css"
99 | }
100 | ]
101 | }
102 | ]
103 | },
104 | {
105 | "begin": "(?i)((@)import)(?:\\s+|$|(?=['\"]|/\\*))",
106 | "beginCaptures": {
107 | "1": {
108 | "name": "keyword.control.at-rule.import.css"
109 | },
110 | "2": {
111 | "name": "punctuation.definition.keyword.css"
112 | }
113 | },
114 | "end": ";",
115 | "endCaptures": {
116 | "0": {
117 | "name": "punctuation.terminator.rule.css"
118 | }
119 | },
120 | "name": "meta.at-rule.import.css",
121 | "patterns": [
122 | {
123 | "begin": "\\G\\s*(?=/\\*)",
124 | "end": "(?<=\\*/)\\s*",
125 | "patterns": [
126 | {
127 | "include": "#comment-block"
128 | }
129 | ]
130 | },
131 | {
132 | "include": "#string"
133 | },
134 | {
135 | "include": "#url"
136 | },
137 | {
138 | "include": "#media-query-list"
139 | }
140 | ]
141 | },
142 | {
143 | "begin": "(?i)((@)font-face)(?=\\s*|{|/\\*|$)",
144 | "beginCaptures": {
145 | "1": {
146 | "name": "keyword.control.at-rule.font-face.css"
147 | },
148 | "2": {
149 | "name": "punctuation.definition.keyword.css"
150 | }
151 | },
152 | "end": "(?!\\G)",
153 | "name": "meta.at-rule.font-face.css",
154 | "patterns": [
155 | {
156 | "include": "#comment-block"
157 | },
158 | {
159 | "include": "#escapes"
160 | },
161 | {
162 | "include": "#rule-list"
163 | }
164 | ]
165 | },
166 | {
167 | "begin": "(?i)(@)page(?=[\\s:{]|/\\*|$)",
168 | "captures": {
169 | "0": {
170 | "name": "keyword.control.at-rule.page.css"
171 | },
172 | "1": {
173 | "name": "punctuation.definition.keyword.css"
174 | }
175 | },
176 | "end": "(?=\\s*($|[:{;]))",
177 | "name": "meta.at-rule.page.css",
178 | "patterns": [
179 | {
180 | "include": "#rule-list"
181 | }
182 | ]
183 | },
184 | {
185 | "begin": "(?i)(?=@media(\\s|\\(|/\\*|$))",
186 | "end": "(?<=})(?!\\G)",
187 | "patterns": [
188 | {
189 | "begin": "(?i)\\G(@)media",
190 | "beginCaptures": {
191 | "0": {
192 | "name": "keyword.control.at-rule.media.css"
193 | },
194 | "1": {
195 | "name": "punctuation.definition.keyword.css"
196 | }
197 | },
198 | "end": "(?=\\s*[{;])",
199 | "name": "meta.at-rule.media.header.css",
200 | "patterns": [
201 | {
202 | "include": "#media-query-list"
203 | }
204 | ]
205 | },
206 | {
207 | "begin": "{",
208 | "beginCaptures": {
209 | "0": {
210 | "name": "punctuation.section.media.begin.bracket.curly.css"
211 | }
212 | },
213 | "end": "}",
214 | "endCaptures": {
215 | "0": {
216 | "name": "punctuation.section.media.end.bracket.curly.css"
217 | }
218 | },
219 | "name": "meta.at-rule.media.body.css",
220 | "patterns": [
221 | {
222 | "include": "$self"
223 | }
224 | ]
225 | }
226 | ]
227 | },
228 | {
229 | "begin": "(?i)(?=@counter-style([\\s'\"{;]|/\\*|$))",
230 | "end": "(?<=})(?!\\G)",
231 | "patterns": [
232 | {
233 | "begin": "(?i)\\G(@)counter-style",
234 | "beginCaptures": {
235 | "0": {
236 | "name": "keyword.control.at-rule.counter-style.css"
237 | },
238 | "1": {
239 | "name": "punctuation.definition.keyword.css"
240 | }
241 | },
242 | "end": "(?=\\s*{)",
243 | "name": "meta.at-rule.counter-style.header.css",
244 | "patterns": [
245 | {
246 | "include": "#comment-block"
247 | },
248 | {
249 | "include": "#escapes"
250 | },
251 | {
252 | "captures": {
253 | "0": {
254 | "patterns": [
255 | {
256 | "include": "#escapes"
257 | }
258 | ]
259 | }
260 | },
261 | "match": "(?x)\n(?:[-a-zA-Z_] | [^\\x00-\\x7F]) # First letter\n(?:[-a-zA-Z0-9_] | [^\\x00-\\x7F] # Remainder of identifier\n |\\\\(?:[0-9a-fA-F]{1,6}|.)\n)*",
262 | "name": "variable.parameter.style-name.css"
263 | }
264 | ]
265 | },
266 | {
267 | "begin": "{",
268 | "beginCaptures": {
269 | "0": {
270 | "name": "punctuation.section.property-list.begin.bracket.curly.css"
271 | }
272 | },
273 | "end": "}",
274 | "endCaptures": {
275 | "0": {
276 | "name": "punctuation.section.property-list.end.bracket.curly.css"
277 | }
278 | },
279 | "name": "meta.at-rule.counter-style.body.css",
280 | "patterns": [
281 | {
282 | "include": "#comment-block"
283 | },
284 | {
285 | "include": "#escapes"
286 | },
287 | {
288 | "include": "#rule-list-innards"
289 | }
290 | ]
291 | }
292 | ]
293 | },
294 | {
295 | "begin": "(?i)(?=@document([\\s'\"{;]|/\\*|$))",
296 | "end": "(?<=})(?!\\G)",
297 | "patterns": [
298 | {
299 | "begin": "(?i)\\G(@)document",
300 | "beginCaptures": {
301 | "0": {
302 | "name": "keyword.control.at-rule.document.css"
303 | },
304 | "1": {
305 | "name": "punctuation.definition.keyword.css"
306 | }
307 | },
308 | "end": "(?=\\s*[{;])",
309 | "name": "meta.at-rule.document.header.css",
310 | "patterns": [
311 | {
312 | "begin": "(?i)(?>>",
634 | "name": "invalid.deprecated.combinator.css"
635 | },
636 | {
637 | "match": ">>|>|\\+|~",
638 | "name": "keyword.operator.combinator.css"
639 | }
640 | ]
641 | },
642 | "commas": {
643 | "match": ",",
644 | "name": "punctuation.separator.list.comma.css"
645 | },
646 | "comment-block": {
647 | "begin": "/\\*",
648 | "beginCaptures": {
649 | "0": {
650 | "name": "punctuation.definition.comment.begin.css"
651 | }
652 | },
653 | "end": "\\*/",
654 | "endCaptures": {
655 | "0": {
656 | "name": "punctuation.definition.comment.end.css"
657 | }
658 | },
659 | "name": "comment.block.css"
660 | },
661 | "escapes": {
662 | "patterns": [
663 | {
664 | "match": "\\\\[0-9a-fA-F]{1,6}",
665 | "name": "constant.character.escape.codepoint.css"
666 | },
667 | {
668 | "begin": "\\\\$\\s*",
669 | "end": "^(?<:=]|\\)|/\\*) # Terminates cleanly"
1207 | },
1208 | "media-feature-keywords": {
1209 | "match": "(?xi)\n(?<=^|\\s|:|\\*/)\n(?: portrait # Orientation\n | landscape\n | progressive # Scan types\n | interlace\n | fullscreen # Display modes\n | standalone\n | minimal-ui\n | browser\n)\n(?=\\s|\\)|$)",
1210 | "name": "support.constant.property-value.css"
1211 | },
1212 | "media-query": {
1213 | "begin": "\\G",
1214 | "end": "(?=\\s*[{;])",
1215 | "patterns": [
1216 | {
1217 | "include": "#comment-block"
1218 | },
1219 | {
1220 | "include": "#escapes"
1221 | },
1222 | {
1223 | "include": "#media-types"
1224 | },
1225 | {
1226 | "match": "(?i)(?<=\\s|^|,|\\*/)(only|not)(?=\\s|{|/\\*|$)",
1227 | "name": "keyword.operator.logical.$1.media.css"
1228 | },
1229 | {
1230 | "match": "(?i)(?<=\\s|^|\\*/|\\))and(?=\\s|/\\*|$)",
1231 | "name": "keyword.operator.logical.and.media.css"
1232 | },
1233 | {
1234 | "match": ",(?:(?:\\s*,)+|(?=\\s*[;){]))",
1235 | "name": "invalid.illegal.comma.css"
1236 | },
1237 | {
1238 | "include": "#commas"
1239 | },
1240 | {
1241 | "begin": "\\(",
1242 | "beginCaptures": {
1243 | "0": {
1244 | "name": "punctuation.definition.parameters.begin.bracket.round.css"
1245 | }
1246 | },
1247 | "end": "\\)",
1248 | "endCaptures": {
1249 | "0": {
1250 | "name": "punctuation.definition.parameters.end.bracket.round.css"
1251 | }
1252 | },
1253 | "patterns": [
1254 | {
1255 | "include": "#media-features"
1256 | },
1257 | {
1258 | "include": "#media-feature-keywords"
1259 | },
1260 | {
1261 | "match": ":",
1262 | "name": "punctuation.separator.key-value.css"
1263 | },
1264 | {
1265 | "match": ">=|<=|=|<|>",
1266 | "name": "keyword.operator.comparison.css"
1267 | },
1268 | {
1269 | "captures": {
1270 | "1": {
1271 | "name": "constant.numeric.css"
1272 | },
1273 | "2": {
1274 | "name": "keyword.operator.arithmetic.css"
1275 | },
1276 | "3": {
1277 | "name": "constant.numeric.css"
1278 | }
1279 | },
1280 | "match": "(\\d+)\\s*(/)\\s*(\\d+)",
1281 | "name": "meta.ratio.css"
1282 | },
1283 | {
1284 | "include": "#numeric-values"
1285 | },
1286 | {
1287 | "include": "#comment-block"
1288 | }
1289 | ]
1290 | }
1291 | ]
1292 | },
1293 | "media-query-list": {
1294 | "begin": "(?=\\s*[^{;])",
1295 | "end": "(?=\\s*[{;])",
1296 | "patterns": [
1297 | {
1298 | "include": "#media-query"
1299 | }
1300 | ]
1301 | },
1302 | "media-types": {
1303 | "captures": {
1304 | "1": {
1305 | "name": "support.constant.media.css"
1306 | },
1307 | "2": {
1308 | "name": "invalid.deprecated.constant.media.css"
1309 | }
1310 | },
1311 | "match": "(?xi)\n(?<=^|\\s|,|\\*/)\n(?:\n # Valid media types\n (all|print|screen|speech)\n |\n # Deprecated in Media Queries 4: http://dev.w3.org/csswg/mediaqueries/#media-types\n (aural|braille|embossed|handheld|projection|tty|tv)\n)\n(?=$|[{,\\s;]|/\\*)"
1312 | },
1313 | "numeric-values": {
1314 | "patterns": [
1315 | {
1316 | "captures": {
1317 | "1": {
1318 | "name": "punctuation.definition.constant.css"
1319 | }
1320 | },
1321 | "match": "(#)(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\\b",
1322 | "name": "constant.other.color.rgb-value.hex.css"
1323 | },
1324 | {
1325 | "captures": {
1326 | "1": {
1327 | "name": "keyword.other.unit.percentage.css"
1328 | },
1329 | "2": {
1330 | "name": "keyword.other.unit.${2:/downcase}.css"
1331 | }
1332 | },
1333 | "match": "(?xi) (?+~|] # - Followed by another selector\n | /\\* # - Followed by a block comment\n )\n |\n # Name contains unescaped ASCII symbol\n (?: # Check for acceptable preceding characters\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # - Valid selector character\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence\n )*\n (?: # Invalid punctuation\n [!\"'%&(*;@^`|\\]}] # - NOTE: We exempt `)` from the list of checked\n | # symbols to avoid matching `:not(.invalid)`\n / (?!\\*) # - Avoid invalidating the start of a comment\n )+\n )\n # Mark remainder of selector invalid\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # - Otherwise valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence\n )*\n)",
1559 | "name": "invalid.illegal.bad-identifier.css"
1560 | },
1561 | {
1562 | "captures": {
1563 | "1": {
1564 | "name": "punctuation.definition.entity.css"
1565 | },
1566 | "2": {
1567 | "patterns": [
1568 | {
1569 | "include": "#escapes"
1570 | }
1571 | ]
1572 | }
1573 | },
1574 | "match": "(?x)\n(\\.) # Valid class-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)",
1575 | "name": "entity.other.attribute-name.class.css"
1576 | },
1577 | {
1578 | "captures": {
1579 | "1": {
1580 | "name": "punctuation.definition.entity.css"
1581 | },
1582 | "2": {
1583 | "patterns": [
1584 | {
1585 | "include": "#escapes"
1586 | }
1587 | ]
1588 | }
1589 | },
1590 | "match": "(?x)\n(\\#)\n(\n -?\n (?![0-9])\n (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n)\n(?=$|[\\s,.\\#)\\[:{>+~|]|/\\*)",
1591 | "name": "entity.other.attribute-name.id.css"
1592 | },
1593 | {
1594 | "begin": "\\[",
1595 | "beginCaptures": {
1596 | "0": {
1597 | "name": "punctuation.definition.entity.begin.bracket.square.css"
1598 | }
1599 | },
1600 | "end": "\\]",
1601 | "endCaptures": {
1602 | "0": {
1603 | "name": "punctuation.definition.entity.end.bracket.square.css"
1604 | }
1605 | },
1606 | "name": "meta.attribute-selector.css",
1607 | "patterns": [
1608 | {
1609 | "include": "#comment-block"
1610 | },
1611 | {
1612 | "include": "#string"
1613 | },
1614 | {
1615 | "captures": {
1616 | "1": {
1617 | "name": "storage.modifier.ignore-case.css"
1618 | }
1619 | },
1620 | "match": "(?<=[\"'\\s]|^|\\*/)\\s*([iI])\\s*(?=[\\s\\]]|/\\*|$)"
1621 | },
1622 | {
1623 | "captures": {
1624 | "1": {
1625 | "name": "string.unquoted.attribute-value.css",
1626 | "patterns": [
1627 | {
1628 | "include": "#escapes"
1629 | }
1630 | ]
1631 | }
1632 | },
1633 | "match": "(?x)(?<==)\\s*((?!/\\*)(?:[^\\\\\"'\\s\\]]|\\\\.)+)"
1634 | },
1635 | {
1636 | "include": "#escapes"
1637 | },
1638 | {
1639 | "match": "[~|^$*]?=",
1640 | "name": "keyword.operator.pattern.css"
1641 | },
1642 | {
1643 | "match": "\\|",
1644 | "name": "punctuation.separator.css"
1645 | },
1646 | {
1647 | "captures": {
1648 | "1": {
1649 | "name": "entity.other.namespace-prefix.css",
1650 | "patterns": [
1651 | {
1652 | "include": "#escapes"
1653 | }
1654 | ]
1655 | }
1656 | },
1657 | "match": "(?x)\n# Qualified namespace prefix\n( -?(?!\\d)(?:[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n| \\*\n)\n# Lookahead to ensure there's a valid identifier ahead\n(?=\n \\| (?!\\s|=|$|\\])\n (?: -?(?!\\d)\n | [\\\\\\w-]\n | [^\\x00-\\x7F]\n )\n)"
1658 | },
1659 | {
1660 | "captures": {
1661 | "1": {
1662 | "name": "entity.other.attribute-name.css",
1663 | "patterns": [
1664 | {
1665 | "include": "#escapes"
1666 | }
1667 | ]
1668 | }
1669 | },
1670 | "match": "(?x)\n(-?(?!\\d)(?>[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+)\n\\s*\n(?=[~|^\\]$*=]|/\\*)"
1671 | }
1672 | ]
1673 | },
1674 | {
1675 | "include": "#pseudo-classes"
1676 | },
1677 | {
1678 | "include": "#pseudo-elements"
1679 | },
1680 | {
1681 | "include": "#functional-pseudo-classes"
1682 | },
1683 | {
1684 | "match": "(?x) (?\\s,.\\#|){:\\[]|/\\*|$)",
1755 | "name": "entity.name.tag.css"
1756 | },
1757 | "unicode-range": {
1758 | "captures": {
1759 | "0": {
1760 | "name": "constant.other.unicode-range.css"
1761 | },
1762 | "1": {
1763 | "name": "punctuation.separator.dash.unicode-range.css"
1764 | }
1765 | },
1766 | "match": "(?]*>\\2>)",
24 | "beginCaptures": {
25 | "1": {
26 | "name": "punctuation.definition.tag.html"
27 | },
28 | "2": {
29 | "name": "entity.name.tag.html"
30 | }
31 | },
32 | "end": "(>(<)/)(\\2)(>)",
33 | "endCaptures": {
34 | "1": {
35 | "name": "punctuation.definition.tag.html"
36 | },
37 | "2": {
38 | "name": "meta.scope.between-tag-pair.html"
39 | },
40 | "3": {
41 | "name": "entity.name.tag.html"
42 | },
43 | "4": {
44 | "name": "punctuation.definition.tag.html"
45 | }
46 | },
47 | "name": "meta.tag.any.html",
48 | "patterns": [
49 | {
50 | "include": "#tag-stuff"
51 | }
52 | ]
53 | },
54 | {
55 | "begin": "(<\\?)(xml)",
56 | "captures": {
57 | "1": {
58 | "name": "punctuation.definition.tag.html"
59 | },
60 | "2": {
61 | "name": "entity.name.tag.xml.html"
62 | }
63 | },
64 | "end": "(\\?>)",
65 | "name": "meta.tag.preprocessor.xml.html",
66 | "patterns": [
67 | {
68 | "include": "#tag-generic-attribute"
69 | },
70 | {
71 | "include": "#string-double-quoted"
72 | },
73 | {
74 | "include": "#string-single-quoted"
75 | }
76 | ]
77 | },
78 | {
79 | "begin": "