fix: use visual column instead of byte offset in get_scol() #54
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
The
get_scol()function returns byte-based column (treesitter offset + 1) whilelines.get_start_col()returns visual column with tab expansion.This mismatch causes sibling navigation (Up/Down) to fail when files use tabs for indentation. The column comparison in
get_neighbor_at_same_col()requires exact match (candidate_col == scol), but:get_scol()returns byte column (e.g., 3 for\t\tvar)get_start_col()returns visual column (e.g., 9 with tabstop=4)So siblings at the same indentation are rejected because
9 == 3is false.Interestingly,
get_down_and_in()(Right movement) usescandidate_col > scol, which accidentally passes (9 > 3), making Right work for sibling navigation while Down doesn't.Solution
Change
get_scol()to return the visual column usinglines.get_start_col(), making it consistent with how candidate columns are calculated.Testing
Tested with Go files using tabs for indentation. Before the fix,
j/k(Down/Up) couldn't navigate between sibling statements inside a block. After the fix, sibling navigation works correctly.