Skip to content

Commit

Permalink
Merge pull request #861 from savetheclocktower/symbols-view-fixes
Browse files Browse the repository at this point in the history
`symbols-view` rolling fixes
  • Loading branch information
savetheclocktower authored Feb 15, 2024
2 parents 732d1d4 + 05de7db commit 114a724
Show file tree
Hide file tree
Showing 13 changed files with 556 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,54 @@
(atx_h1_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "· "))
(#set! symbol.prepend "· ")
(#set! symbol.icon "chevron-right"))

((atx_heading
(atx_h2_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "·· "))
(#set! symbol.prepend "·· ")
(#set! symbol.icon "chevron-right"))

((atx_heading
(atx_h3_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "··· "))
(#set! symbol.prepend "··· ")
(#set! symbol.icon "chevron-right"))

((atx_heading
(atx_h4_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "···· "))
(#set! symbol.prepend "···· ")
(#set! symbol.icon "chevron-right"))

((atx_heading
(atx_h5_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "····· "))
(#set! symbol.prepend "····· ")
(#set! symbol.icon "chevron-right"))

((atx_heading
(atx_h6_marker)
(heading_content) @name) @definition.heading
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "······ "))
(#set! symbol.prepend "······ ")
(#set! symbol.icon "chevron-right"))

((setext_heading
(heading_content) @name) @definition.heading
(setext_h1_underline)
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "· "))
(#set! symbol.prepend "· ")
(#set! symbol.icon "chevron-right"))

((setext_heading
(heading_content) @name) @definition.heading
(setext_h2_underline)
(#set! symbol.strip "(^\\s*|\\s*$)")
(#set! symbol.prepend "·· "))
(#set! symbol.prepend "·· ")
(#set! symbol.icon "chevron-right"))
6 changes: 3 additions & 3 deletions packages/language-php/grammars/tree-sitter/queries/tags.scm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

(namespace_definition
name: (namespace_name) @name) @module
name: (namespace_name) @name) @definition.namespace

(interface_declaration
name: (name) @name) @definition.interface
Expand All @@ -11,7 +11,7 @@
(class_declaration
name: (name) @name) @definition.class

(class_interface_clause [(name) (qualified_name)] @name) @impl
(class_interface_clause [(name) (qualified_name)] @name) @reference.interface

(property_declaration
(property_element (variable_name (name) @name))) @definition.field
Expand Down Expand Up @@ -40,4 +40,4 @@
(member_call_expression
name: (name) @name) @reference.call

(enum_declaration (name) @name) @definition.enum
((enum_declaration (name) @name) @definition.enum)
28 changes: 18 additions & 10 deletions packages/symbol-provider-tree-sitter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ This allows us to incorporate any transformations that were applied to the other

##### Adding the `context` field

The `context` field of a symbol is a short piece of text meant to give context. For instance, a symbol that represents a class method could have a `context` field that contains the name of the owning class. The `context` field is not filtered on.
The `context` field of a symbol is a short piece of text meant to give context. For instance, a symbol that represents a class method could have a `context` field that contains the name of the class it belongs to. The `context` field is not filtered on.

###### symbol.contextNode

Expand Down Expand Up @@ -135,7 +135,11 @@ The point of `context` is to provide information to help you tell symbols apart,

##### Adding a tag

The `tag` field is a string (ideally a short string) that indicates a symbol’s kind or type. A `tag` for a class method’s symbol might say `method`, whereas the symbol for the class itself might have a `tag` of `class`. These tags will be indicated in the UI with a badge or an icon.
The `tag` field is a string that indicates a symbol’s kind or type. It should be a single word wherever possible. A `tag` for a class method’s symbol would typically be `method`, whereas the symbol for the class itself would typically have a `tag` of `class`. These tags will be indicated in the UI with a badge, an icon, or both.

If you’re not sure what to call something, consult [this list from the Language Server Protocol spec](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind). But some symbols may not fit any of those, so ultimately it’s up to the author. (For example, headings in Markdown files are assigned a kind of `heading`.)

For consistency, tags should be all lowercase. The interface will apply its own casing effect through CSS (`text-transform: capitalize` by default, but customizable in UI themes).

The preferred method of adding a tag is to leverage the `@definition.` captures that are typically present in a tags file. For instance, in this excerpt from the JavaScript grammar’s `tags.scm` file…

Expand All @@ -154,28 +158,32 @@ The preferred method of adding a tag is to leverage the `@definition.` captures

In cases where this is impractical, you can provide the tag explicitly with a predicate.

###### symbol.icon
Nearly all the tags on [the aforementioned list](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind) will also apply an appropriate `icon` to their symbol when assigned. If you choose a tag name not on that list, or want to override the default, you can use the `symbol.icon` predicate described below.

###### symbol.tag

```scm
(class_body (method_definition
name: (property_identifier) @name
(#set! symbol.icon "package")
(#set! symbol.tag "class")
))
```

The icon to be shown alongside the symbol in a list. Will only be shown if the user has enabled the “Show Icons in Symbols View” option in the `symbols-view` settings. You can see the full list of available icons by invoking the **Styleguide: Show** command and browsing the “Icons” section. The value can include the preceding `icon-` or can omit it; e.g., `icon-package` and `package` are both valid values.
The `symbol.tag` predicate will set the value of a symbol’s `tag` property to a fixed string.

If this value is omitted, this provider will still attempt to match certain common tag values to icons. If `tag` is not present on the symbol, or is an uncommon value, there will be a blank space instead of an icon.
The `tag` property is used to supply a word that represents the symbol in some way. For conventional symbols, this will often be something like `class` or `function`.

###### symbol.tag
This provider will attempt to match certain common tag values to icons. This can be overridden by specifying an explicit `symbol.icon` value.

###### symbol.icon

```scm
(class_body (method_definition
name: (property_identifier) @name
(#set! symbol.tag "class")
(#set! symbol.icon "package")
))
```

The `symbol.tag` predicate will set the value of a symbol’s `tag` property to a fixed string.
The icon to be shown alongside the symbol in a list. Will only be shown if the user has enabled the “Show Icons in Symbols View” option in the `symbols-view` settings. You can see the full list of available icons by invoking the **Styleguide: Show** command and browsing the “Icons” section. The value can include the preceding `icon-` or can omit it; e.g., `icon-package` and `package` are both valid values.

The `tag` property is used to supply a word that represents the symbol in some way. For conventional symbols, this will often be something like `class` or `function`.
If this value is omitted, this provider will still attempt to match certain common tag values to icons. If `tag` is not present on the symbol, or is an uncommon value, there will be a blank space instead of an icon.
82 changes: 64 additions & 18 deletions packages/symbol-provider-tree-sitter/lib/capture-organizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,66 @@ const PatternCache = {
},
};


// Assign a default icon type for each tag — or what LSP calls “kind.” This
// list is copied directly from the LSP spec's exhaustive list of potential
// symbol kinds:
//
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind
function iconForTag(tag) {
switch (tag) {
case 'function':
return 'icon-gear';
case 'method':
return 'icon-gear';
case 'file':
return 'icon-file';
case 'module':
return 'icon-database';
case 'namespace':
return 'icon-tag';
case 'variable':
return 'icon-code';
case 'class':
case 'package':
return 'icon-package';
case 'constant':
return 'icon-primitive-square';
case 'class':
return 'icon-puzzle';
case 'method':
return 'icon-gear';
case 'property':
return 'icon-primitive-dot';
case 'interface':
return 'icon-key';
case 'field':
return 'icon-primitive-dot';
case 'constructor':
return 'icon-tools';
case 'module':
return 'icon-database';
case 'enum':
return 'icon-list-unordered';
case 'interface':
return 'icon-key';
case 'function':
return 'icon-gear';
case 'variable':
return 'icon-code';
case 'constant':
return 'icon-primitive-square';
case 'string':
return 'icon-quote';
case 'number':
return 'icon-plus';
case 'boolean':
return 'icon-question';
case 'array':
return 'icon-list-ordered';
case 'object':
return 'icon-file-code';
case 'key':
return 'icon-key';
case 'null':
return null;
case 'enum-member':
return 'icon-primitive-dot';
case 'struct':
return 'icon-book';
case 'event':
return 'icon-calendar';
case 'operator':
return 'icon-plus';
case 'type-parameter':
return null;
default:
return null;
}
Expand All @@ -66,9 +104,10 @@ class Container {
this.capture = capture;
this.node = capture.node;
this.organizer = organizer;
this.props = capture.setProperties || {};

this.tag = capture.name.substring(capture.name.indexOf('.') + 1);
this.icon = iconForTag(this.tag);
this.icon = this.resolveIcon();
this.position = capture.node.range.start;
}

Expand Down Expand Up @@ -108,14 +147,21 @@ class Container {
);
}

resolveIcon() {
let icon = this.props['symbol.icon'] ?? iconForTag(this.tag);
if (icon && !icon.startsWith('icon-'))
icon = `icon-${icon}`;
return icon;
}

toSymbol() {
if (!this.nameCapture) return null;
let nameSymbol = this.nameCapture.toSymbol();
let symbol = {
name: nameSymbol.name,
shortName: nameSymbol.shortName,
tag: nameSymbol.tag ?? this.tag,
icon: nameSymbol.icon ?? iconForTag(nameSymbol.tag) ?? iconForTag(this.tag),
icon: nameSymbol.icon ?? this.icon,
position: this.position
};

Expand Down Expand Up @@ -246,11 +292,11 @@ class Name {
}

toSymbol() {
let { name, shortName, position, context, tag } = this;
let symbol = { name, shortName, position };
let { name, shortName, position, context, tag, icon } = this;
let symbol = { name, shortName, position, icon };
if (tag) {
symbol.tag = tag;
symbol.icon = iconForTag(tag);
symbol.icon ??= iconForTag(tag);
}
if (context) symbol.context = context;

Expand Down
Loading

0 comments on commit 114a724

Please sign in to comment.