Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide token scope map #1349

Merged
merged 2 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Changes to Calva.

## [Unreleased]
- [Provide semantic token fallback map for Calva's TM grammar](https://github.com/BetterThanTomorrow/calva/issues/1348)

## [2.0.218] - 2021-10-18
- [npm audit fixes](https://github.com/BetterThanTomorrow/calva/issues/1346)
Expand Down
16 changes: 15 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@
"editor.parameterHints.enabled": false
}
},
"semanticTokenScopes": [
{
"language": "clojure",
"scopes": {
"macro": [
"storage.control.clojure",
"keyword.control.clojure"
],
"keyword": [
"variable.other.constant.clojure"
]
}
}
],
"configuration": [
{
"type": "object",
Expand Down Expand Up @@ -2558,4 +2572,4 @@
"webpack": "^5.27.1",
"webpack-cli": "^4.5.0"
}
}
}
20 changes: 14 additions & 6 deletions src/calva-fmt/atom-language-clojure/grammars/clojure.cson
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@
}
{
'match': '(?<=^|\\s|\\(|\\[|\\{)(declare-?|(in-)?ns|import|use|require|load|compile|(def(?!ault)[\\p{Ll}\\-]*))(?=(\\s|\\)|\\]|\\}))'
'name': 'keyword.control.clojure'
'name': 'storage.control.clojure'
}
]
'dynamic-variables':
'match': '\\*[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\d]+\\*'
'name': 'meta.symbol.dynamic.clojure'
'name': 'entity.name.variable.dynamic.clojure'
'map':
'begin': '(\\{)'
'beginCaptures':
Expand Down Expand Up @@ -297,7 +297,7 @@
'begin': '(?<=\\()(ns|declare|def(?!ault)[\\w\\d._:+=><!?*-]*|[\\w._:+=><!?*-][\\w\\d._:+=><!?*-]*/def(?!ault)[\\w\\d._:+=><!?*-]*)\\s+'
'beginCaptures':
'1':
'name': 'keyword.control.clojure'
'name': 'storage.control.clojure'
'end': '(?=\\))'
'name': 'meta.definition.global.clojure'
'patterns': [
Expand Down Expand Up @@ -337,6 +337,14 @@
{
'include': '#sexp'
}
{
'match': '(?<=\\()([\\p{L}\\.\\-\\_\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)/([^"]+?)(?=\\s|\\))'
'captures':
'1':
'name': 'entity.name.namespace.clojure'
'2':
'name': 'entity.name.function.clojure'
}
{
'match': '(?<=\\()([^"]+?)(?=\\s|\\))'
'captures':
Expand Down Expand Up @@ -383,14 +391,14 @@
'match': '([\\p{L}\\.\\-\\_\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)/'
'captures':
'1':
'name': 'meta.symbol.namespace.clojure'
'name': 'entity.name.namespace.clojure'
}
]
'symbol':
'patterns': [
{
'match': '([\\p{L}\\.\\-\\_\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)'
'name': 'meta.symbol.clojure'
'name': 'entity.name.variable.clojure'
}
]
'var':
Expand Down Expand Up @@ -423,7 +431,7 @@
'2':
'name': 'keyword.control.prompt.clojure'
'3':
'name': 'meta.symbol.namespace.prompt.clojure'
'name': 'entity.name.namespace.prompt.clojure'
'4':
'name': 'keyword.control.prompt.clojure'
}
Expand Down
58 changes: 36 additions & 22 deletions src/calva-fmt/atom-language-clojure/spec/clojure-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe "Clojure grammar", ->
it "does not tokenize escaped semicolons as comments", ->
{tokens} = grammar.tokenizeLine "\\; clojure"
expect(tokens[0]).toEqual value: "\\; ", scopes: ["source.clojure"]
expect(tokens[1]).toEqual value: "clojure", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[1]).toEqual value: "clojure", scopes: ["source.clojure", "entity.name.variable.clojure"]

it "tokenizes shebang comments", ->
{tokens} = grammar.tokenizeLine "#!/usr/bin/env clojure"
Expand Down Expand Up @@ -148,17 +148,23 @@ describe "Clojure grammar", ->

for keyfn in keyfns
{tokens} = grammar.tokenizeLine "(#{keyfn})"
expect(tokens[1]).toEqual value: keyfn, scopes: ["source.clojure", "meta.expression.clojure", "keyword.control.clojure"]
expect(tokens[1]).toEqual value: keyfn, scopes: ["source.clojure", "meta.expression.clojure", "storage.control.clojure"]

it "does not tokenize `default...`s as keyfn (keyword control)", ->
{tokens} = grammar.tokenizeLine "(defnormal foo)"
expect(tokens[1].scopes).toContain "keyword.control.clojure"
expect(tokens[1].scopes).toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(foo/defnormal foo)"
expect(tokens[1].scopes).toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(normaldef foo)"
expect(tokens[1].scopes).not.toContain "keyword.control.clojure"
expect(tokens[1].scopes).not.toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(default foo)"
expect(tokens[1].scopes).not.toContain "keyword.control.clojure"
expect(tokens[1].scopes).not.toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(defaultfoo ba)"
expect(tokens[1].scopes).not.toContain "keyword.control.clojure"
expect(tokens[1].scopes).not.toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(foo/default foo)"
expect(tokens[1].scopes).not.toContain "storage.control.clojure"
{tokens} = grammar.tokenizeLine "(foo/defaultfoo ba)"
expect(tokens[1].scopes).not.toContain "storage.control.clojure"

it "tokenizes keyfns (storage control)", ->
keyfns = ["if", "when", "for", "cond", "do", "let", "binding", "loop", "recur", "fn", "throw", "try", "catch", "finally", "case"]
Expand All @@ -172,25 +178,25 @@ describe "Clojure grammar", ->

for macro in macros
{tokens} = grammar.tokenizeLine "(#{macro} foo 'bar)"
expect(tokens[1]).toEqual value: macro, scopes: ["source.clojure", "meta.expression.clojure", "meta.definition.global.clojure", "keyword.control.clojure"]
expect(tokens[1]).toEqual value: macro, scopes: ["source.clojure", "meta.expression.clojure", "meta.definition.global.clojure", "storage.control.clojure"]
expect(tokens[3]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "meta.definition.global.clojure", "entity.global.clojure"]

it "tokenizes dynamic variables", ->
mutables = ["*ns*", "*foo-bar*", "*åÄÖπç*"]

for mutable in mutables
{tokens} = grammar.tokenizeLine mutable
expect(tokens[0]).toEqual value: mutable, scopes: ["source.clojure", "meta.symbol.dynamic.clojure"]
expect(tokens[0]).toEqual value: mutable, scopes: ["source.clojure", "entity.name.variable.dynamic.clojure"]

it "tokenizes metadata", ->
{tokens} = grammar.tokenizeLine "^Foo"
expect(tokens[0]).toEqual value: "^", scopes: ["source.clojure", "meta.metadata.simple.clojure"]
expect(tokens[1]).toEqual value: "Foo", scopes: ["source.clojure", "meta.metadata.simple.clojure", "meta.symbol.clojure"]
expect(tokens[1]).toEqual value: "Foo", scopes: ["source.clojure", "meta.metadata.simple.clojure", "entity.name.variable.clojure"]

# non-ASCII letters
{tokens} = grammar.tokenizeLine "^Öπ"
expect(tokens[0]).toEqual value: "^", scopes: ["source.clojure", "meta.metadata.simple.clojure"]
expect(tokens[1]).toEqual value: "Öπ", scopes: ["source.clojure", "meta.metadata.simple.clojure", "meta.symbol.clojure"]
expect(tokens[1]).toEqual value: "Öπ", scopes: ["source.clojure", "meta.metadata.simple.clojure", "entity.name.variable.clojure"]

{tokens} = grammar.tokenizeLine "^{:foo true}"
expect(tokens[0]).toEqual value: "^{", scopes: ["source.clojure", "meta.metadata.map.clojure", "punctuation.section.metadata.map.begin.clojure"]
Expand All @@ -206,6 +212,14 @@ describe "Clojure grammar", ->
{tokens} = grammar.tokenizeLine expr
expect(tokens[1]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.function.clojure"]

namespaced_expressions = ["(bar/foo)", "(bar/foo 1 10)"]

for expr in namespaced_expressions
{tokens} = grammar.tokenizeLine expr
expect(tokens[1]).toEqual value: "bar", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.namespace.clojure"]
expect(tokens[2]).toEqual value: "/", scopes: ["source.clojure", "meta.expression.clojure"]
expect(tokens[3]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.function.clojure"]

#non-ASCII letters
{tokens} = grammar.tokenizeLine "(Öπ 2 20)"
expect(tokens[1]).toEqual value: "Öπ", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.function.clojure"]
Expand All @@ -222,27 +236,27 @@ describe "Clojure grammar", ->

it "tokenizes symbols", ->
{tokens} = grammar.tokenizeLine "x"
expect(tokens[0]).toEqual value: "x", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[0]).toEqual value: "x", scopes: ["source.clojure", "entity.name.variable.clojure"]

# non-ASCII letters
{tokens} = grammar.tokenizeLine "Öπ"
expect(tokens[0]).toEqual value: "Öπ", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[0]).toEqual value: "Öπ", scopes: ["source.clojure", "entity.name.variable.clojure"]

# Should not be tokenized as a symbol
{tokens} = grammar.tokenizeLine "1foobar"
expect(tokens[0]).toEqual value: "1", scopes: ["source.clojure", "constant.numeric.long.clojure"]

it "tokenizes namespaces", ->
{tokens} = grammar.tokenizeLine "foo/bar"
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "meta.symbol.namespace.clojure"]
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "entity.name.namespace.clojure"]
expect(tokens[1]).toEqual value: "/", scopes: ["source.clojure"]
expect(tokens[2]).toEqual value: "bar", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[2]).toEqual value: "bar", scopes: ["source.clojure", "entity.name.variable.clojure"]

# non-ASCII letters
{tokens} = grammar.tokenizeLine "Öπ/Åä"
expect(tokens[0]).toEqual value: "Öπ", scopes: ["source.clojure", "meta.symbol.namespace.clojure"]
expect(tokens[0]).toEqual value: "Öπ", scopes: ["source.clojure", "entity.name.namespace.clojure"]
expect(tokens[1]).toEqual value: "/", scopes: ["source.clojure"]
expect(tokens[2]).toEqual value: "Åä", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[2]).toEqual value: "Åä", scopes: ["source.clojure", "entity.name.variable.clojure"]

testMetaSection = (metaScope, puncScope, startsWith, endsWith) ->
# Entire expression on one line.
Expand Down Expand Up @@ -295,10 +309,10 @@ describe "Clojure grammar", ->
expect(tokens[1]).toEqual value: "(", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure", "punctuation.section.expression.begin.clojure"]
expect(tokens[2]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure", "entity.name.function.clojure"]
expect(tokens[3]).toEqual value: " ", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure"]
expect(tokens[4]).toEqual value: "bar", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure", "meta.symbol.clojure"]
expect(tokens[4]).toEqual value: "bar", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure", "entity.name.variable.clojure"]
expect(tokens[5]).toEqual value: ")", scopes: ["source.clojure", "meta.expression.clojure", "meta.expression.clojure", "punctuation.section.expression.end.clojure"]
expect(tokens[6]).toEqual value: " ", scopes: ["source.clojure", "meta.expression.clojure"]
expect(tokens[7]).toEqual value: "baz", scopes: ["source.clojure", "meta.expression.clojure", "meta.symbol.clojure"]
expect(tokens[7]).toEqual value: "baz", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.variable.clojure"]
expect(tokens[8]).toEqual value: ")", scopes: ["source.clojure", "meta.expression.clojure", "punctuation.section.expression.end.trailing.clojure"]

it "tokenizes maps used as functions", ->
Expand All @@ -307,7 +321,7 @@ describe "Clojure grammar", ->
expect(tokens[1]).toEqual value: "{", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure", "punctuation.section.map.begin.clojure"]
expect(tokens[2]).toEqual value: ":foo", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure", "variable.other.constant.clojure"]
expect(tokens[3]).toEqual value: " ", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure"]
expect(tokens[4]).toEqual value: "bar", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure", "meta.symbol.clojure"]
expect(tokens[4]).toEqual value: "bar", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure", "entity.name.variable.clojure"]
expect(tokens[5]).toEqual value: "}", scopes: ["source.clojure", "meta.expression.clojure", "meta.map.clojure", "punctuation.section.map.end.clojure"]
expect(tokens[6]).toEqual value: " ", scopes: ["source.clojure", "meta.expression.clojure"]
expect(tokens[7]).toEqual value: ":foo", scopes: ["source.clojure", "meta.expression.clojure", "variable.other.constant.clojure"]
Expand Down Expand Up @@ -336,15 +350,15 @@ describe "Clojure grammar", ->
{tokens} = grammar.tokenizeLine "foo꞉bar.baz-2꞉> "
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "keyword.control.prompt.clojure"]
expect(tokens[1]).toEqual value: "꞉", scopes: ["source.clojure", "keyword.control.prompt.clojure"]
expect(tokens[2]).toEqual value: "bar.baz-2", scopes: ["source.clojure", "meta.symbol.namespace.prompt.clojure"]
expect(tokens[2]).toEqual value: "bar.baz-2", scopes: ["source.clojure", "entity.name.namespace.prompt.clojure"]
expect(tokens[3]).toEqual value: "꞉>", scopes: ["source.clojure", "keyword.control.prompt.clojure"]
it "does not tokenize repl prompt when prepended with anything", ->
{tokens} = grammar.tokenizeLine " foo꞉bar.baz-2꞉> "
expect(tokens[0]).toEqual value: " ", scopes: ["source.clojure"]
expect(tokens[1]).toEqual value: "foo", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[1]).toEqual value: "foo", scopes: ["source.clojure", "entity.name.variable.clojure"]
it "does not tokenize repl prompt when not followed by hard space", ->
{tokens} = grammar.tokenizeLine "foo꞉bar.baz-2꞉>"
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "meta.symbol.clojure"]
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "entity.name.variable.clojure"]

describe "firstLineMatch", ->
it "recognises interpreter directives", ->
Expand Down