dotfiles/nvim/lua/my/tab.lua

81 lines
1.8 KiB
Lua
Raw Permalink Normal View History

2025-02-18 21:28:13 +00:00
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