A utility plugin for those who write their own neovim config, and want to write some complex textobject related movements.
- Chain/Pipping - Chain methods to create complex keymaps with minimal boilerplate
- Convenient defaults - Common textobject patterns (around/inner/next/prev) with out-of-the-box defaults
- Group prefixes - Organize related motions under a single key prefix
- Flexible overrides - Override any default on a per-keymap basis
-- 1. Require and create instance with a prefix for grouped keymaps
local keysitter = require 'keysitter'
local tsto = keysitter.new('treesitter-textobjects', { group_prefix = 'o' })
-- 2. Setup autocommand to define keymaps
tsto.setup({ 'FileType', 'BufEnter' }, 'keysitter', function()
-- 3. Chain methods to create keymaps
tsto:set('f', 'function'):around():inner():next():prev()
end, { desc = 'Set keysitter keymaps' })
-- Result: vaof, viof, ]of, ]oF, [of, [oFThis plugin is made to simplify writing complex keymaps for selecting/jumping textobjects, while also perform some checks and simple logical guards. And it's designed to be used in association with other plugins.
Note
Currently, 'nvim-treesitter-textobjects' is the only supported plugin. But if you find it useful and need it to support other plugins then let me know, I'll try my best to add it.
local keysitter = require 'keysitter'
local tsto = keysitter.new('treesitter-textobjects', { group_prefix = 'o' })
-- a setup function for the group, a new group requires a new setup.
tsto.setup({ 'FileType', 'BufEnter' }, 'keysitter', function()
-- the following will set:
tsto:set('f', 'function')
:around() -- `vaof` for visual-select around a function
:inner() -- `viof` for visual-select inner function
:next() -- `]of` and `]oF` for jumping to the next start & end of a function
:prev() -- `[of` and `[oF` for jumping to the previous start & end of a function
-- notice how all keymaps are _prefixed_ with `o`, and it will continue unless its overridden per method.
tsto
:set('=', 'assignment') -- setting new keymaps
:around() -- `vao=` for visual-select around an assignment
-- for inner, we want to target the right-hand-side of the assignment
:inner({ attribute = 'rhs' }) -- `vio=` for visual-select inner (rhs) assignment
-- next & prev methods are only for convenience, and you can split their functionality
:next_start({ attribute = 'lhs' })
:previous_start({ attribute = 'lhs' })
:next_start({ attribute = 'rhs', key = '-' }, { desc = 'next rhs assignment' })
:previous_start({ attribute = 'rhs', key = '-' }, { desc = 'previous rhs assignment' })
-- or some complex mapping
tsto
:set('c', 'class')
:around() -- `vaoc` for visual-select around a class
:inner() -- `vioc` for visual-select inner class
:next_start({ motion = ']', group_prefix = '', key = ']' }) -- ']]' for next class start
:next_end({ motion = ']', group_prefix = '', key = '[' }) -- '][' for next class end
:previous_start({ motion = '[', group_prefix = '', key = '[' }) -- '[[' for prev class start
:previous_end({ motion = '[', group_prefix= '', key = ']' }) -- '[]' for next class end
end, { desc = 'Set keysitter keymaps for nvim-treesitter-textobjects' })-
Import/require the plugin
-
Use
setupmethod to setup theKeysitterinstance for keymap setting. -
Use the
callbackwithinsetupmethod to define a function that sets keymaps.- Use
setmethod to define targeted textobject (e.g., "function", "class") and associated primary key (e.g., "f", "c") - Use methods like
around,inner,next,prev, etc.
- Use
- neovim >= 0.11.0
- 'nvim-treesitter-textobjects'
Requires nvim >= 0.12
vim.pack.add {
-- make sure you already have those dependencies installed
{ src = 'https://github.com/nvim-treesitter/nvim-treesitter'},
{ src = 'https://github.com/nvim-treesitter/nvim-treesitter-textobjects'},
{ src = 'https://github.com/ABDsheikho/nvim-keysitter' },
}
-- now you can use it as any other plugin/module
local keysitter = require 'keysitter'
local tsto = keysitter.new('treesitter-textobjects', { group_prefix = 'o' })
-- setup function, see [setup](#setup)
tsto.setup({ 'FileType', 'BufEnter' }, 'keysitter', function()
-- your keymaps go here
tsto:set('f', 'function'):around():inner():next():prev()
end, { desc = 'Set keysitter keymaps for nvim-treesitter-textobjects' }){
'nvim-treesitter/nvim-treesitter-textobjects',
branch = 'main',
dependencies = {
{
'ABDsheikho/nvim-keysitter',
config = function()
local keysitter = require 'keysitter'
local tsto = keysitter.new('treesitter-textobjects', { group_prefix = 'o' })
-- setup function, see [setup](#setup)
tsto.setup({ 'FileType', 'BufEnter' }, 'keysitter', function()
-- your keymaps go here
tsto:set('f', 'function'):around():inner():next():prev()
end, { desc = 'Set keysitter keymaps for nvim-treesitter-textobjects' })
end,
},
},
-- the rest of nvim-treesitter-textobject
}{
'ABDsheikho/nvim-keysitter',
dependencies = {
'nvim-treesitter/nvim-treesitter',
'nvim-treesitter/nvim-treesitter-textobjects',
},
config = function()
local keysitter = require 'keysitter'
local tsto = keysitter.new('treesitter-textobjects', { group_prefix = 'o' })
-- setup function, see [setup](#setup)
tsto.setup({ 'FileType', 'BufEnter' }, 'keysitter', function()
-- your keymaps go here
tsto:set('f', 'function'):around():inner():next():prev()
end, { desc = 'Set keysitter keymaps for nvim-treesitter-textobjects' })
end,
}- key (
string): The primary key for keymap - object (
string): The textobject name (e.g., "function", "class") - group_prefix (
string): optional Prefix for the keymap group, good for grouping multiple related motions under one key/prefix. (default to "")
- group_prefix (
string): optional Prefix for the keymap group, good for grouping multiple related motions under one key/prefix. (default to "")
- mode (
string|string[]): optional Override the default vim mode(s) for the keymap, see:h vim.keymap.set() - motion (
string): optional Override the main motion used to target the textobject while visual-selection/jumping (e.g., 'a', 'i', ']', '[' ) - key (
string): optional Override the primary key for the keymap - group_prefix (
string): optional Override the group prefix for the keymap - attribute (
keysitter.Attribute): optional Attribute for the textobject node (e.g., "outer", "inner", "rhs", "lhs", etc.) - callback (
function): optional Optional callback to execute instead of default action
Alias for vim.keymap.set.Opts see :h vim.keymap.set()
Create a new Keysitter instance for the specified textobject-module.
param:
- txtobj_module (
keysitter.TextObjectModule): The name of the textobject group (e.g., "treesitter-textobjects") - opts (
keysitter.GroupOpts): optional Optional group-configuration options
return:
- A Keysitter instance (
keysitter.Keysitter)
Delegates setup to the loaded Keysitter module. Allows modules to configure their own autocommands and callbacks.
param:
- event (
string|string[]): List of Neovim event(s) that will trigger the handler, see:h nvim_create_autocmd() - group (
string): Name or id of the autocommand group to match against - callback (
function|string): Callable function for the autocommand - opts (
keysitter.SetupOpts): optional Module-specific options
Note
Currently (with the only usage of nvim-treesitter-textobject) this function acts as a wrapper
for only nvim_create_autocmd & nvim_create_augroup as a simpler form. And it can be replaced
by a snippet like: (compare it to example)
vim.api.nvim_create_autocmd({ 'FileType', 'BufEnter' }, {
desc = 'Set keysitter keymaps for nvim-treesitter-textobjects'
group = vim.api.nvim_create_augroup('keysitter', { clear = true }),
callback = function()
-- this part is where you use Keysitter-instance to define keymaps.
tsto:set('f', 'function'):around():inner():next():prev()
end,
})Create a keymap for selecting the outer textobject, including its boundaries (full scope).
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create a keymap for selecting the inner textobject, excluding its boundaries (inner scope).
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create keymaps for moving to both the start and end of the next textobject.
Convenient method that chains next_start() and next_end().
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create keymaps for moving to both the start and end of the previous textobject.
Convenient method that chains previous_start() and previous_end().
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create keymaps for moving to the start of the next and previous textobject.
Convenient method that chains next_start() and previous_start().
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create keymaps for moving to the end of the next and previous textobject.
Convenient method that chains next_end() and previous_end().
Only available if the textobject-module supports end for its textobjects.
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create a keymap for moving to the start of the next textobject.
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create a keymap for moving to the end of the next textobject. Only available if the textobject-module supports end for its textobjects.
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create a keymap for moving to the start of the previous textobject.
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
Create a keymap for moving to the end of the previous textobject. Only available if the textobject-module supports end for its textobjects.
param:
- opts (
keysitter.KeymapOpts): optional User options (overrides defaults) - vim_opts (
keysitter.VimKeymapOpts): optional options forvim.keymap.set(), see:h vim.keymap.set()
return:
- A Keysitter instance (
keysitter.Keysitter)
- make
swapfunctionality fornvim-treesitter-textobjects. - check for other potential plugins (maybe
gitsings?).
My main motivation was to write something for nvim-treesitter/nvim-treesitter-textobjects
that simplifies my config, which led me to separate it into its own plugin.
Thanks to them for their incredible work.
Licensed under the Apache License, Version 2.0. See LICENSE for details.