mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-19 03:40:04 -04:00
Textobjects: provide mappings for all swap/goto functions
This commit is contained in:
parent
1642e37499
commit
e629efafd8
4 changed files with 116 additions and 54 deletions
26
README.md
26
README.md
|
|
@ -147,7 +147,31 @@ require'nvim-treesitter.configs'.setup {
|
||||||
["ad"] = "@comment.outer",
|
["ad"] = "@comment.outer",
|
||||||
["am"] = "@call.outer",
|
["am"] = "@call.outer",
|
||||||
["im"] = "@call.inner"
|
["im"] = "@call.inner"
|
||||||
}
|
},
|
||||||
|
-- swap parameters (keymap -> textobject query)
|
||||||
|
swap_next = {
|
||||||
|
["<a-p>"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
swap_previous = {
|
||||||
|
["<a-P>"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
-- set mappings to go to start/end of adjacent textobjects (keymap -> textobject query)
|
||||||
|
goto_previous_start = {
|
||||||
|
["[m"] = "@function.outer",
|
||||||
|
["[["] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[M"] = "@function.outer",
|
||||||
|
["[]"] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_next_start = {
|
||||||
|
["]m"] = "@function.outer",
|
||||||
|
["]]"] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]M"] = "@function.outer",
|
||||||
|
["]["] = "@class.outer",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ensure_installed = "all" -- one of "all", "language", or a list of languages
|
ensure_installed = "all" -- one of "all", "language", or a list of languages
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,31 @@ By default, everything is disabled. To enable support for features, in your `ini
|
||||||
["ad"] = "@comment.outer",
|
["ad"] = "@comment.outer",
|
||||||
["am"] = "@call.outer",
|
["am"] = "@call.outer",
|
||||||
["im"] = "@call.inner"
|
["im"] = "@call.inner"
|
||||||
}
|
},
|
||||||
|
-- swap parameters (keymap -> textobject query)
|
||||||
|
swap_next = {
|
||||||
|
["<a-p>"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
swap_previous = {
|
||||||
|
["<a-P>"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
-- set mappings to go to start/end of adjacent textobjects (keymap -> textobject query)
|
||||||
|
goto_previous_start = {
|
||||||
|
["[m"] = "@function.outer",
|
||||||
|
["[["] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[M"] = "@function.outer",
|
||||||
|
["[]"] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_next_start = {
|
||||||
|
["]m"] = "@function.outer",
|
||||||
|
["]]"] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]M"] = "@function.outer",
|
||||||
|
["]["] = "@class.outer",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ensure_installed = "all" -- one of "all", "language", or a list of languages
|
ensure_installed = "all" -- one of "all", "language", or a list of languages
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,12 @@ local builtin_modules = {
|
||||||
return has_some_textobject_mapping(lang) or queries.has_textobjects(lang)
|
return has_some_textobject_mapping(lang) or queries.has_textobjects(lang)
|
||||||
end,
|
end,
|
||||||
keymaps = {},
|
keymaps = {},
|
||||||
swap_next_keymaps = {},
|
swap_next = {},
|
||||||
swap_previous_keymaps = {}
|
swap_previous = {},
|
||||||
|
goto_next_start = {},
|
||||||
|
goto_next_end = {},
|
||||||
|
goto_previous_start = {},
|
||||||
|
goto_previous_end = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ local ts_utils = require'nvim-treesitter.ts_utils'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local function get_textobject_at_point(query_string)
|
local function textobject_at_point(query_string)
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
local lang = parsers.get_buf_lang(bufnr)
|
local lang = parsers.get_buf_lang(bufnr)
|
||||||
if not lang then return end
|
if not lang then return end
|
||||||
|
|
@ -74,59 +74,69 @@ local function get_textobject_at_point(query_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.select_textobject(query_string)
|
function M.select_textobject(query_string)
|
||||||
local bufnr, textobject = get_textobject_at_point(query_string)
|
local bufnr, textobject = textobject_at_point(query_string)
|
||||||
if textobject then
|
if textobject then
|
||||||
ts_utils.update_selection(bufnr, textobject)
|
ts_utils.update_selection(bufnr, textobject)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function swap_textobject(query_string, direction)
|
local function swap_textobject(query_string, direction)
|
||||||
local bufnr, textobject_range, node = get_textobject_at_point(query_string)
|
local bufnr, textobject_range, node = textobject_at_point(query_string)
|
||||||
local step = direction > 0 and 1 or -1
|
local step = direction > 0 and 1 or -1
|
||||||
if not node then return end
|
if not node then return end
|
||||||
for _ = 1, math.abs(direction), step do
|
for _ = 1, math.abs(direction), step do
|
||||||
if direction > 0 then
|
if direction > 0 then
|
||||||
ts_utils.swap_nodes(textobject_range, M.next_textobject(node, query_string, true, bufnr), bufnr, "yes, set cursor!")
|
ts_utils.swap_nodes(textobject_range,
|
||||||
|
M.next_textobject(node, query_string, true, bufnr),
|
||||||
|
bufnr,
|
||||||
|
"yes, set cursor!")
|
||||||
else
|
else
|
||||||
ts_utils.swap_nodes(textobject_range, M.previous_textobject(node, query_string, true, bufnr), bufnr, "yes, set cursor!")
|
ts_utils.swap_nodes(textobject_range,
|
||||||
|
M.previous_textobject(node, query_string, true, bufnr),
|
||||||
|
bufnr,
|
||||||
|
"yes, set cursor!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.swap_textobject_next(query_string)
|
function M.swap_next(query_string)
|
||||||
swap_textobject(query_string, 1)
|
swap_textobject(query_string, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.swap_textobject_previous(query_string)
|
function M.swap_previous(query_string)
|
||||||
swap_textobject(query_string, -1)
|
swap_textobject(query_string, -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.goto_adjacent_textobejct(query_string, forward, start, same_parent)
|
function M.goto_adjacent(query_string, forward, start, same_parent)
|
||||||
local bufnr, _, node = get_textobject_at_point(query_string)
|
local bufnr, _, node = textobject_at_point(query_string)
|
||||||
local ajacent_textobject
|
local adjacent_textobject
|
||||||
if forward then
|
if forward then
|
||||||
ajacent_textobject = M.next_textobject(node, query_string, same_parent, bufnr)
|
adjacent_textobject = M.next_textobject(node, query_string, same_parent, bufnr)
|
||||||
else
|
else
|
||||||
ajacent_textobject = M.previous_textobject(node, query_string, same_parent, bufnr)
|
adjacent_textobject = M.previous_textobject(node, query_string, same_parent, bufnr)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ajacent_textobject then
|
if adjacent_textobject then
|
||||||
local adjacent_textobject_range = {ajacent_textobject:range()}
|
local adjacent_textobject_range = {adjacent_textobject:range()}
|
||||||
if start then
|
if start then
|
||||||
api.nvim_win_set_cursor(api.nvim_get_current_win(), { adjacent_textobject_range[1] + 1, adjacent_textobject_range[2] })
|
api.nvim_win_set_cursor(api.nvim_get_current_win(),
|
||||||
|
{ adjacent_textobject_range[1] + 1, adjacent_textobject_range[2] })
|
||||||
else
|
else
|
||||||
api.nvim_win_set_cursor(api.nvim_get_current_win(), { adjacent_textobject_range[3] + 1, adjacent_textobject_range[4] })
|
api.nvim_win_set_cursor(api.nvim_get_current_win(),
|
||||||
|
{ adjacent_textobject_range[3] + 1, adjacent_textobject_range[4] })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
M.goto_next_textobject_start = function(query_string) M.goto_adjacent_textobejct(query_string, 'forward', 'start', false) end
|
-- luacheck: push ignore 631
|
||||||
M.goto_next_textobject_end = function(query_string) M.goto_adjacent_textobejct(query_string, 'forward', false, false) end
|
M.goto_next_start = function(query_string) M.goto_adjacent(query_string, 'forward', 'start', false) end
|
||||||
M.goto_previous_textobject_start = function(query_string) M.goto_adjacent_textobejct(query_string, false, 'start', false) end
|
M.goto_next_end = function(query_string) M.goto_adjacent(query_string, 'forward', false, false) end
|
||||||
M.goto_previous_textobject_end = function(query_string) M.goto_adjacent_textobejct(query_string, false, false, false) end
|
M.goto_previous_start = function(query_string) M.goto_adjacent(query_string, false, 'start', false) end
|
||||||
|
M.goto_previous_end = function(query_string) M.goto_adjacent(query_string, false, false, false) end
|
||||||
|
-- luacheck: pop
|
||||||
|
|
||||||
function M.goto_next_textobject_end(query_string)
|
function M.goto_next_end(query_string)
|
||||||
local bufnr, _, node = get_textobject_at_point(query_string)
|
local bufnr, _, node = textobject_at_point(query_string)
|
||||||
if not node then return end
|
if not node then return end
|
||||||
local next_textobject = M.next_textobject(node, query_string, false, bufnr)
|
local next_textobject = M.next_textobject(node, query_string, false, bufnr)
|
||||||
local next_textobject_range = next_textobject:range()
|
local next_textobject_range = next_textobject:range()
|
||||||
|
|
@ -189,6 +199,13 @@ function M.previous_textobject(node, query_string, same_parent, bufnr)
|
||||||
return previous_node and previous_node.node
|
return previous_node and previous_node.node
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local normal_mode_functions = { "swap_next",
|
||||||
|
"swap_previous",
|
||||||
|
"goto_next_start",
|
||||||
|
"goto_next_end",
|
||||||
|
"goto_previous_start",
|
||||||
|
"goto_previous_end"}
|
||||||
|
|
||||||
function M.attach(bufnr, lang)
|
function M.attach(bufnr, lang)
|
||||||
local buf = bufnr or api.nvim_get_current_buf()
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
local config = configs.get_module("textobjects")
|
local config = configs.get_module("textobjects")
|
||||||
|
|
@ -206,26 +223,17 @@ function M.attach(bufnr, lang)
|
||||||
api.nvim_buf_set_keymap(buf, "v", mapping, cmd, {silent = true, noremap = true })
|
api.nvim_buf_set_keymap(buf, "v", mapping, cmd, {silent = true, noremap = true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for mapping, query in pairs(config.swap_next_keymaps) do
|
for _, function_call in pairs(normal_mode_functions) do
|
||||||
if type(query) == 'table' then
|
for mapping, query in pairs(config[function_call] or {}) do
|
||||||
query = query[lang]
|
if type(query) == 'table' then
|
||||||
elseif not queries.get_query(lang, 'textobjects') then
|
query = query[lang]
|
||||||
query = nil
|
elseif not queries.get_query(lang, 'textobjects') then
|
||||||
end
|
query = nil
|
||||||
if query then
|
end
|
||||||
local cmd = ":lua require'nvim-treesitter.textobjects'.swap_textobject_next('"..query.."')<CR>"
|
if query then
|
||||||
api.nvim_buf_set_keymap(buf, "n", mapping, cmd, {silent = true})
|
local cmd = ":lua require'nvim-treesitter.textobjects'."..function_call.."('"..query.."')<CR>"
|
||||||
end
|
api.nvim_buf_set_keymap(buf, "n", mapping, cmd, {silent = true, noremap = true })
|
||||||
end
|
end
|
||||||
for mapping, query in pairs(config.swap_previous_keymaps) do
|
|
||||||
if type(query) == 'table' then
|
|
||||||
query = query[lang]
|
|
||||||
elseif not queries.get_query(lang, 'textobjects') then
|
|
||||||
query = nil
|
|
||||||
end
|
|
||||||
if query then
|
|
||||||
local cmd = ":lua require'nvim-treesitter.textobjects'.swap_textobject_previous('"..query.."')<CR>"
|
|
||||||
api.nvim_buf_set_keymap(buf, "n", mapping, cmd, {silent = true})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -246,14 +254,16 @@ function M.detach(bufnr)
|
||||||
api.nvim_buf_del_keymap(buf, "v", mapping)
|
api.nvim_buf_del_keymap(buf, "v", mapping)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for mapping, query in pairs(config.swap_next_keymaps) or pairs(config.swap_previous_keymaps) do
|
for _, function_call in pairs(normal_mode_functions) do
|
||||||
if type(query) == 'table' then
|
for mapping, query in pairs(config[function_call] or {}) do
|
||||||
query = query[lang]
|
if type(query) == 'table' then
|
||||||
elseif not queries.get_query(lang, 'textobjects') then
|
query = query[lang]
|
||||||
query = nil
|
elseif not queries.get_query(lang, 'textobjects') then
|
||||||
end
|
query = nil
|
||||||
if query then
|
end
|
||||||
api.nvim_buf_del_keymap(buf, "n", mapping)
|
if query then
|
||||||
|
api.nvim_buf_del_keymap(buf, "n", mapping)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue