Skip to content

Rework to support "main" treesitter branch - #55

Open
dtor wants to merge 21 commits into
RRethy:masterfrom
dtor:main
Open

Rework to support "main" treesitter branch#55
dtor wants to merge 21 commits into
RRethy:masterfrom
dtor:main

Conversation

@dtor

@dtor dtor commented Mar 1, 2026

Copy link
Copy Markdown

I see there are already a couple of pull requests to adopt textsubjects to the main branch of treesitter (#53, #54)... They are trying to reimplement "make-range!" functionality that was removed form treesitter.

This pull request is more comprehensive rewrite of the textsubjects project, leveraging quantified captures supported by the newer treesitter. It also rearranges the plugin structure to be more straightforward, and makes several optimizations and enhancements.

Of note there is a commit improving the inner selection by leveraging new @range.extended capture that was added to a number of queries. It ensures that inner container selection works properly even when cursor is just outside the inner block. Situation like this:

for (i = 0; i < n; i++) {
<c> statement_1;
    statement_2;
    statement_3;
}

<c> represents the cursor.

Please take a look.

dtor added 21 commits January 14, 2026 17:45
In preparation to move to the 'main' branch of nvim-treesitter, which
requires newer version of neovim and does not have
nvim-treesitter.define_modules interface, remove code using it.
In preparation to move to the 'main' branch of nvim-treesitter, remove
the dependency on nvim-treesitter.configs module that was removed from
treesitter on the main branch, and leave only support for configuration
private to nvim-treesitter-textsubjects plugin.
Since Neovim 0.7, vim.keymap.set() is the preferred API because it
accepts Lua functions directly as the callback, avoiding the string
serialization overhead and quoting issues.
In preparation to using 'main' treesitter branch where 'parsers' module
has been removed, replace parsers.get_buf_lang() with call to
vim.treesitter.language.get_lang() and replace parsers.has_parser() with
call to vim.treesitter.language.add() which is the recommended way for
testing whether a parser is available.
Rework plugin structure to keep all lua files under
lua/nvim-treesitter-textsubjects/... and make init.lua as the entry
point of the plugin.
Add stylua.toml matching majority of the existing code to ensure
consistency.
In preparation to using 'main' treesitter branch where 'ts_utils' module
has been removed, iprovide a replacement for its update_selection()
method.
In preparation to using 'main' treesitter branch where 'query' module
has been removed, replace queries.has_query_files() and
queries.get_query() with suitable methods from vim.treesitter.query
module, and replace queries.get_capture_matches_recursively() with
local implementation.
Update all queries to use quantified captures instead of "#make-range!"
directive that is no longer available in nvim-treesitter.
Adds inner container queries for if, elseif, else, while, for, repeat,
and do blocks, using correct field names (consequence/body).

Groups related patterns for clarity.
Define "setup" as an alias for configure() method so that lazy.nvim can
automatically apply user configuration from the plugin specification if
specified.
Instead of selecting from start to end and then swapping the anchor
extra time, select from the end upwards.
The conversion from "make-range" to quantative captures intriduced
regressions in incremental selections and handling previous selection,
this fixes them by tracking both original ranges and expanded ranges
that include surrounding whitespace.
To avoid confusion between 0-based treesitter ranges and 1-based cursor
positions introduce Position and Range classes that use 0-based
coordinates and use them throughout.
This simplifies the code by avoiding the need to explicitly exit visual
mode to update the marks and restore visual mode afterwards if we failed
to locate appropriate object.
Add support for supplemental (and optional) @range.extended captures
that help dealing with scenarios when cursor is placed on whitespace
before and after inner blocks.

Adjust C, C++, Go, Lua, and Rust queries to use these new captures.
This allows printing identified matches/ranges for given query.
Implement a per-buffer caching mechanism for Treesitter query results to
improve performance.

Caching is done using a memoize helper borrowed from
nvim-treesitter-textobjects that uses buffer number and Treesitter root
node ID for efficient invalidation.
When the selection trigger is a single point (i.e., the cursor position),
the plugin now uses a 0-width range for the 'strictly surrounds' check.
This allows Tree-sitter nodes that are only 1 character wide to be
selected, as they strictly surround the 0-width point.

Subsequent triggers or existing selections continue to use their full
range, ensuring that 'stepping out' to larger surrounding objects
still works as intended.
The previous logic failed to extend to a blank line below the selection if
the selection started on the first line of the file (start_row == 0).

The new logic simplifies the check and correctly prioritizes extending to
one blank line below, falling back to one blank line above if none exists
below, matching standard Vim 'outer' text object behavior regardless of
the block's position in the file.
Implement a new configuration option 'greedy_whitespace' (default: false).
When enabled, the plugin will select all consecutive blank lines both
above and below in line-wise mode, and all surrounding whitespace on the
same lines in character-wise mode.

Also updated README.md with configuration examples for the new option
and showing how to add descriptions to keymaps.
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