vim-config/lua/auto-pairs.lua
2025-05-19 12:58:17 +08:00

133 lines
3.7 KiB
Lua

-- 不能正常工作的括号补全代码
-- 完全由ai生成qwq
--
local M = {}
-- 定义需要自动补全的字符对
local pairs_map = {
['('] = ')',
['['] = ']',
['{'] = '}',
["'"] = "'",
['"'] = '"',
['`'] = '`',
['<'] = '>',
}
-- 检查光标前是否是转义字符
local function is_escaped()
local col = vim.api.nvim_win_get_cursor(0)[2]
local line = vim.api.nvim_get_current_line()
local count = 0
while col > 0 and line:sub(col, col) == '\\' do
count = count + 1
col = col - 1
end
return count % 2 == 1
end
-- 检查是否在注释或字符串中
local function is_in_comment_or_string()
local synstack = vim.fn.synstack(vim.fn.line('.'), vim.fn.col('.'))
for _, id in ipairs(synstack) do
local syn = vim.fn.synIDattr(id, 'name')
if string.find(syn, 'comment') or string.find(syn, 'string') then
return true
end
end
return false
end
local function should_auto_pair(left, right)
local line = vim.api.nvim_get_current_line()
local col = vim.api.nvim_win_get_cursor(0)[2]
local next_char = line:sub(col + 1, col + 1)
-- 特殊处理引号:如果下一个字符是字母/数字,不自动补全
if left == "'" or left == '"' or left == '`' then
if next_char:match('%w') then
return false
end
end
return next_char == '' or next_char:match('%s') or next_char == right
end
local function auto_pair(left)
local right = pairs_map[left]
if should_auto_pair(left, right) then
local keys = left .. right .. '<Left>'
return vim.api.nvim_replace_termcodes(keys, true, true, true)
end
return left
end
-- 修改右括号处理函数
local function handle_right_pair(right)
local line = vim.api.nvim_get_current_line()
local col = vim.api.nvim_win_get_cursor(0)[2]
local next_char = line:sub(col + 1, col + 1)
-- 只有当下一个字符确实是配对的右括号时才跳过
if next_char == right then
-- 检查前面是否有未闭合的左括号
local before_cursor = line:sub(1, col)
local after_cursor = line:sub(col + 1)
-- 计算前面左括号和后面右括号的数量
local left_count = select(2, before_cursor:gsub(vim.pesc(pairs_map[right]), ''))
local right_count = select(2, after_cursor:gsub(vim.pesc(right), ''))
-- 只有当前面有未闭合的左括号时才跳过
if left_count > right_count then
return vim.api.nvim_replace_termcodes('<Right>', true, true, true)
end
end
return right
end
-- 主函数,处理自动补全
function M.setup()
vim.keymap.set('i', '<BS>', function()
return M.auto_pairs_bs()
end, {expr = true, noremap = true})
for left, right in pairs(pairs_map) do
vim.keymap.set('i', left, function()
if is_escaped() or is_in_comment_or_string(left) then
return left
end
return auto_pair(left)
end, {expr = true, noremap = true})
-- 设置右符号
vim.keymap.set('i', right, function()
if is_escaped() or is_in_comment_or_string() then
return right
end
return handle_right_pair(right)
end, {expr = true, noremap = true})
end
end
-- 退格键处理
function M.auto_pairs_bs()
local line = vim.fn.getline('.')
local col = vim.fn.col('.') -- 获取 1-based 列号
local prev_char = line:sub(col-1, col-1)
local next_char = line:sub(col, col)
for left, right in pairs(pairs_map) do
if prev_char == left and next_char == right then
return '<Del><BS>'
end
end
return '<BS>'
end
return M