{"id":19638973,"url":"https://github.com/savetheclocktower/symbol-provider-tree-sitter","last_synced_at":"2026-07-12T12:32:14.146Z","repository":{"id":160139390,"uuid":"635082967","full_name":"savetheclocktower/symbol-provider-tree-sitter","owner":"savetheclocktower","description":"Provides symbols to symbols-view based on Tree-sitter queries","archived":false,"fork":false,"pushed_at":"2023-12-30T08:39:09.000Z","size":88,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-09T13:34:13.743Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/savetheclocktower.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-01T23:41:13.000Z","updated_at":"2023-05-01T23:43:41.000Z","dependencies_parsed_at":"2023-12-30T09:28:43.440Z","dependency_job_id":null,"html_url":"https://github.com/savetheclocktower/symbol-provider-tree-sitter","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/savetheclocktower/symbol-provider-tree-sitter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/savetheclocktower%2Fsymbol-provider-tree-sitter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/savetheclocktower%2Fsymbol-provider-tree-sitter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/savetheclocktower%2Fsymbol-provider-tree-sitter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/savetheclocktower%2Fsymbol-provider-tree-sitter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/savetheclocktower","download_url":"https://codeload.github.com/savetheclocktower/symbol-provider-tree-sitter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/savetheclocktower%2Fsymbol-provider-tree-sitter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35392296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T12:43:24.306Z","updated_at":"2026-07-12T12:32:14.129Z","avatar_url":"https://github.com/savetheclocktower.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# symbol-provider-tree-sitter package\n\nProvides symbols to `symbols-view` via Tree-sitter queries.\n\nTree-sitter grammars [with tags queries](https://tree-sitter.github.io/tree-sitter/code-navigation-systems) can very easily give us a list of all the symbols in a file without the drawbacks of a `ctags`-based approach. For instance, they operate on the contents of the buffer, not the contents of the file on disk, so they work just fine in brand-new files and in files that have been modified since the last save.\n\nThis provider does not currently support project-wide symbol search, but possibly could do so in the future.\n\n## Tags queries\n\nThis provider expects for a grammar to have specified a tags query in its grammar definition file. All the built-in Tree-sitter grammars will have such a file. If you’re using a third-party Tree-sitter grammar that hasn’t defined one, file an issue on Pulsar and we’ll see what we can do.\n\nIf you’re writing your own grammar, or contributing a `tags.scm` to a grammar without one, keep reading.\n\n### Query syntax\n\nThe query syntax starts as a subset of what is described [on this page](https://tree-sitter.github.io/tree-sitter/code-navigation-systems). Here’s what this package can understand:\n\n* A query that consists of a `@definition.THING` capture with a `@name` capture inside will properly be understood as a symbol with a tag corresponding to `THING` and a name corresponding to the `@name` capture’s text.\n* A query that consists of a `@reference.THING` capture with a `@name` capture inside will be ignored by default. If the proper setting is enabled, each of these references will become a symbol with a tag corresponding to `THING` and a name corresponding to the `@name` capture’s text.\n* All other `@name` captures that are not within either a `@definition` or a `@reference` will be considered as a symbol in isolation. (These symbols can still specify a tag via a `#set!` predicate.)\n\nTo match the current behavior of the `symbols-view` package, you can usually take a `queries/tags.scm` file from a Tree-sitter repository — many parsers define them — and paste it straight into your grammar’s `tags.scm` file.\n\n#### Advanced features\n\nThe text of the captured node is what will be displayed as the symbol’s name, but a few predicates are available to alter that field and others. Symbol predicates use `#set!` and the `symbol` namespace.\n\n##### Node position descriptors\n\nSeveral predicates take a **node position descriptor** as an argument. It’s a string that resembles an object lookup chain in JavaScript:\n\n```scm\n(#set! symbol.prependTextForNode parent.parent.firstNamedChild)\n```\n\nStarting at the captured node, it describes a path to take within the tree in order to get to another meaningful node.\n\nIn all these examples, if the descriptor is invalid and does not return a node, the predicate will be ignored.\n\n##### Changing the symbol’s name\n\nThere are several ways to add text to the beginning or end of the symbol’s name:\n\n###### symbol.prepend\n\n```scm\n(class_declaration\n  name: (identifier) @name\n  (#set! symbol.prepend \"Class: \"))\n```\n\nThe `symbol.prepend` predicate adds a constant string to the beginning of a symbol name. For a class `Foo` in JavaScript, this predicate would result in a symbol called `Class: Foo`.\n\n###### symbol.append\n\n```scm\n(class_declaration\n  name: (identifier) @name\n  (#set! symbol.append \" (class)\"))\n```\n\nThe `symbol.append` predicate adds a constant string to the end of a symbol name. For a class `Foo`, this predicate would result in a symbol called `Foo (class)`.\n\n\n###### symbol.strip\n\n```scm\n(class_declaration\n  name: (identifier) @name\n  (#set! symbol.strip \"^\\\\s+|\\\\s+$\"))\n```\n\nThe `symbol.strip` predicate will replace everything matched by the regular expression with an empty string. The pattern given is compiled into a JavaScript `RegExp` with an implied `g` (global) flag.\n\nIn this example, _if_ the `identifier` node included whitespace on either side of the symbol, the symbol’s name would be stripped of that whitespace before being shown in the UI.\n\n###### symbol.prependTextForNode\n\n```scm\n(class_body (method_definition\n  name: (property_identifier) @name\n  (#set! symbol.prependTextForNode \"parent.parent.previousNamedSibling\")\n  (#set! symbol.joiner \"#\")\n))\n```\n\nThe `symbol.prependTextForNode` predicate will look up the text of the node referred to by the provided _node position descriptor_, then prepend that text to the symbol name. If `symbol.joiner` is provided, it will be inserted in between the two.\n\nIn this example, a `bar` method on a class named `Foo` would have a symbol name of `Foo#bar`.\n\n###### symbol.prependSymbolForNode\n\n```scm\n(class_body (method_definition\n  name: (property_identifier) @name\n  (#set! symbol.prependSymbolForNode \"parent.parent.previousNamedSibling\")\n  (#set! symbol.joiner \"#\")\n))\n```\n\nThe `symbol.prependSymbolForNode` predicate will look up the symbol name of the node referred to by the provided _node position descriptor_, then prepend that name to the symbol name. If `symbol.joiner` is provided, it will be inserted in between the two.\n\nUnlike `symbol.prependTextForNode`, the node referred to with the descriptor must have its own symbol name, and it must have been processed already — that is, it must be a symbol whose name was determined earlier than that of the current node.\n\nThis allows us to incorporate any transformations that were applied to the other node’s symbol name. We can use this to build “recursive” symbol names — for instance, JSON keys whose symbols consist of their entire key path from the root.\n\n##### Adding the `context` field\n\nThe `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.\n\n###### symbol.contextNode\n\n```scm\n(class_body (method_definition\n  name: (property_identifier) @name\n  (#set! symbol.contextNode \"parent.parent.previousNamedSibling\")\n))\n```\n\nThe `symbol.contextNode` predicate will set the value of a symbol’s `context` property to the text of a node based on the provided _node position descriptor_.\n\n###### symbol.context\n\n```scm\n(class_body (method_definition\n  name: (property_identifier) @name\n  (#set! symbol.context \"class\")\n))\n```\n\nThe `symbol.context` predicate will set the value of a symbol’s `context` property to a fixed string.\n\nThe point of `context` is to provide information to help you tell symbols apart, so you probably don’t want to set it to a fixed value. But this predicate is available just in case.\n\n##### Adding a tag\n\nThe `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.\n\nThe 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…\n\n```scm\n(assignment_expression\n  left: [\n    (identifier) @name\n    (member_expression\n      property: (property_identifier) @name)\n  ]\n  right: [(arrow_function) (function)]\n) @definition.function\n```\n\n…the resulting symbol will infer a `tag` value of `function`.\n\nIn cases where this is impractical, you can provide the tag explicitly with a predicate.\n\n###### symbol.tag\n\n```scm\n(class_body (method_definition\n  name: (property_identifier) @name\n  (#set! symbol.tag \"class\")\n))\n```\n\nThe `symbol.tag` predicate will set the value of a symbol’s `tag` property to a fixed string.\n\nThe `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`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsavetheclocktower%2Fsymbol-provider-tree-sitter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsavetheclocktower%2Fsymbol-provider-tree-sitter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsavetheclocktower%2Fsymbol-provider-tree-sitter/lists"}