From 368a6fcb37acb8faed9fe96f0c4995c7d6d0a402 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Wed, 16 Jul 2025 18:04:44 +0200 Subject: [PATCH] nvim: Add mini.ai textobjects from lazyvim Shamelessly stolen from http://www.lazyvim.org/plugins/coding#miniai, allows us to select in/around: [c]lass, [f]unction, [d]igits, MultiCas[e] words, [g]lobal buffer, [u]sage of functions (function calls) or the last part of a function [Usage] and the current code bl[o]ck (loop, conditional or block). Super useful! --- nvim/.config/nvim/lua/plugins/base.lua | 41 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/nvim/.config/nvim/lua/plugins/base.lua b/nvim/.config/nvim/lua/plugins/base.lua index 7c7e190..cc70347 100644 --- a/nvim/.config/nvim/lua/plugins/base.lua +++ b/nvim/.config/nvim/lua/plugins/base.lua @@ -210,8 +210,45 @@ return { "echasnovski/mini.nvim", event = { "InsertEnter", "VeryLazy" }, config = function() - -- manually create lazy loading scenarios - require("mini.ai").setup() + local ai = require("mini.ai") + local function ai_buffer(ai_type) + local start_line, end_line = 1, vim.fn.line("$") + if ai_type == "i" then + -- Skip first and last blank lines for `i` textobject + local first_nonblank, last_nonblank = vim.fn.nextnonblank(start_line), vim.fn.prevnonblank(end_line) + -- Do nothing for buffer with all blanks + if first_nonblank == 0 or last_nonblank == 0 then + return { from = { line = start_line, col = 1 } } + end + start_line, end_line = first_nonblank, last_nonblank + end + + local to_col = math.max(vim.fn.getline(end_line):len(), 1) + return { from = { line = start_line, col = 1 }, to = { line = end_line, col = to_col } } + end + ai.setup({ + custom_textobjects = { + c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }), -- class + d = { "%f[%d]%d+" }, -- digits + e = { -- single part of MultiCaseWords + { + "%u[%l%d]+%f[^%l%d]", + "%f[%S][%l%d]+%f[^%l%d]", + "%f[%P][%l%d]+%f[^%l%d]", + "^[%l%d]+%f[^%l%d]", + }, + "^().*()$", + }, + f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), -- function + g = ai_buffer, -- buffer with or without whitespace + o = ai.gen_spec.treesitter({ -- current 'codeblock' + a = { "@block.outer", "@conditional.outer", "@loop.outer" }, + i = { "@block.inner", "@conditional.inner", "@loop.inner" }, + }), + u = ai.gen_spec.function_call(), -- function [u]sage + U = ai.gen_spec.function_call({ name_pattern = "[%w_]" }), -- function [U]sage of last dot element + }, + }) -- Align tables and other alignable things require("mini.align").setup({})