nixos/pkgs/nixvim/coding/mini-ai.nix

122 lines
4.5 KiB
Nix

{ ... }:
{
youthlic.plugins.mini-ai = {
enable = true;
luaConfig.pre =
#lua
''
do
local ai = require("mini.ai")
_M.__coding_plugin_mini_ai_opts = {
n_lines = 500,
custom_textobjects = {
o = ai.gen_spec.treesitter({ -- code block
a = { "@block.outer", "@conditional.outer", "@loop.outer" },
i = { "@block.inner", "@conditional.inner", "@loop.inner" },
}),
f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), -- function
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }), -- class
t = { "<([%p%w]-)%f[^<%w][^<>]->.-</%1>", "^<.->().*()</[^/]->$" }, -- tags
d = { "%f[%d]%d+" }, -- digits
e = { -- Word with case
{ "%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]" },
"^().*()$",
},
g = function(ai_type)
local start_line, end_line = 1, vim.fn.line("$")
if ai_type == "i" then
local first_nonblank, last_nonblank = vim.fn.nextnonblank(start_line), vim.fn.prevnonblank(end_line)
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, -- buffer
u = ai.gen_spec.function_call(), -- u for "Usage"
U = ai.gen_spec.function_call({ name_pattern = "[%w_]" }), -- without dot in function name
},
}
end
'';
settings = {
__raw =
#lua
"_M.__coding_plugin_mini_ai_opts";
};
luaConfig.post =
#lua
''
_M.on_load("which-key", function()
local opts = _M.__coding_plugin_mini_ai_opts
local objects = {
{ " ", desc = "whitespace" },
{ '"', desc = '" string' },
{ "'", desc = "' string" },
{ "(", desc = "() block" },
{ ")", desc = "() block with ws" },
{ "<", desc = "<> block" },
{ ">", desc = "<> block with ws" },
{ "?", desc = "user prompt" },
{ "U", desc = "use/call without dot" },
{ "[", desc = "[] block" },
{ "]", desc = "[] block with ws" },
{ "_", desc = "underscore" },
{ "`", desc = "` string" },
{ "a", desc = "argument" },
{ "b", desc = ")]} block" },
{ "c", desc = "class" },
{ "d", desc = "digit(s)" },
{ "e", desc = "CamelCase / snake_case" },
{ "f", desc = "function" },
{ "g", desc = "entire file" },
{ "i", desc = "indent" },
{ "o", desc = "block, conditional, loop" },
{ "q", desc = "quote `\"'" },
{ "t", desc = "tag" },
{ "u", desc = "use/call" },
{ "{", desc = "{} block" },
{ "}", desc = "{} with ws" },
}
---@type wk.Spec[]
local ret = { mode = { "o", "x" } }
---@type table<string, string>
local mappings = vim.tbl_extend("force", {}, {
around = "a",
inside = "i",
around_next = "an",
inside_next = "in",
around_last = "al",
inside_last = "il",
}, opts.mappings or {})
mappings.goto_left = nil
mappings.goto_right = nil
for name, prefix in pairs(mappings) do
name = name:gsub("^around_", ""):gsub("^inside_", "")
ret[#ret + 1] = { prefix, group = name }
for _, obj in ipairs(objects) do
local desc = obj.desc
if prefix:sub(1, 1) == "i" then
desc = desc:gsub(" with ws", "")
end
ret[#ret + 1] = { prefix .. obj[1], desc = obj.desc }
end
end
require("which-key").add(ret, { notify = false })
end)
'';
};
}