Skip to content

Fix LSP go-to-definition for command aliases#322

Open
kindermax wants to merge 2 commits intomasterfrom
codex/fix-lsp-goto-def-on
Open

Fix LSP go-to-definition for command aliases#322
kindermax wants to merge 2 commits intomasterfrom
codex/fix-lsp-goto-def-on

Conversation

@kindermax
Copy link
Copy Markdown
Collaborator

@kindermax kindermax commented Mar 26, 2026

  • Summary
    • teach the LSP parser to recognize alias positions (e.g., <<: *foo) and extract the referenced command name
    • route go-to-definition requests over alias positions to the matching command definition and note the behavior in the changelog
  • Testing
    • Not run (not requested)

Summary by Sourcery

Improve LSP go-to-definition support for command references in YAML configs.

Bug Fixes:

  • Enable go-to-definition from YAML merge alias references like <<: *test to jump to the corresponding command definition in lets self lsp.

Enhancements:

  • Unify command reference extraction for depends entries and command aliases in the LSP parser.

Documentation:

  • Document the improved go-to-definition behavior for YAML merge aliases in the changelog.

Tests:

  • Add parser and handler tests covering detection of command alias positions, extraction of command references, and resolving command definitions via aliases.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 26, 2026

Reviewer's Guide

Teach the LSP to recognize YAML merge alias positions (e.g., <<: *foo) as command references and route go-to-definition through a new parser path that resolves the underlying command name, with tests and changelog entry.

Sequence diagram for LSP go-to-definition on YAML command alias

sequenceDiagram
  actor Editor
  participant LSPClient
  participant lspServer
  participant definitionHandler
  participant parser
  participant TreeSitter

  Editor->>LSPClient: go to definition at position (alias *foo)
  LSPClient->>lspServer: textDocument/definition(params)

  lspServer->>parser: getPositionType(doc, position)
  parser->>TreeSitter: parseYAMLDocument(doc)
  TreeSitter-->>parser: tree, docBytes
  parser->>parser: inMixinsPosition?
  parser-->>lspServer: PositionTypeCommandAlias

  lspServer->>definitionHandler: findCommandDefinition(doc, params)

  definitionHandler->>parser: extractCommandReference(doc, position)
  activate parser
  parser->>parser: extractDependsCommandReference(doc, position)
  parser->>TreeSitter: parseYAMLDocument(doc)
  TreeSitter-->>parser: tree, docBytes
  parser->>parser: query depends references
  parser-->>parser: "" (no match)

  parser->>parser: extractAliasCommandReference(doc, position)
  parser->>TreeSitter: parseYAMLDocument(doc)
  TreeSitter-->>parser: tree, docBytes
  parser->>parser: query merge alias <<: *foo
  parser-->>definitionHandler: commandName "foo"
  deactivate parser

  definitionHandler->>parser: findCommand(doc, commandName)
  parser-->>definitionHandler: Command{name: foo}
  definitionHandler-->>lspServer: location of command foo
  lspServer-->>LSPClient: definition Location
  LSPClient-->>Editor: jump cursor to command foo definition
Loading

Class diagram for updated LSP parser and definition handling

classDiagram
  class parser {
    +getPositionType(document *string, position lsp_Position) PositionType
    +inDependsPosition(document *string, position lsp_Position) bool
    +inCommandAliasPosition(document *string, position lsp_Position) bool
    +extractCommandReference(document *string, position lsp_Position) string
    +extractDependsCommandReference(document *string, position lsp_Position) string
    +extractAliasCommandReference(document *string, position lsp_Position) string
    +findCommand(document *string, name string) *Command
  }

  class definitionHandler {
    -parser *parser
    +findMixinsDefinition(doc *string, params *lsp_DefinitionParams) any
    +findCommandDefinition(doc *string, params *lsp_DefinitionParams) (any, error)
  }

  class lspServer {
    -parser *parser
    -definitionHandler *definitionHandler
    +textDocumentDefinition(context *glsp_Context, params *lsp_DefinitionParams) (any, error)
  }

  class Command {
    -name string
  }

  class PositionType {
    <<enumeration>>
    PositionTypeMixins
    PositionTypeDepends
    PositionTypeCommandAlias
    PositionTypeNone
  }

  parser --> Command : uses
  definitionHandler --> parser : composes
  lspServer --> parser : has
  lspServer --> definitionHandler : has
  parser --> PositionType : returns
  definitionHandler --> Command : returns location of
  lspServer --> Command : via definitionHandler
Loading

File-Level Changes

Change Details Files
Add detection of command alias positions in the YAML LSP parser and expose them as a distinct position type.
  • Extend PositionType enum with a command-alias variant and wire it into getPositionType.
  • Implement inCommandAliasPosition using a Tree-sitter query that matches <<: *alias mappings and checks cursor containment.
  • Add unit tests covering cursor positions inside and outside the alias token and verifying getPositionType returns the new alias type.
internal/lsp/treesitter.go
internal/lsp/treesitter_test.go
Unify command reference extraction logic to support both depends arrays and alias-based references for go-to-definition.
  • Introduce extractCommandReference, delegating to depends and alias-specific helpers.
  • Refactor existing depends extraction into extractDependsCommandReference with a Tree-sitter query for block and flow sequences.
  • Add extractAliasCommandReference that matches merge alias nodes, trims the * marker, and returns the underlying anchor name.
  • Add tests verifying reference extraction for block depends, flow depends, alias star, alias name, and non-reference positions.
internal/lsp/treesitter.go
internal/lsp/treesitter_test.go
Route go-to-definition for command references (depends and aliases) through the new extraction logic and document the behavior.
  • Update findCommandDefinition to rely on extractCommandReference instead of line/word-based parsing.
  • Extend textDocumentDefinition to treat command alias positions like depends positions for command resolution.
  • Add an integration-style test ensuring go-to-definition from an alias location returns the referenced command location.
  • Add a changelog entry describing the fixed go-to-definition behavior for YAML merge aliases.
internal/lsp/handlers.go
internal/lsp/treesitter_test.go
docs/docs/changelog.md

Possibly linked issues

  • #: PR adds parser and handler logic so go-to-definition on <<: *test jumps to the test command.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Both extractDependsCommandReference and extractAliasCommandReference (and inCommandAliasPosition) repeat the same parse/query/match boilerplate; consider extracting a small helper to reduce duplication and make future YAML query changes easier.
  • The go-to-definition path now reparses the YAML multiple times per request (e.g., getPositionType and then extractCommandReference); if this becomes hot, consider threading a parsed tree or a lightweight cache through the parser/handler to avoid redundant work.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Both `extractDependsCommandReference` and `extractAliasCommandReference` (and `inCommandAliasPosition`) repeat the same parse/query/match boilerplate; consider extracting a small helper to reduce duplication and make future YAML query changes easier.
- The go-to-definition path now reparses the YAML multiple times per request (e.g., `getPositionType` and then `extractCommandReference`); if this becomes hot, consider threading a parsed tree or a lightweight cache through the parser/handler to avoid redundant work.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant