docs(textobj): add mini.ai integration recipe to vimdoc (#44)

Problem: users with mini.ai installed find that buffer-local `at`, `it`,
`aC`, `iC` text objects never fire because mini.ai intercepts `a`/`i` as
single-key handlers in operator-pending/visual modes before Neovim's
mapping system can route them to buffer-local maps.

Solution: add a *pending-mini-ai* recipe section to the RECIPES block in
pending.txt. The recipe explains the conflict, describes mini.ai's
custom_textobjects spec (`{ from = {line,col}, to = {line,col} }`), and
shows how to wrap `textobj.inner_task_range` and `textobj.category_bounds`
(the two functions that return positional data) into the shape mini.ai
expects, registered via `vim.b.miniai_config` in a FileType autocmd. Notes
that `aC` cannot be expressed this way due to its linewise selection, and
that the built-in keymaps work fine for users without mini.ai.
This commit is contained in:
Barrett Ruth 2026-02-26 18:30:14 -05:00 committed by GitHub
parent dcb6a4781d
commit 994294393c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -709,6 +709,77 @@ Event-driven statusline refresh: >lua
})
<
mini.ai integration: ~ *pending-mini-ai*
mini.ai (from mini.nvim) maps `a` and `i` as single-key handlers in
operator-pending and visual modes. It captures the next keystroke internally
rather than routing it through Neovim's mapping system, which means the
buffer-local `at`, `it`, `aC`, and `iC` maps never fire for users who have
mini.ai installed.
The fix is to register pending.nvim's text objects as mini.ai custom
textobjects via `vim.b.miniai_config` in a `FileType` autocmd. mini.ai's
`custom_textobjects` spec expects each entry to be a function returning
`{ from = { line, col }, to = { line, col } }` (1-indexed, col is
byte-offset from 1).
pending.nvim's `textobj.inner_task_range(line)` returns the start and end
column offsets within the current line. Combine it with the cursor row and
the buffer line to build the region tables mini.ai expects: >lua
vim.api.nvim_create_autocmd('FileType', {
pattern = 'pending',
callback = function()
local function task_inner()
local textobj = require('pending.textobj')
local row = vim.api.nvim_win_get_cursor(0)[1]
local line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
if not line then return end
local s, e = textobj.inner_task_range(line)
if s > e then return end
return { from = { line = row, col = s }, to = { line = row, col = e } }
end
local function category_inner()
local textobj = require('pending.textobj')
local buffer = require('pending.buffer')
local meta = buffer.meta()
if not meta then return end
local row = vim.api.nvim_win_get_cursor(0)[1]
local header_row, last_row = textobj.category_bounds(row, meta)
if not header_row then return end
local first_task, last_task
for r = header_row + 1, last_row do
if meta[r] and meta[r].type == 'task' then
if not first_task then first_task = r end
last_task = r
end
end
if not first_task then return end
local first_line = vim.api.nvim_buf_get_lines(0, first_task - 1, first_task, false)[1] or ''
local last_line = vim.api.nvim_buf_get_lines(0, last_task - 1, last_task, false)[1] or ''
return {
from = { line = first_task, col = 1 },
to = { line = last_task, col = #last_line },
}
end
vim.b.miniai_config = {
custom_textobjects = { t = task_inner, C = category_inner },
}
end,
})
<
Note that the default `keymaps.a_task = 'at'` and friends still work in
standard Neovim operator-pending mode for users who do not have mini.ai. The
`vim.b.miniai_config` block is only needed when mini.ai is active.
`aC` (outer category) is not exposed here because mini.ai does not support
the linewise selection that `aC` requires. Use the buffer-local `aC` key
directly, or disable `a_category` in `keymaps` and handle it via a
`vim.b.miniai_config` entry that returns a linewise region if mini.ai's
spec allows it in your version.
==============================================================================
GOOGLE CALENDAR *pending-gcal*