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

Semantic highlighting (v2) #1839

Merged
merged 61 commits into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
54c5725
Add support for semantic tokens
jwortmann Aug 15, 2021
df71b31
Address some comments
jwortmann Sep 5, 2021
fc4c57a
Update stub file
jwortmann Sep 5, 2021
1fe2740
Make semantic tokens mapping be part of the configuration
jwortmann Sep 8, 2021
8ca086b
Merge branch 'main' into semantic-highlighting
jwortmann Sep 9, 2021
7c9c911
Fix linter error
jwortmann Sep 9, 2021
9a5d518
Only update regions which actually changed
jwortmann Sep 10, 2021
202a3e3
Merge branch 'main' into semantic-highlighting
rwols Sep 12, 2021
10d467f
Initialize region keys for new SessionViews
jwortmann Sep 14, 2021
992324a
Combine all instance variables into a SemanticTokensData class
jwortmann Sep 14, 2021
c7e34f7
Type annotation
jwortmann Sep 14, 2021
21ef85f
I hate this linter
jwortmann Sep 14, 2021
b4983dc
Fix upper bound for diagnostic tags when initializing regins
jwortmann Sep 14, 2021
3519985
Merge branch 'main' into semantic-highlighting
rwols Sep 18, 2021
4f4e7ae
Fix off-by-one error in scope name popup
jwortmann Sep 19, 2021
41ad058
Merge branch 'main' into semantic-highlighting
jwortmann Sep 19, 2021
6beb9d5
Don't update regions if there were changes to the buffer between requ…
jwortmann Sep 23, 2021
bbd04ce
Merge branch 'main' into semantic-highlighting
jwortmann Sep 23, 2021
3f32aaa
Draw scope-less tokens if there is a color scheme rule for it
jwortmann Sep 30, 2021
8cec036
Ensure lowercase scope name and update docs
jwortmann Oct 1, 2021
34f8c60
Merge branch 'main' into semantic-highlighting
jwortmann Oct 1, 2021
d94d2d8
Merge branch 'main' into semantic-highlighting
jwortmann Oct 25, 2021
16ffaeb
Merge branch 'main' into semantic-highlighting
jwortmann Oct 28, 2021
cdc74af
Add error response handler and rename state variable
jwortmann Oct 28, 2021
a8bc0bc
Merge branch 'main' into semantic-highlighting
jwortmann Oct 31, 2021
1aa70fc
Merge branch 'main' into semantic-highlighting
jwortmann Nov 7, 2021
513a901
Adjust scope mapping for constants
jwortmann Nov 13, 2021
8a40191
Add caching for token decoding
jwortmann Nov 13, 2021
dd004c0
Listen for show_scope_name command if semantic highlighting is enabled
jwortmann Nov 14, 2021
0f3aa4a
Move function for token decoding to Session class
jwortmann Nov 14, 2021
2aadb1a
Add required rule for semantic highlighting to the default color schemes
jwortmann Nov 14, 2021
1ee0cd5
Don't check for pending response
jwortmann Nov 16, 2021
d01a3c7
Merge branch 'main' into semantic-highlighting
jwortmann Nov 19, 2021
75ee9b9
Use different strategy for semantic tokens request after text change
jwortmann Nov 19, 2021
bbbb4b8
notify sessionbuffer of sessionview being removed
rchl Nov 19, 2021
5c58891
Address some comments
jwortmann Nov 19, 2021
4ede8d0
Remove token regions when server gets disabled
jwortmann Nov 19, 2021
f32fe9c
Small tweak
jwortmann Nov 20, 2021
0a6f7fb
Use caching for token decoding
jwortmann Nov 21, 2021
eac3ff6
Don't mutate dict while iterating
jwortmann Nov 21, 2021
84f68da
Merge branch 'main' into semantic-highlighting
jwortmann Nov 21, 2021
a162b77
Code formatting and indentation
jwortmann Nov 21, 2021
1a77566
Code cleanup
jwortmann Nov 21, 2021
5885b61
Request semantic tokens for all visible views on refresh
jwortmann Nov 23, 2021
80feebd
Always redraw all regions after semantic tokens response
jwortmann Dec 4, 2021
0a167c1
Allow color schemes to target tokens with modifiers
jwortmann Dec 4, 2021
dd565bb
Update ST API type stub
jwortmann Dec 4, 2021
9ba3a11
Merge branch 'main' into semantic-highlighting
jwortmann Dec 6, 2021
c884364
Allow scope overrides for tokens with one modifier
jwortmann Dec 6, 2021
19a3685
Update tokens for visible views in all groups after refresh request
jwortmann Dec 6, 2021
d96a25f
Update docs
jwortmann Dec 9, 2021
a658a7c
Update meta scopes for tokens with modifiers
jwortmann Dec 9, 2021
d545a1f
Merge branch 'main' into semantic-highlighting
jwortmann Dec 15, 2021
d17ad0d
Declare required methods on SessionBufferProtocol interface
jwortmann Dec 15, 2021
ea80e28
Revert "Add required rule for semantic highlighting to the default co…
jwortmann Dec 15, 2021
6a582d5
Declare getter method for tokens on SessionBufferProtocol
jwortmann Dec 15, 2021
06538c9
Merge branch 'main' into semantic-highlighting
jwortmann Dec 16, 2021
5014576
Cancel request with pending response on new request
jwortmann Dec 20, 2021
814905c
Remove unnecessary type hint
jwortmann Dec 20, 2021
8d7d488
Revert "Revert "Add required rule for semantic highlighting to the de…
jwortmann Dec 20, 2021
1a9e1a9
Cleanup
jwortmann Dec 23, 2021
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
8 changes: 8 additions & 0 deletions ColorSchemes/Breakers.sublime-color-scheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000001"
}
]
}
8 changes: 8 additions & 0 deletions ColorSchemes/Celeste.sublime-color-scheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000001"
}
]
}
8 changes: 8 additions & 0 deletions ColorSchemes/Mariana.sublime-color-scheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000001"
}
]
}
8 changes: 8 additions & 0 deletions ColorSchemes/Monokai.sublime-color-scheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000001"
}
]
}
8 changes: 8 additions & 0 deletions ColorSchemes/Sixteen.sublime-color-scheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000001"
}
]
}
8 changes: 8 additions & 0 deletions LSP.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@
// Valid values are "dot", "circle", "bookmark", "sign" or ""
"diagnostics_gutter_marker": "dot",

// Enable semantic highlighting in addition to standard syntax highlighting (experimental!).
// Note: Must be supported by the language server and also requires a special rule in the
// color scheme to work. If you use none of the built-in color schemes from Sublime Text,
// please see the documentation under
// https://lsp.sublimetext.io/customization/#semantic-highlighting
// for a description about how to configure your color scheme for semantic highlighting.
"semantic_highlighting": false,

// Show code actions:
// "annotation" - show an annotation on the right when code actions are available.
// "bulb" - show a bulb in the gutter when code actions are available.
Expand Down
1 change: 1 addition & 0 deletions boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
from .plugin.save_command import LspSaveAllCommand
from .plugin.save_command import LspSaveCommand
from .plugin.selection_range import LspExpandSelectionCommand
from .plugin.semantic_highlighting import LspShowScopeNameCommand
from .plugin.symbols import LspDocumentSymbolsCommand
from .plugin.symbols import LspSelectionAddCommand
from .plugin.symbols import LspSelectionClearCommand
Expand Down
70 changes: 70 additions & 0 deletions docs/src/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,76 @@ There is an example in the [official ST documentation](https://www.sublimetext.c

The following tables give an overview about the scope names used by LSP.

### Semantic Highlighting

!!! info "This feature is only available if the server has the *semanticTokensProvider* capability."
Language servers which support semantic highlighting are for example *clangd* and *rust-analyzer*.

In order to support semantic highlighting, the color scheme requires a special rule with a background color set for semantic tokens, which is (marginally) different from the original background.
LSP automatically adds such a rule to the built-in color schemes from Sublime Text.
If you use a custom color scheme, select `UI: Customize Color Scheme` from the Command Palette and add for example the following code:

```json
{
"rules": [
{
"scope": "meta.semantic-token",
"background": "#00000101"
},
]
}
```

Furthermore it is possible to adjust the colors for semantic tokens by applying a foreground color to the individual token types:

| scope | [Semantic Token Type](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#semanticTokenTypes) |
| ----- | ------------------ |
| `meta.semantic-token.namespace` | namespace |
| `meta.semantic-token.type` | type |
| `meta.semantic-token.class` | class |
| `meta.semantic-token.enum` | enum |
| `meta.semantic-token.interface` | interface |
| `meta.semantic-token.struct` | struct |
| `meta.semantic-token.typeparameter` | typeParameter |
| `meta.semantic-token.parameter` | parameter |
| `meta.semantic-token.variable` | variable |
| `meta.semantic-token.property` | property |
| `meta.semantic-token.enummember` | enumMember |
| `meta.semantic-token.event` | event |
| `meta.semantic-token.function` | function |
| `meta.semantic-token.method` | method |
| `meta.semantic-token.macro` | macro |
| `meta.semantic-token.keyword` | keyword |
| `meta.semantic-token.modifier` | modifier |
| `meta.semantic-token.comment` | comment |
| `meta.semantic-token.string` | string |
| `meta.semantic-token.number` | number |
| `meta.semantic-token.regexp` | regexp |
| `meta.semantic-token.operator` | operator |

By default, LSP will assign scopes based on the [scope naming guideline](https://www.sublimetext.com/docs/scope_naming.html) to each of these token types, but if you define color scheme rules for the scopes specified above, the latter will take precedence.

Language servers can also add their own custom token types, which are not defined in the protocol.
A "LSP-*" helper package (or user) can provide a "semantic_tokens" mapping in the server configuration for such additional token types, or to override the scopes used for the predefined tokens from the table above.
Keys of this mapping should be the token types and values should be the corresponding scopes.
Semantic tokens with exactly one [token modifier](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#semanticTokenModifiers) can be addressed by apending the modifier after a dot.

```json
{
"semantic_tokens": {
"magicFunction": "support.function.builtin",
"selfParameter": "variable.language",
"type.defaultLibrary": "storage.type.builtin"
}
}
```

The color for custom token types can also be adjusted via a color scheme rule for the scope `meta.semantic-token.<token-type>`, where `<token-type>` is the name of the custom token type, but with all letters lowercased (similar to the listed scopes in the table above).
To target tokens with one modifier, use the scope `meta.semantic-token.<token-type>.<token-modifier>` (all lowercased).
Currently, semantic tokens with more than one modifier cannot be styled reliably.

If neither a scope for a custom token type is defined, nor a color scheme rule for this token type exists, then it will only be highlighted via the regular syntax highlighting.

### Document Highlights

!!! info "This feature is only available if the server has the *documentHighlightProvider* capability."
Expand Down
50 changes: 50 additions & 0 deletions plugin/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,44 @@ class InsertTextMode:
AdjustIndentation = 2


class SemanticTokenTypes:
Namespace = "namespace"
Type = "type"
Class = "class"
Enum = "enum"
Interface = "interface"
Struct = "struct"
TypeParameter = "typeParameter"
Parameter = "parameter"
Variable = "variable"
Property = "property"
EnumMember = "enumMember"
Event = "event"
Function = "function"
Method = "method"
Macro = "macro"
Keyword = "keyword"
Modifier = "modifier"
Comment = "comment"
String = "string"
Number = "number"
Regexp = "regexp"
Operator = "operator"


class SemanticTokenModifiers:
Declaration = "declaration"
Definition = "definition"
Readonly = "readonly"
Static = "static"
Deprecated = "deprecated"
Abstract = "abstract"
Async = "async"
Modification = "modification"
Documentation = "documentation"
DefaultLibrary = "defaultLibrary"


DocumentUri = str

Position = TypedDict('Position', {
Expand Down Expand Up @@ -316,6 +354,18 @@ def documentSymbols(cls, params: Mapping[str, Any], view: sublime.View) -> 'Requ
def documentHighlight(cls, params: Mapping[str, Any], view: sublime.View) -> 'Request':
return Request("textDocument/documentHighlight", params, view)

@classmethod
def semanticTokensFull(cls, params: Mapping[str, Any], view: sublime.View) -> 'Request':
return Request("textDocument/semanticTokens/full", params, view)

@classmethod
def semanticTokensFullDelta(cls, params: Mapping[str, Any], view: sublime.View) -> 'Request':
return Request("textDocument/semanticTokens/full/delta", params, view)

@classmethod
def semanticTokensRange(cls, params: Mapping[str, Any], view: sublime.View) -> 'Request':
return Request("textDocument/semanticTokens/range", params, view)

@classmethod
def resolveCompletionItem(cls, params: CompletionItem, view: sublime.View) -> 'Request':
return Request("completionItem/resolve", params, view)
Expand Down
Loading