Skip to content

Commit 7dd52e5

Browse files
Merge pull request #852 from savetheclocktower/add-php-grammar
Tree-sitter fixes for December (including a PHP grammar!)
2 parents 580157d + 0111e13 commit 7dd52e5

File tree

54 files changed

+2640
-1090
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2640
-1090
lines changed

packages/language-c/grammars/tree-sitter-cpp/highlights.scm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@
138138
(function_declarator
139139
(field_identifier) @entity.name.function.method.cpp)
140140

141+
(field_initializer
142+
(field_identifier) @entity.name.function.cpp)
143+
141144
(call_expression
142145
(identifier) @support.function.c99.cpp
143146
; Regex copied from the TM grammar.

packages/language-c/lib/main.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
1-
exports.activate = function() {
1+
exports.activate = function () {
22
// Highlight macro bodies as C/C++
33
for (const language of ['c', 'cpp']) {
44
for (const nodeType of ['preproc_def', 'preproc_function_def']) {
55
atom.grammars.addInjectionPoint(`source.${language}`, {
66
type: nodeType,
7-
language(node) {
7+
language() {
88
return language;
99
},
1010
content(node) {
1111
return node.lastNamedChild;
1212
}
1313
});
1414
}
15+
16+
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
17+
const HYPERLINK_PATTERN = /\bhttps?:/
18+
19+
atom.grammars.addInjectionPoint(`source.${language}`, {
20+
type: 'comment',
21+
language: (node) => {
22+
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
23+
},
24+
content: (node) => node,
25+
languageScope: null
26+
});
27+
28+
for (let type of ['string_literal', 'comment']) {
29+
atom.grammars.addInjectionPoint(`source.${language}`, {
30+
type,
31+
language: (node) => {
32+
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
33+
},
34+
content: (node) => node,
35+
languageScope: null
36+
});
37+
}
1538
}
1639
};

packages/language-c/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"license": "MIT",
1111
"engines": {
1212
"atom": "*",
13-
"node": "*"
13+
"node": ">=12"
1414
},
1515
"dependencies": {
1616
"tree-sitter-c": "0.20.2",

packages/language-css/lib/main.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
exports.activate = () => {
22

3-
atom.grammars.addInjectionPoint('source.css', {
4-
type: 'comment',
5-
language: () => 'todo',
6-
content: (node) => node
7-
});
3+
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
4+
const HYPERLINK_PATTERN = /\bhttps?:/
85

96
atom.grammars.addInjectionPoint('source.css', {
107
type: 'comment',
11-
language: () => 'hyperlink',
12-
content: (node) => node
8+
language(node) {
9+
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
10+
},
11+
content: (node) => node,
12+
languageScope: null
1313
});
1414

15-
atom.grammars.addInjectionPoint('source.css', {
16-
type: 'string_value',
17-
language: () => 'hyperlink',
18-
content: (node) => node
19-
});
15+
for (let type of ['comment', 'string_value']) {
16+
atom.grammars.addInjectionPoint('source.css', {
17+
type,
18+
language(node) {
19+
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
20+
},
21+
content: (node) => node,
22+
languageScope: null
23+
});
24+
}
2025

2126
// Catch things like
2227
//
@@ -31,7 +36,8 @@ exports.activate = () => {
3136
if (!functionName === 'url') { return null; }
3237

3338
return node.descendantsOfType('plain_value');
34-
}
39+
},
40+
languageScope: null
3541
});
3642

3743
};

packages/language-go/lib/main.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
exports.activate = () => {
2+
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
3+
const HYPERLINK_PATTERN = /\bhttps?:/
4+
5+
for (let type of ['comment', 'interpreted_string_literal', 'raw_string_literal']) {
6+
atom.grammars.addInjectionPoint('source.go', {
7+
type,
8+
language: (node) => {
9+
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
10+
},
11+
content: (node) => node,
12+
languageScope: null
13+
});
14+
}
15+
16+
atom.grammars.addInjectionPoint('source.go', {
17+
type: 'comment',
18+
language(node) {
19+
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
20+
},
21+
content: (node) => node,
22+
languageScope: null
23+
});
24+
25+
};

packages/language-go/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "language-go",
33
"description": "Go language support in Atom",
4+
"main": "lib/main",
45
"keywords": [
56
"tree-sitter"
67
],

packages/language-html/grammars/tree-sitter-html/folds.scm

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11

2-
; (element) @fold
3-
; (style_element) @fold
4-
; (script_element) @fold
5-
62
[
73
(element)
84
(script_element)

packages/language-hyperlink/spec/hyperlink-spec.js

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11

22
const path = require('path');
33

4-
describe('Hyperlink grammar', function() {
4+
describe('Hyperlink grammar', function () {
55
let grammar = null;
66

7-
beforeEach(function() {
7+
beforeEach(function () {
8+
// TODO: All these specs rely on the ability of a grammar to tokenize a
9+
// line in isolation, which is something that a `WASMTreeSitterGrammar`
10+
// cannot do. This package will need specialized tests for the modern
11+
// Tree-sitter world the same way that most other language packages do.
12+
atom.config.set('core.useTreeSitterParsers', false);
813
waitsForPromise(() => atom.packages.activatePackage('language-hyperlink'));
914

1015
runs(() => grammar = atom.grammars.grammarForScopeName('text.hyperlink'));
1116
});
1217

13-
it('parses the grammar', function() {
18+
it('parses the grammar', function () {
1419
expect(grammar).toBeTruthy();
1520
expect(grammar.scopeName).toBe('text.hyperlink');
1621
});
1722

18-
it('parses http: and https: links', function() {
23+
it('parses http: and https: links', function () {
1924
const plainGrammar = atom.grammars.selectGrammar();
2025

2126
let {tokens} = plainGrammar.tokenizeLine('http://github.com');
@@ -29,16 +34,16 @@ describe('Hyperlink grammar', function() {
2934

3035
({tokens} = plainGrammar.tokenizeLine('https://github.com/atom/brightray_example'));
3136
expect(tokens[0]).toEqual({value: 'https://github.com/atom/brightray_example', scopes: ['text.plain.null-grammar', 'markup.underline.link.https.hyperlink']});
32-
});
37+
});
3338

34-
it('parses http: and https: links that contains unicode characters', function() {
39+
it('parses http: and https: links that contains unicode characters', function () {
3540
const plainGrammar = atom.grammars.selectGrammar();
3641

3742
const {tokens} = plainGrammar.tokenizeLine('https://sv.wikipedia.org/wiki/Mañana');
3843
expect(tokens[0]).toEqual({value: 'https://sv.wikipedia.org/wiki/Mañana', scopes: ['text.plain.null-grammar', 'markup.underline.link.https.hyperlink']});
39-
});
44+
});
4045

41-
it('parses other links', function() {
46+
it('parses other links', function () {
4247
const plainGrammar = atom.grammars.selectGrammar();
4348

4449
let {tokens} = plainGrammar.tokenizeLine('mailto:noreply@example.com');
@@ -49,55 +54,57 @@ describe('Hyperlink grammar', function() {
4954

5055
({tokens} = plainGrammar.tokenizeLine('atom://core/open/file?filename=urlEncodedFileName&line=n&column=n'));
5156
expect(tokens[0]).toEqual({value: 'atom://core/open/file?filename=urlEncodedFileName&line=n&column=n', scopes: ['text.plain.null-grammar', 'markup.underline.link.atom.hyperlink']});
52-
});
57+
});
5358

54-
it('does not parse links in a regex string', function() {
59+
it('does not parse links in a regex string', function () {
5560
const testGrammar = atom.grammars.loadGrammarSync(path.join(__dirname, 'fixtures', 'test-grammar.cson'));
5661

5762
const {tokens} = testGrammar.tokenizeLine('regexp:http://github.com');
5863
expect(tokens[1]).toEqual({value: 'http://github.com', scopes: ['source.test', 'string.regexp.test']});
59-
});
60-
61-
describe('parsing PHP strings', () => it('does not parse links in a regex string', function() {
62-
// PHP is unique in that its root scope is `text.html.php`, meaning that even though
63-
// `string - string.regexp` won't match in a regex string, `text` still will.
64-
// This is the reason the injection selector is `text - string.regexp` instead.
65-
// https://github.com/atom/language-php/issues/219
66-
67-
waitsForPromise(() => atom.packages.activatePackage('language-php'));
68-
69-
runs(function() {
70-
const phpGrammar = atom.grammars.grammarForScopeName('text.html.php');
64+
});
7165

72-
const {tokens} = phpGrammar.tokenizeLine('<?php "/mailto:/" ?>');
73-
expect(tokens[3]).toEqual({value: 'mailto:', scopes: ['text.html.php', 'meta.embedded.line.php', 'source.php', 'string.regexp.double-quoted.php']});});
74-
}));
66+
describe('parsing PHP strings', () => {
67+
it('does not parse links in a regex string', function () {
68+
// PHP is unique in that its root scope is `text.html.php`, meaning that even though
69+
// `string - string.regexp` won't match in a regex string, `text` still will.
70+
// This is the reason the injection selector is `text - string.regexp` instead.
71+
// https://github.com/atom/language-php/issues/219
72+
73+
waitsForPromise(() => atom.packages.activatePackage('language-php'));
74+
75+
runs(() => {
76+
const phpGrammar = atom.grammars.grammarForScopeName('text.html.php');
77+
const {tokens} = phpGrammar.tokenizeLine('<?php "/mailto:/" ?>');
78+
expect(tokens[3]).toEqual({ value: 'mailto:', scopes: ['text.html.php', 'meta.embedded.line.php', 'source.php', 'string.regexp.double-quoted.php']});
79+
});
80+
});
81+
});
7582

76-
describe('parsing cfml strings', function() {
77-
it('does not include anything between (and including) pound signs', function() {
83+
describe('parsing cfml strings', function () {
84+
it('does not include anything between (and including) pound signs', function () {
7885
const plainGrammar = atom.grammars.selectGrammar();
7986
const {tokens} = plainGrammar.tokenizeLine('http://github.com/#username#');
8087
expect(tokens[0]).toEqual({value: 'http://github.com/', scopes: ['text.plain.null-grammar', 'markup.underline.link.http.hyperlink']});
81-
});
88+
});
8289

83-
it('still includes single pound signs', function() {
90+
it('still includes single pound signs', function () {
8491
const plainGrammar = atom.grammars.selectGrammar();
8592
const {tokens} = plainGrammar.tokenizeLine('http://github.com/atom/#start-of-content');
8693
expect(tokens[0]).toEqual({value: 'http://github.com/atom/#start-of-content', scopes: ['text.plain.null-grammar', 'markup.underline.link.http.hyperlink']});
94+
});
8795
});
88-
});
8996

90-
describe('parsing matching parentheses', function() {
91-
it('still includes matching parentheses', function() {
97+
describe('parsing matching parentheses', function () {
98+
it('still includes matching parentheses', function () {
9299
const plainGrammar = atom.grammars.selectGrammar();
93100
const {tokens} = plainGrammar.tokenizeLine('https://en.wikipedia.org/wiki/Atom_(text_editor)');
94101
expect(tokens[0]).toEqual({value: 'https://en.wikipedia.org/wiki/Atom_(text_editor)', scopes: ['text.plain.null-grammar', 'markup.underline.link.https.hyperlink']});
95-
});
102+
});
96103

97-
it('does not include wrapping parentheses', function() {
104+
it('does not include wrapping parentheses', function () {
98105
const plainGrammar = atom.grammars.selectGrammar();
99106
const {tokens} = plainGrammar.tokenizeLine('(https://en.wikipedia.org/wiki/Atom_(text_editor))');
100107
expect(tokens[1]).toEqual({value: 'https://en.wikipedia.org/wiki/Atom_(text_editor)', scopes: ['text.plain.null-grammar', 'markup.underline.link.https.hyperlink']});
108+
});
101109
});
102110
});
103-
});

packages/language-java/lib/main.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
11
exports.activate = () => {
2-
// TODO: Injections for language-todo and language-hyperlink.
2+
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
3+
const HYPERLINK_PATTERN = /\bhttps?:/
4+
5+
atom.grammars.addInjectionPoint('source.java', {
6+
type: 'comment',
7+
language: (node) => {
8+
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
9+
},
10+
content: (node) => node,
11+
languageScope: null
12+
});
13+
14+
for (let type of ['string_literal', 'comment']) {
15+
atom.grammars.addInjectionPoint('source.java', {
16+
type,
17+
language: (node) => {
18+
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
19+
},
20+
content: (node) => node,
21+
languageScope: null
22+
});
23+
}
324
};

packages/language-javascript/grammars/ts/highlights.scm

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@
7474
; The "bar" in `foo.bar = true`
7575
(assignment_expression
7676
left: (member_expression
77-
property: (property_identifier)) @variable.other.assignment.property.js)
77+
property: (property_identifier) @variable.other.assignment.property.js))
78+
79+
; The "bar" in `foo.#bar = true`
80+
(assignment_expression
81+
left: (member_expression
82+
property: (private_property_identifier) @variable.other.assignment.property.private.js))
83+
7884

7985
; The "foo" in `foo += 1`.
8086
(augmented_assignment_expression
@@ -84,6 +90,9 @@
8490
(update_expression
8591
argument: (identifier) @variable.other.assignment.js)
8692

93+
(field_definition
94+
property: (private_property_identifier) @variable.other.assignment.property.private.js)
95+
8796
; `object_pattern` appears to only be encountered in assignment expressions, so
8897
; this won't match other uses of object/prop shorthand.
8998
;
@@ -136,6 +145,13 @@
136145
(array_pattern
137146
(identifier) @variable.other.assignment.destructuring.js))
138147

148+
; A variable array destructuring with a default:
149+
; The "baz" in `let [foo, bar, baz = false] = something`
150+
(variable_declarator
151+
(array_pattern
152+
(assignment_pattern
153+
(identifier) @variable.other.assignment.destructuring.js)))
154+
139155
; A variable declaration in a for…(in|of) loop:
140156
; The "foo" in `for (let foo of bar) {`
141157
(for_in_statement
@@ -203,7 +219,7 @@
203219
; The "foo" in `function (foo = false) {`.
204220
(formal_parameters
205221
(assignment_pattern
206-
(identifier) @variable.parameter.js))
222+
left: (identifier) @variable.parameter.js))
207223

208224

209225
; FUNCTIONS
@@ -451,6 +467,10 @@
451467
(member_expression
452468
property: (property_identifier) @support.other.property.js)
453469

470+
; The "#bar" in `foo.#bar`, `foo.#bar.baz`, and `foo.#bar[baz]`.
471+
(member_expression
472+
property: (private_property_identifier) @support.other.property.private.js)
473+
454474
; The "BAR" in `foo.BAR` should also be scoped as a constant.
455475
(member_expression
456476
property: (property_identifier) @constant.other.property.js

0 commit comments

Comments
 (0)