Skip to content

feat: handle corner case of IDE selecting an item#2300

Draft
Myriad-Dreamin wants to merge 5 commits intomainfrom
adj-expr-classify
Draft

feat: handle corner case of IDE selecting an item#2300
Myriad-Dreamin wants to merge 5 commits intomainfrom
adj-expr-classify

Conversation

@Myriad-Dreamin
Copy link
Owner

@Myriad-Dreamin Myriad-Dreamin commented Dec 8, 2025

If the item before and after the cursor are both valid language items. We prefer to select the previous one. e.g. @a:1|@b:1, we select the @a:1.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Myriad-Dreamin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces significant improvements to the IDE's understanding and manipulation of language items, particularly labels and content references. It refines how these items are identified, resolved, and renamed, addressing corner cases and enhancing the overall developer experience. The changes include more precise span handling, enabling renaming for previously unsupported declaration types, and providing clearer feedback to the user through LSP change annotations for refactoring operations.

Highlights

  • Enhanced Label and Content Reference Resolution: The system now more robustly identifies and resolves related Label and ContentRef declarations, improving the accuracy of language features like 'Go to Definition' and 'Find References'.
  • Precise Span Handling for References: The extraction of spans for references has been refined, specifically for RefMarker within ast::Ref nodes, leading to more accurate highlighting and manipulation of reference locations.
  • Introduction of Label Renaming Functionality: The ability to rename Var, Label, and ContentRef declarations has been added, significantly expanding the IDE's refactoring capabilities for these language items.
  • LSP Change Annotations for Renames: Label renames now utilize LSP ChangeAnnotations, allowing clients to present these changes to the user with an option for confirmation, especially for potentially fuzzy or broad refactorings.
  • Improved Syntax Error Handling: A new contains_error method has been added to SyntaxClass to detect error nodes, preventing renaming operations on invalid syntax and improving overall stability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces label renaming and improves reference handling for labels and content references. The changes are a good step forward for IDE support. However, I've identified a couple of critical issues in the implementation that need to be addressed. Specifically, the logic for determining the rename range for references is incorrect, and the span calculation for content references will lead to incorrect highlighting. I've provided detailed suggestions to fix these issues. Additionally, there's a minor wording improvement for a user-facing message.

Comment on lines +45 to +55
let mut node = syntax.node().clone();
if matches!(node.kind(), SyntaxKind::Ref) {
let marker = node
.children()
.find(|child| child.kind() == SyntaxKind::RefMarker)?;
node = marker;
}
let mut range = node.range();
if matches!(node.kind(), SyntaxKind::RefMarker) {
range.start += 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The logic for determining the range for a rename operation on a Ref seems incorrect. It currently finds the RefMarker (@) and adjusts its range, which will not cover the identifier that needs to be renamed.

To fix this, you should find the identifier node within the Ref and use its range directly. This will ensure that the rename UI is anchored to the correct part of the code.

        let range = if syntax.node().kind() == SyntaxKind::Ref {
            syntax
                .node()
                .children()
                .find(|child| matches!(child.kind(), SyntaxKind::Ident | SyntaxKind::Label))
                .map(|ident_node| ident_node.range())
                .unwrap_or_else(|| syntax.node().range())
        } else {
            syntax.node().range()
        };

Comment on lines +576 to +584
at: {
let marker_span = ident
.to_untyped()
.children()
.find(|child| child.kind() == SyntaxKind::RefMarker)
.map(|child| child.span());

marker_span.unwrap_or(ident.span())
},
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The logic to determine the span for a ContentRef seems to be targeting the RefMarker (@), which is likely incorrect. The span should probably cover the identifier part of the reference to ensure correct behavior for features like 'find references' and 'rename'.

By storing the span of the identifier itself, you'll get more accurate ranges for highlighting and editing. With this change, you'll also need to update references.rs to remove the adjustment for ContentRef (i.e., change Some((1, 0)) to None), as the span will now be correct.

Suggested change
at: {
let marker_span = ident
.to_untyped()
.children()
.find(|child| child.kind() == SyntaxKind::RefMarker)
.map(|child| child.span());
marker_span.unwrap_or(ident.span())
},
at: {
let ident_span = ident
.to_untyped()
.children()
.find(|child| matches!(child.kind(), SyntaxKind::Ident | SyntaxKind::Label))
.map(|child| child.span());
ident_span.unwrap_or(ident.span())
},

let change_annotations = Some(create_change_annotation(
change_id,
true,
Some("The language server fuzzy searched the labels".to_string()),
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The description for the rename annotation is a bit misleading. It's not a fuzzy search, but a precise search for all references to the label. A more accurate description would be clearer for the user.

Suggested change
Some("The language server fuzzy searched the labels".to_string()),
Some("Renaming this label will affect all its references.".to_string()),

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

Comments