81 lines
1.8 KiB
Lua
81 lines
1.8 KiB
Lua
|
local M = {}
|
||
|
|
||
|
local ok, ts = pcall(require, "nvim-treesitter.ts_utils")
|
||
|
|
||
|
if not ok then
|
||
|
vim.notify "my.tab requires nvim-treesitter to work"
|
||
|
end
|
||
|
|
||
|
local pairs = {
|
||
|
["("] = ")",
|
||
|
["{"] = "}",
|
||
|
["["] = "]",
|
||
|
["<"] = ">",
|
||
|
["'"] = "'",
|
||
|
['"'] = '"',
|
||
|
["`"] = "`",
|
||
|
}
|
||
|
|
||
|
local get_new_position = function(node, direction)
|
||
|
local is_single_line = function()
|
||
|
local row_start, _, row_end, _ = node:range()
|
||
|
return row_start == row_end
|
||
|
end
|
||
|
|
||
|
local is_wrapped = function()
|
||
|
local text = vim.treesitter.get_node_text(node, 0)
|
||
|
local first = string.sub(text, 1, 1)
|
||
|
local last = string.sub(text, -1)
|
||
|
return pairs[first] == last
|
||
|
end
|
||
|
|
||
|
if is_wrapped() and is_single_line() then
|
||
|
if direction == "backward" then
|
||
|
return node:start()
|
||
|
end
|
||
|
return node:end_()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- @param direction string The direction of the tab ('forward' | 'backward')
|
||
|
--- @return nil
|
||
|
M.tab = function(direction)
|
||
|
-- Normal tab action
|
||
|
local tab_action
|
||
|
if direction == "forward" then
|
||
|
tab_action = function()
|
||
|
local codes = vim.api.nvim_replace_termcodes("<Tab>", true, true, true)
|
||
|
vim.api.nvim_call_function("feedkeys", { codes, "n" })
|
||
|
end
|
||
|
else
|
||
|
tab_action = function()
|
||
|
local codes = vim.api.nvim_replace_termcodes("<S-Tab>", true, true, true)
|
||
|
vim.api.nvim_call_function("feedkeys", { codes, "n" })
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local node = ts.get_node_at_cursor()
|
||
|
|
||
|
if not node or not node:parent() then
|
||
|
return tab_action()
|
||
|
end
|
||
|
|
||
|
local line, col = get_new_position(node, direction)
|
||
|
|
||
|
if not line then
|
||
|
return tab_action()
|
||
|
end
|
||
|
|
||
|
vim.api.nvim_win_set_cursor(0, { line + 1, col })
|
||
|
end
|
||
|
|
||
|
M.forwards = function()
|
||
|
M.tab "forward"
|
||
|
end
|
||
|
|
||
|
M.backwards = function()
|
||
|
M.tab "backward"
|
||
|
end
|
||
|
|
||
|
return M
|