From 08d137e8b4b14f48e956c84d3c73caeb0af5bcb1 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Thu, 26 Feb 2026 18:15:51 -0500 Subject: [PATCH] docs(textobj): add mini.ai integration recipe to vimdoc 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. --- doc/pending.txt | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/doc/pending.txt b/doc/pending.txt index be369b5..84d3d1e 100644 --- a/doc/pending.txt +++ b/doc/pending.txt @@ -644,6 +644,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*