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",
|
||||
-- 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 = {
|
||||
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.*", "")
|
||||
enabled = function()
|
||||
vim.schedule(function()
|
||||
local Config = require("lazy.core.config")
|
||||
if Config.spec.disabled["mini.ai"] then
|
||||
require("lazy.core.util").warn(
|
||||
[[ `mini.ai` has been moved to extras:
|
||||
The core config for nvim-treesitter now contains textobjects
|
||||
for `select`, `move` and `swap`.
|
||||
If you want to keep using mini.ai, you can add the mini-ai extra:
|
||||
`lazyvim.plugins.extras.coding.mini-ai`
|
||||
By doing so, your original mini.ai setup remains unchanged.
|
||||
]],
|
||||
{ title = "LazyVim" }
|
||||
)
|
||||
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)
|
||||
return false
|
||||
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 {
|
||||
-- Treesitter is a new parser generator tool that we can
|
||||
-- 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
|
||||
build = ":TSUpdate",
|
||||
event = { "BufReadPost", "BufNewFile" },
|
||||
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,
|
||||
},
|
||||
},
|
||||
dependencies = { "nvim-treesitter/nvim-treesitter-textobjects" },
|
||||
cmd = { "TSUpdateSync" },
|
||||
keys = {
|
||||
{ "<c-space>", desc = "Increment selection" },
|
||||
|
|
@ -59,36 +62,70 @@ return {
|
|||
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
|
||||
config = function(_, opts)
|
||||
if type(opts.ensure_installed) == "table" then
|
||||
---@type table<string, boolean>
|
||||
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)
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue