mirror of
https://github.com/LazyVim/LazyVim.git
synced 2026-07-25 14:01:06 +00:00
mini.ai: move to extras. Add default textobjects to treesitter
This commit is contained in:
parent
a72a84972d
commit
0c12cc332a
3 changed files with 230 additions and 101 deletions
|
|
@ -150,74 +150,27 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Better text-objects
|
-- disable old installations of mini.ai. Optional so it doesn't appear under disabled plugins
|
||||||
{
|
{
|
||||||
"echasnovski/mini.ai",
|
"echasnovski/mini.ai",
|
||||||
-- keys = {
|
enabled = function()
|
||||||
-- { "a", mode = { "x", "o" } },
|
vim.schedule(function()
|
||||||
-- { "i", mode = { "x", "o" } },
|
local Config = require("lazy.core.config")
|
||||||
-- },
|
if Config.spec.disabled["mini.ai"] then
|
||||||
event = "VeryLazy",
|
require("lazy.core.util").warn(
|
||||||
dependencies = { "nvim-treesitter-textobjects" },
|
[[ `mini.ai` has been moved to extras:
|
||||||
opts = function()
|
The core config for nvim-treesitter now contains textobjects
|
||||||
local ai = require("mini.ai")
|
for `select`, `move` and `swap`.
|
||||||
return {
|
If you want to keep using mini.ai, you can add the mini-ai extra:
|
||||||
n_lines = 500,
|
`lazyvim.plugins.extras.coding.mini-ai`
|
||||||
custom_textobjects = {
|
By doing so, your original mini.ai setup remains unchanged.
|
||||||
o = ai.gen_spec.treesitter({
|
]],
|
||||||
a = { "@block.outer", "@conditional.outer", "@loop.outer" },
|
{ title = "LazyVim" }
|
||||||
i = { "@block.inner", "@conditional.inner", "@loop.inner" },
|
)
|
||||||
}, {}),
|
|
||||||
f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}),
|
|
||||||
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
config = function(_, opts)
|
|
||||||
require("mini.ai").setup(opts)
|
|
||||||
-- register all text objects with which-key
|
|
||||||
require("lazyvim.util").on_load("which-key.nvim", function()
|
|
||||||
---@type table<string, string|table>
|
|
||||||
local i = {
|
|
||||||
[" "] = "Whitespace",
|
|
||||||
['"'] = 'Balanced "',
|
|
||||||
["'"] = "Balanced '",
|
|
||||||
["`"] = "Balanced `",
|
|
||||||
["("] = "Balanced (",
|
|
||||||
[")"] = "Balanced ) including white-space",
|
|
||||||
[">"] = "Balanced > including white-space",
|
|
||||||
["<lt>"] = "Balanced <",
|
|
||||||
["]"] = "Balanced ] including white-space",
|
|
||||||
["["] = "Balanced [",
|
|
||||||
["}"] = "Balanced } including white-space",
|
|
||||||
["{"] = "Balanced {",
|
|
||||||
["?"] = "User Prompt",
|
|
||||||
_ = "Underscore",
|
|
||||||
a = "Argument",
|
|
||||||
b = "Balanced ), ], }",
|
|
||||||
c = "Class",
|
|
||||||
f = "Function",
|
|
||||||
o = "Block, conditional, loop",
|
|
||||||
q = "Quote `, \", '",
|
|
||||||
t = "Tag",
|
|
||||||
}
|
|
||||||
local a = vim.deepcopy(i)
|
|
||||||
for k, v in pairs(a) do
|
|
||||||
a[k] = v:gsub(" including.*", "")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local ic = vim.deepcopy(i)
|
|
||||||
local ac = vim.deepcopy(a)
|
|
||||||
for key, name in pairs({ n = "Next", l = "Last" }) do
|
|
||||||
i[key] = vim.tbl_extend("force", { name = "Inside " .. name .. " textobject" }, ic)
|
|
||||||
a[key] = vim.tbl_extend("force", { name = "Around " .. name .. " textobject" }, ac)
|
|
||||||
end
|
|
||||||
require("which-key").register({
|
|
||||||
mode = { "o", "x" },
|
|
||||||
i = i,
|
|
||||||
a = a,
|
|
||||||
})
|
|
||||||
end)
|
end)
|
||||||
|
return false
|
||||||
end,
|
end,
|
||||||
|
optional = true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
139
lua/lazyvim/plugins/extras/coding/mini-ai.lua
Normal file
139
lua/lazyvim/plugins/extras/coding/mini-ai.lua
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
local load_textobjects = false
|
||||||
|
|
||||||
|
---@param langs table<string>
|
||||||
|
---@return table<string>
|
||||||
|
local function dedup(langs)
|
||||||
|
-- TODO: move this utility function to a better location
|
||||||
|
---@type table<string, boolean>
|
||||||
|
local added = {}
|
||||||
|
return vim.tbl_filter(function(lang)
|
||||||
|
if added[lang] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
added[lang] = true
|
||||||
|
return true
|
||||||
|
end, langs)
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
{
|
||||||
|
"nvim-treesitter/nvim-treesitter",
|
||||||
|
dependencies = {
|
||||||
|
{
|
||||||
|
"nvim-treesitter/nvim-treesitter-textobjects",
|
||||||
|
init = function()
|
||||||
|
-- disable rtp plugin, as we only need its queries for mini.ai
|
||||||
|
-- In case other textobject modules are enabled, we will load them
|
||||||
|
-- once nvim-treesitter is loaded
|
||||||
|
require("lazy.core.loader").disable_rtp_plugin("nvim-treesitter-textobjects")
|
||||||
|
load_textobjects = true
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opts = function(_, opts)
|
||||||
|
-- override the default textobjects, set in plugins/treesitter.lua
|
||||||
|
-- when using this extra, the user is expected to add textobjects
|
||||||
|
-- on a need-to-have basis
|
||||||
|
opts.textobjects = nil
|
||||||
|
end,
|
||||||
|
---@param opts TSConfig
|
||||||
|
config = function(_, opts) -- override config in plugins/treesitter.lua
|
||||||
|
if type(opts.ensure_installed) == "table" then
|
||||||
|
opts.ensure_installed = dedup(opts.ensure_installed)
|
||||||
|
end
|
||||||
|
require("nvim-treesitter.configs").setup(opts)
|
||||||
|
|
||||||
|
if load_textobjects then
|
||||||
|
-- PERF: no need to load the plugin, if we only need its queries for mini.ai
|
||||||
|
if opts.textobjects then
|
||||||
|
for _, mod in ipairs({ "move", "select", "swap", "lsp_interop" }) do
|
||||||
|
if opts.textobjects[mod] and opts.textobjects[mod].enable then
|
||||||
|
local Loader = require("lazy.core.loader")
|
||||||
|
Loader.disabled_rtp_plugins["nvim-treesitter-textobjects"] = nil
|
||||||
|
local plugin = require("lazy.core.config").plugins["nvim-treesitter-textobjects"]
|
||||||
|
require("lazy.core.loader").source_runtime(plugin.dir, "plugin")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Better text-objects
|
||||||
|
{
|
||||||
|
"echasnovski/mini.ai",
|
||||||
|
enabled = true,
|
||||||
|
-- keys = {
|
||||||
|
-- { "a", mode = { "x", "o" } },
|
||||||
|
-- { "i", mode = { "x", "o" } },
|
||||||
|
-- },
|
||||||
|
event = "VeryLazy",
|
||||||
|
dependencies = { "nvim-treesitter-textobjects" },
|
||||||
|
opts = function()
|
||||||
|
local ai = require("mini.ai")
|
||||||
|
return {
|
||||||
|
n_lines = 500,
|
||||||
|
custom_textobjects = {
|
||||||
|
|
||||||
|
-- see: https://github.com/echasnovski/mini.nvim/issues/474
|
||||||
|
t = false, -- for now, fallback to neovim's builtin tag.
|
||||||
|
|
||||||
|
o = ai.gen_spec.treesitter({
|
||||||
|
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" }, {}),
|
||||||
|
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
config = function(_, opts)
|
||||||
|
require("mini.ai").setup(opts)
|
||||||
|
-- register all text objects with which-key
|
||||||
|
require("lazyvim.util").on_load("which-key.nvim", function()
|
||||||
|
---@type table<string, string|table>
|
||||||
|
local i = {
|
||||||
|
[" "] = "Whitespace",
|
||||||
|
['"'] = 'Balanced "',
|
||||||
|
["'"] = "Balanced '",
|
||||||
|
["`"] = "Balanced `",
|
||||||
|
["("] = "Balanced (",
|
||||||
|
[")"] = "Balanced ) including white-space",
|
||||||
|
[">"] = "Balanced > including white-space",
|
||||||
|
["<lt>"] = "Balanced <",
|
||||||
|
["]"] = "Balanced ] including white-space",
|
||||||
|
["["] = "Balanced [",
|
||||||
|
["}"] = "Balanced } including white-space",
|
||||||
|
["{"] = "Balanced {",
|
||||||
|
["?"] = "User Prompt",
|
||||||
|
_ = "Underscore",
|
||||||
|
a = "Argument",
|
||||||
|
b = "Balanced ), ], }",
|
||||||
|
c = "Class",
|
||||||
|
f = "Function",
|
||||||
|
o = "Block, conditional, loop",
|
||||||
|
q = "Quote `, \", '",
|
||||||
|
t = "Tag",
|
||||||
|
}
|
||||||
|
local a = vim.deepcopy(i)
|
||||||
|
for k, v in pairs(a) do
|
||||||
|
a[k] = v:gsub(" including.*", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
local ic = vim.deepcopy(i)
|
||||||
|
local ac = vim.deepcopy(a)
|
||||||
|
for key, name in pairs({ n = "Next", l = "Last" }) do
|
||||||
|
i[key] = vim.tbl_extend("force", { name = "Inside " .. name .. " textobject" }, ic)
|
||||||
|
a[key] = vim.tbl_extend("force", { name = "Around " .. name .. " textobject" }, ac)
|
||||||
|
end
|
||||||
|
require("which-key").register({
|
||||||
|
mode = { "o", "x" },
|
||||||
|
i = i,
|
||||||
|
a = a,
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,18 @@
|
||||||
local load_textobjects = false
|
---@param langs table<string>
|
||||||
|
---@return table<string>
|
||||||
|
local function dedup(langs)
|
||||||
|
-- TODO: move this utility function to a better location
|
||||||
|
---@type table<string, boolean>
|
||||||
|
local added = {}
|
||||||
|
return vim.tbl_filter(function(lang)
|
||||||
|
if added[lang] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
added[lang] = true
|
||||||
|
return true
|
||||||
|
end, langs)
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
-- Treesitter is a new parser generator tool that we can
|
-- Treesitter is a new parser generator tool that we can
|
||||||
-- use in Neovim to power faster and more accurate
|
-- use in Neovim to power faster and more accurate
|
||||||
|
|
@ -8,18 +22,7 @@ return {
|
||||||
version = false, -- last release is way too old and doesn't work on Windows
|
version = false, -- last release is way too old and doesn't work on Windows
|
||||||
build = ":TSUpdate",
|
build = ":TSUpdate",
|
||||||
event = { "BufReadPost", "BufNewFile" },
|
event = { "BufReadPost", "BufNewFile" },
|
||||||
dependencies = {
|
dependencies = { "nvim-treesitter/nvim-treesitter-textobjects" },
|
||||||
{
|
|
||||||
"nvim-treesitter/nvim-treesitter-textobjects",
|
|
||||||
init = function()
|
|
||||||
-- disable rtp plugin, as we only need its queries for mini.ai
|
|
||||||
-- In case other textobject modules are enabled, we will load them
|
|
||||||
-- once nvim-treesitter is loaded
|
|
||||||
require("lazy.core.loader").disable_rtp_plugin("nvim-treesitter-textobjects")
|
|
||||||
load_textobjects = true
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
cmd = { "TSUpdateSync" },
|
cmd = { "TSUpdateSync" },
|
||||||
keys = {
|
keys = {
|
||||||
{ "<c-space>", desc = "Increment selection" },
|
{ "<c-space>", desc = "Increment selection" },
|
||||||
|
|
@ -59,36 +62,70 @@ return {
|
||||||
node_decremental = "<bs>",
|
node_decremental = "<bs>",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
textobjects = {
|
||||||
|
select = {
|
||||||
|
enable = true,
|
||||||
|
lookahead = true,
|
||||||
|
keymaps = {
|
||||||
|
["ak"] = { query = "@block.outer", desc = "around block" },
|
||||||
|
["ik"] = { query = "@block.inner", desc = "inside block" },
|
||||||
|
["ac"] = { query = "@class.outer", desc = "around class" },
|
||||||
|
["ic"] = { query = "@class.inner", desc = "inside class" },
|
||||||
|
["a?"] = { query = "@conditional.outer", desc = "around conditional" },
|
||||||
|
["i?"] = { query = "@conditional.inner", desc = "inside conditional" },
|
||||||
|
["af"] = { query = "@function.outer", desc = "around function " },
|
||||||
|
["if"] = { query = "@function.inner", desc = "inside function " },
|
||||||
|
["al"] = { query = "@loop.outer", desc = "around loop" },
|
||||||
|
["il"] = { query = "@loop.inner", desc = "inside loop" },
|
||||||
|
["aa"] = { query = "@parameter.outer", desc = "around argument" },
|
||||||
|
["ia"] = { query = "@parameter.inner", desc = "inside argument" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
move = {
|
||||||
|
enable = true,
|
||||||
|
set_jumps = true,
|
||||||
|
goto_next_start = {
|
||||||
|
["]k"] = { query = "@block.outer", desc = "Next block start" },
|
||||||
|
["]f"] = { query = "@function.outer", desc = "Next function start" },
|
||||||
|
["]a"] = { query = "@parameter.inner", desc = "Next argument start" },
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]K"] = { query = "@block.outer", desc = "Next block end" },
|
||||||
|
["]F"] = { query = "@function.outer", desc = "Next function end" },
|
||||||
|
["]A"] = { query = "@parameter.inner", desc = "Next argument end" },
|
||||||
|
},
|
||||||
|
goto_previous_start = {
|
||||||
|
["[k"] = { query = "@block.outer", desc = "Previous block start" },
|
||||||
|
["[f"] = { query = "@function.outer", desc = "Previous function start" },
|
||||||
|
["[a"] = { query = "@parameter.inner", desc = "Previous argument start" },
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[K"] = { query = "@block.outer", desc = "Previous block end" },
|
||||||
|
["[F"] = { query = "@function.outer", desc = "Previous function end" },
|
||||||
|
["[A"] = { query = "@parameter.inner", desc = "Previous argument end" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
swap = {
|
||||||
|
enable = true,
|
||||||
|
swap_next = {
|
||||||
|
[">K"] = { query = "@block.outer", desc = "Swap next block" },
|
||||||
|
[">F"] = { query = "@function.outer", desc = "Swap next function" },
|
||||||
|
[">A"] = { query = "@parameter.inner", desc = "Swap next argument" },
|
||||||
|
},
|
||||||
|
swap_previous = {
|
||||||
|
["<K"] = { query = "@block.outer", desc = "Swap previous block" },
|
||||||
|
["<F"] = { query = "@function.outer", desc = "Swap previous function" },
|
||||||
|
["<A"] = { query = "@parameter.inner", desc = "Swap previous argument" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
---@param opts TSConfig
|
---@param opts TSConfig
|
||||||
config = function(_, opts)
|
config = function(_, opts)
|
||||||
if type(opts.ensure_installed) == "table" then
|
if type(opts.ensure_installed) == "table" then
|
||||||
---@type table<string, boolean>
|
opts.ensure_installed = dedup(opts.ensure_installed)
|
||||||
local added = {}
|
|
||||||
opts.ensure_installed = vim.tbl_filter(function(lang)
|
|
||||||
if added[lang] then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
added[lang] = true
|
|
||||||
return true
|
|
||||||
end, opts.ensure_installed)
|
|
||||||
end
|
end
|
||||||
require("nvim-treesitter.configs").setup(opts)
|
require("nvim-treesitter.configs").setup(opts)
|
||||||
|
|
||||||
if load_textobjects then
|
|
||||||
-- PERF: no need to load the plugin, if we only need its queries for mini.ai
|
|
||||||
if opts.textobjects then
|
|
||||||
for _, mod in ipairs({ "move", "select", "swap", "lsp_interop" }) do
|
|
||||||
if opts.textobjects[mod] and opts.textobjects[mod].enable then
|
|
||||||
local Loader = require("lazy.core.loader")
|
|
||||||
Loader.disabled_rtp_plugins["nvim-treesitter-textobjects"] = nil
|
|
||||||
local plugin = require("lazy.core.config").plugins["nvim-treesitter-textobjects"]
|
|
||||||
require("lazy.core.loader").source_runtime(plugin.dir, "plugin")
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue