Skip to content

Conversation

@benodiwal
Copy link
Contributor

Closes #2103

  • Only create folding range for 2+ consecutive imports
  • Handle multiple import groups separated by non-import declarations
  • Use .inclusive range to include semicolons
  • Added some tests as well

A simple demo to see this feature in action:
Screenshot 2025-11-23 at 2 16 03 AM
Screenshot 2025-11-23 at 2 16 25 AM

@benodiwal
Copy link
Contributor Author

Hey @Techatrix, can u please review this PR. Thanks.

@benodiwal benodiwal force-pushed the feat/folding-range-imports branch from c21183a to 653c9a7 Compare November 25, 2025 18:24
@benodiwal
Copy link
Contributor Author

Hey @Techatrix, is this issue #2103 planned for the next release ?

@benodiwal
Copy link
Contributor Author

ig the checks are failing due to rebase

@benodiwal benodiwal force-pushed the feat/folding-range-imports branch from 653c9a7 to ff08db3 Compare November 27, 2025 16:05
@Techatrix Techatrix force-pushed the feat/folding-range-imports branch from ff08db3 to 9092d20 Compare November 28, 2025 18:45
Copy link
Member

@Techatrix Techatrix left a comment

Choose a reason for hiding this comment

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

This recursively drills down field accesses to find the base.

This doc comment doesn't match the implementation. It's not recursive and doesn't look drill down a sequence of field accesses.

Field accesses should recursively check the left side of the expression. We can also assume that identifiers refer to aliases which should lead to better results than assuming the opposite. In the future, this logic should ideally be shared with code actions.

Here is how this could be implemented (without actual recursion)

fn isImportOrAlias(tree: *const Ast, init_node: Ast.Node.Index) bool {
    var node = init_node;
    while (true) {
        node = switch (tree.nodeTag(node)) {
            .builtin_call_two, .builtin_call_two_comma => {
                // just like before
            },
            .field_access => tree.nodeData(node).node_and_token[0],
            .identifier => return true,
            else => return false,
        };
    }
}

const var_decl = tree.simpleVarDecl(node);
const init_node = var_decl.ast.init_node.unwrap() orelse break :blk false;

// Check if this is an @import() call or a field access/identifier based on an import
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Check if this is an @import() call or a field access/identifier based on an import

This comment is almost the same as the doc comment of isImportOrAlias so it doesn't carry any additional information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @Techatrix, thanks for the feedback on the PR. Got your point, the earlier implementation seems to be half baked from my side. You're absolutely right that the doc comment didn't match the implementation.

I implemented your suggestion, and it works much better. However, I'm seeing a case where it might create false positives. For example:

  const FoldingRange = struct { ... };  // Local struct
  const std = @import("std");
  const loc = FoldingRange.loc;  // ← Gets included in fold range

Since we assume all identifiers are aliases, FoldingRange.loc gets included even though FoldingRange is a local struct, not an import. Is this trade-off acceptable for the folding range use case, or should we add additional heuristics to filter these out?

Copy link
Member

Choose a reason for hiding this comment

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

I find this trade off acceptable. A future improvement can reuse the logic that is used for code actions.

@benodiwal benodiwal force-pushed the feat/folding-range-imports branch from 9092d20 to 9419f58 Compare November 28, 2025 20:23
@Techatrix Techatrix merged commit c990fe8 into zigtools:master Nov 28, 2025
6 checks passed
llogick pushed a commit to llogick/zls that referenced this pull request Nov 28, 2025
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.

add folding ranges for imports

2 participants