mirror of
https://github.com/ilyakooo0/nvim-autopairs.git
synced 2024-09-11 07:15:44 +03:00
finish add pair
This commit is contained in:
parent
8e9187d001
commit
1e808ecdf0
@ -17,7 +17,7 @@ M.setup = function(opt)
|
||||
autocmd!
|
||||
autocmd BufEnter * :lua require("nvim-autopairs").on_attach()
|
||||
augroup end
|
||||
]],false)
|
||||
]],false)
|
||||
|
||||
end
|
||||
|
||||
@ -28,9 +28,9 @@ M.on_attach = function(bufnr)
|
||||
|
||||
state.rules = M.config.rules
|
||||
api.nvim_exec(string.format([[
|
||||
augroup autopairs_insert_%d
|
||||
autocmd!
|
||||
autocmd InsertCharPre <buffer=%d> call luaeval("require('nvim-autopairs').autopairs_insert(%d, _A)", v:char)
|
||||
augroup autopairs_insert_%d
|
||||
autocmd!
|
||||
autocmd InsertCharPre <buffer=%d> call luaeval("require('nvim-autopairs').autopairs_insert(%d, _A)", v:char)
|
||||
augroup end ]],
|
||||
bufnr, bufnr, bufnr), false)
|
||||
|
||||
@ -43,7 +43,7 @@ end
|
||||
|
||||
local skip_next = false
|
||||
M.autopairs_insert = function(bufnr, char)
|
||||
if skip_next then skip_next = false return end
|
||||
if skip_next then skip_next = false return end
|
||||
local line = utils.text_get_current_line(bufnr)
|
||||
log.debug("-----------------")
|
||||
log.debug("line:" .. line)
|
||||
@ -51,23 +51,43 @@ M.autopairs_insert = function(bufnr, char)
|
||||
local _, col = utils.get_cursor()
|
||||
log.debug(vim.inspect(col))
|
||||
local filetype = vim.bo.filetype
|
||||
local new_text = line:sub(1, col) .. char .. line:sub(col + 1,#line)
|
||||
log.debug("new_text:[" .. new_text .. "]")
|
||||
for _, rule in pairs(state.rules) do
|
||||
if rule.start_pair and utils.check_filetype(rule.filetypes, filetype) then
|
||||
local new_text = line:sub(0, col) .. char .. line:sub(col)
|
||||
log.debug("new_text:[" .. new_text .. "]")
|
||||
log.debug("start_pair" .. rule.start_pair)
|
||||
local prev_char = utils.text_sub_char(new_text, col + 1,-#rule.start_pair)
|
||||
local next_char = utils.text_sub_char(new_text, col + 2,#rule.start_pair)
|
||||
log.debug('prev_char' .. prev_char)
|
||||
log.debug('next_char' .. next_char)
|
||||
if
|
||||
prev_char == rule.start_pair
|
||||
then
|
||||
vim.schedule(function()
|
||||
utils.insert_char(rule.end_pair)
|
||||
utils.feed("<left>")
|
||||
end)
|
||||
return
|
||||
if rule.start_pair == '(' then
|
||||
log.debug("start_pair" .. rule.start_pair)
|
||||
log.debug('prev_char' .. prev_char)
|
||||
log.debug('next_char' .. next_char)
|
||||
end
|
||||
if prev_char == rule.start_pair then
|
||||
local cond_opt = {
|
||||
text = new_text,
|
||||
rule = rule,
|
||||
bufnr = bufnr,
|
||||
col = col,
|
||||
char = char,
|
||||
line = line,
|
||||
prev_char = prev_char,
|
||||
next_char = next_char,
|
||||
}
|
||||
|
||||
if rule:can_move(cond_opt) then
|
||||
vim.schedule(function()
|
||||
utils.feed(utils.key.del, 1)
|
||||
end)
|
||||
return
|
||||
end
|
||||
if rule:can_pair(cond_opt) then
|
||||
log.debug('match')
|
||||
vim.schedule(function()
|
||||
utils.insert_char(rule.end_pair)
|
||||
utils.feed(utils.key.left, #rule.end_pair)
|
||||
end)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
37
lua/nvim-autopairs/conds.lua
Normal file
37
lua/nvim-autopairs/conds.lua
Normal file
@ -0,0 +1,37 @@
|
||||
local utils = require('nvim-autopairs.utils')
|
||||
local log = require('nvim-autopairs._log')
|
||||
local cond={}
|
||||
|
||||
cond.not_regex_check = function(regex, length)
|
||||
length = length or 1
|
||||
return function(opts)
|
||||
local str = utils.text_sub_char(opts.line, opts.col, - length)
|
||||
log.debug(vim.inspect(str))
|
||||
if str:match(regex) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
cond.move_right = function ()
|
||||
return function(opts)
|
||||
log.debug("move right test")
|
||||
log.debug(opts)
|
||||
if utils.is_quote(opts.char)
|
||||
and opts.next_char == opts.char
|
||||
then
|
||||
local length = string.len(opts.line) -- situtaion |" => "|
|
||||
log.debug("is quote" .. length) -- move right when have quote on end line or in quote
|
||||
if opts.col + 1 == string.len(opts.line) then
|
||||
return true
|
||||
end
|
||||
-- ("|") => (""|)
|
||||
-- "" |" " => "" "| "
|
||||
if utils.is_in_quote(opts.text, opts.col - 1, opts.char) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
return cond
|
@ -1,37 +1,66 @@
|
||||
local log = require('nvim-autopairs._log')
|
||||
local Rule = {}
|
||||
|
||||
|
||||
function Rule.new(...)
|
||||
local params = {...}
|
||||
local opt = {}
|
||||
if params.start_pair then
|
||||
opt = params
|
||||
if type(params[1]) == 'table' then
|
||||
opt = params[1]
|
||||
else
|
||||
opt.start_pair = params[1]
|
||||
opt.end_pair = params[2]
|
||||
opt.filetype = params[3]
|
||||
if type(params[3])=="string" then
|
||||
opt.filetypes = {params[3]}
|
||||
else
|
||||
opt.filetypes = params[3]
|
||||
end
|
||||
end
|
||||
opt = vim.tbl_extend('force', {
|
||||
start_pair = nil,
|
||||
end_pair = nil,
|
||||
filetype = "*",
|
||||
filetypes = nil,
|
||||
-- allow move when press close_pairs
|
||||
can_move = function ()
|
||||
return true
|
||||
move_cond = function ()
|
||||
return false
|
||||
end,
|
||||
-- allow delete when press bs
|
||||
can_delete = function()
|
||||
return true
|
||||
del_cond = function()
|
||||
return false
|
||||
end,
|
||||
can_pair = function(_)
|
||||
pair_cond = function(_)
|
||||
-- local prev_char, line, ts_node = unpack(opts)
|
||||
return true
|
||||
end,
|
||||
},opt)
|
||||
|
||||
return setmetatable(opt, {__index = Rule})
|
||||
end
|
||||
|
||||
local function can_do(conds, opt)
|
||||
if type(conds) == 'table' then
|
||||
for _, cond in pairs(conds) do
|
||||
if not cond(opt) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
elseif type(conds) == 'function' then
|
||||
return conds(opt)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Rule:can_pair(opt)
|
||||
return can_do(self.pair_cond, opt)
|
||||
|
||||
end
|
||||
|
||||
function Rule:can_move(opt)
|
||||
return can_do(self.move_cond, opt)
|
||||
end
|
||||
|
||||
function Rule:can_del(opt)
|
||||
return can_do(self.del_cond, opt)
|
||||
end
|
||||
|
||||
return Rule.new
|
||||
|
@ -1,17 +1,30 @@
|
||||
|
||||
local Rule = require('nvim-autopairs.rule')
|
||||
|
||||
local check_func = require('nvim-autopairs.check_func')
|
||||
local cond = require('nvim-autopairs.conds')
|
||||
|
||||
local basic = {
|
||||
Rule("```", "```", 'markdown'),
|
||||
Rule("'", "'"),
|
||||
Rule('"""', '"""', 'python'),
|
||||
Rule({
|
||||
start_pair = "'",
|
||||
end_pair = "'",
|
||||
pair_cond = {
|
||||
cond.not_regex_check('%w')
|
||||
}
|
||||
}),
|
||||
Rule("`", "`"),
|
||||
Rule('"', '"'),
|
||||
|
||||
-- Rule({
|
||||
-- start_pair = '"',
|
||||
-- end_pair = '"',
|
||||
-- move_cond = {
|
||||
-- cond.move_right()
|
||||
-- }
|
||||
-- }),
|
||||
Rule("(", ")"),
|
||||
Rule("[", "]"),
|
||||
Rule("{", "}"),
|
||||
Rule('"""', '"""', 'python'),
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,6 +2,38 @@ local M={}
|
||||
local api = vim.api
|
||||
local log = require('nvim-autopairs._log')
|
||||
|
||||
M.key = {
|
||||
left = "<left>",
|
||||
del = "<del>",
|
||||
bs = "<bs>",
|
||||
right = "<right>"
|
||||
}
|
||||
|
||||
|
||||
|
||||
M.is_quote = function (char)
|
||||
return char == "'" or char == '"' or char == '`'
|
||||
end
|
||||
|
||||
M.is_in_quote = function(line, pos, quote)
|
||||
local cIndex = 0
|
||||
local result = false
|
||||
|
||||
while cIndex < string.len(line) and cIndex < pos do
|
||||
cIndex = cIndex + 1
|
||||
local char = line:sub(cIndex, cIndex)
|
||||
if
|
||||
result == true and
|
||||
char == quote and
|
||||
line:sub(cIndex -1, cIndex -1) ~= "\\"
|
||||
then
|
||||
result = false
|
||||
elseif result == false and char == quote then
|
||||
result = true
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
M.is_attached = function(bufnr)
|
||||
local _, check = pcall(api.nvim_buf_get_var, bufnr, "nvim-autopairs")
|
||||
@ -45,24 +77,49 @@ M.text_get_current_line = function(bufnr)
|
||||
return M.text_get_line(bufnr, row -1)
|
||||
end
|
||||
|
||||
|
||||
-- function M.text_prev_next(line, col, prev_count, next_char)
|
||||
-- prev_count = prev_count or 1
|
||||
-- next_char = next_char or prev_count
|
||||
|
||||
-- if line then
|
||||
-- local prev = string.sub(line, math.max(col - prev_count + 1, 0), col)
|
||||
-- local next = string.sub(line, col + 1, math.min(col + next_char, #line + 1))
|
||||
-- return prev, next
|
||||
-- end
|
||||
-- end
|
||||
|
||||
M.text_sub_char = function(line, start, num)
|
||||
if num > 0 then num = num - 1
|
||||
elseif num < 0 then num = num + 1 end
|
||||
log.debug(vim.inspect(num))
|
||||
return string.sub(line,
|
||||
math.min(start, start + num),
|
||||
math.max(start, start + num)
|
||||
)
|
||||
local finish = start
|
||||
if num < 0 then
|
||||
start = start + num + 1
|
||||
else
|
||||
finish = start + num -1
|
||||
end
|
||||
return string.sub(line, start, finish)
|
||||
end
|
||||
|
||||
-- P(M.text_sub_char("aa'' aaa", 3, -1))
|
||||
M.insert_char = function(text)
|
||||
api.nvim_put({text}, "c", false, true)
|
||||
end
|
||||
|
||||
M.feed = function(text)
|
||||
api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
text, true, false, true),
|
||||
"n", true)
|
||||
M.feed = function(text, num)
|
||||
-- num = num or 1
|
||||
-- local result = ''
|
||||
-- for _ = 1, num, 1 do
|
||||
-- result = result .. text
|
||||
-- end
|
||||
-- log.debug("result" .. result)
|
||||
-- api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
-- result, true, false, true),
|
||||
-- "n", true)
|
||||
|
||||
for i = 1, num, 1 do
|
||||
api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
text, true, false, true),
|
||||
"n", true)
|
||||
end
|
||||
end
|
||||
|
||||
M.esc = function(cmd)
|
||||
|
@ -17,9 +17,9 @@ set nocindent
|
||||
set nosmartindent
|
||||
set indentexpr=
|
||||
|
||||
|
||||
lua << EOF
|
||||
_G.__is_log = true
|
||||
require("plenary/busted")
|
||||
vim.cmd[[luafile ./tests/test_utils.lua]]
|
||||
require("nvim-autopairs").setup()
|
||||
EOF
|
||||
|
@ -1,20 +1,8 @@
|
||||
local helpers = {}
|
||||
local npairs = require('nvim-autopairs')
|
||||
_G.npairs = npairs;
|
||||
local utils = require('nvim-autopairs.utils')
|
||||
local api = vim.api
|
||||
|
||||
utils.insert_char = function(text)
|
||||
api.nvim_put({text}, "c", true, true)
|
||||
end
|
||||
|
||||
utils.feed = function(text)
|
||||
api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
text, true, false, true),
|
||||
"x", true)
|
||||
end
|
||||
local log = require('nvim-autopairs._log')
|
||||
local eq = assert.are.same
|
||||
_G.npairs = npairs;
|
||||
local eq=_G.eq
|
||||
|
||||
vim.api.nvim_set_keymap('i' , '<CR>','v:lua.npairs.check_break_line_char()', {expr = true , noremap = true})
|
||||
function helpers.feed(text, feed_opts)
|
||||
@ -32,8 +20,8 @@ local data = {
|
||||
|
||||
name = "add normal bracket" ,
|
||||
key = [[{]],
|
||||
before = [[| ]],
|
||||
after = [[{|} ]]
|
||||
before = [[x| ]],
|
||||
after = [[x{|} ]]
|
||||
},
|
||||
|
||||
{
|
||||
@ -45,8 +33,8 @@ local data = {
|
||||
{
|
||||
name = "add normal bracket" ,
|
||||
key = [[(]],
|
||||
before = [[aaaa| ]],
|
||||
after = [[aaaa(|) ]]
|
||||
before = [[aaaa|x ]],
|
||||
after = [[aaaa(|)x ]]
|
||||
},
|
||||
{
|
||||
name = "add normal quote" ,
|
||||
@ -55,19 +43,33 @@ local data = {
|
||||
after = [[aa"|" aa]]
|
||||
},
|
||||
{
|
||||
only = true,
|
||||
name = "add normal quote" ,
|
||||
|
||||
name = "add python quote" ,
|
||||
filetype = "python",
|
||||
key = [["]],
|
||||
before = [[""|]],
|
||||
after = [["""|"""]]
|
||||
before = [[""| ]],
|
||||
after = [["""|""" ]]
|
||||
},
|
||||
|
||||
{
|
||||
name = "add markdown quote" ,
|
||||
filetype = "markdown",
|
||||
key = [[`]],
|
||||
before = [[``| ]],
|
||||
after = [[```|``` ]]
|
||||
},
|
||||
{
|
||||
name = "don't add single quote with previous alphabet char" ,
|
||||
key = [[']],
|
||||
before = [[aa| aa ]],
|
||||
after = [[aa'| aa ]]
|
||||
},
|
||||
{
|
||||
name = "don't add single quote with alphabet char" ,
|
||||
key = [[']],
|
||||
before = [[a|x ]],
|
||||
after = [[a'|x ]]
|
||||
},
|
||||
-- {
|
||||
-- name = "don't add single quote with previous alphabet char" ,
|
||||
-- key = [[']],
|
||||
-- before = [[aa| aa]],
|
||||
-- after = [[aa'| aa]]
|
||||
-- },
|
||||
-- {
|
||||
-- name = "don't add single quote on end line",
|
||||
-- key = [[<right>']],
|
||||
@ -98,12 +100,12 @@ local data = {
|
||||
-- before = [[aa |aa]],
|
||||
-- after = [[aa (|aa]]
|
||||
-- },
|
||||
-- {
|
||||
-- name = "move right end line " ,
|
||||
-- key = [["]],
|
||||
-- before = [[aaaa|"]],
|
||||
-- after = [[aaaa"|]]
|
||||
-- },
|
||||
{
|
||||
name = "move right end line " ,
|
||||
key = [["]],
|
||||
before = [[aaaa|"]],
|
||||
after = [[aaaa"|]]
|
||||
},
|
||||
-- {
|
||||
-- name = "move right when inside quote" ,
|
||||
-- key = [["]],
|
||||
@ -195,7 +197,7 @@ local function Test(test_data)
|
||||
local pos = vim.fn.getpos('.')
|
||||
if value.key ~= '<cr>' then
|
||||
eq(after, result , "\n\n text error: " .. value.name .. "\n")
|
||||
eq(p_after , pos[3], "\n\n pos error: " .. value.name .. "\n")
|
||||
eq(p_after, pos[3] + 1, "\n\n pos error: " .. value.name .. "\n")
|
||||
else
|
||||
local line2 = vim.fn.getline(line + 2)
|
||||
eq(line + 1, pos[2], '\n\n breakline error:' .. value.name .. "\n")
|
||||
|
26
tests/test_utils.lua
Normal file
26
tests/test_utils.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local utils = require('nvim-autopairs.utils')
|
||||
local log = require('nvim-autopairs._log')
|
||||
local api = vim.api
|
||||
|
||||
utils.insert_char = function(text)
|
||||
api.nvim_put({text}, "c", true, true)
|
||||
end
|
||||
|
||||
utils.feed = function(text,num)
|
||||
if num > 0 then
|
||||
num = num + 1
|
||||
else
|
||||
num = 1
|
||||
end
|
||||
|
||||
local result = ''
|
||||
for _ = 1, num, 1 do
|
||||
result = result .. text
|
||||
end
|
||||
log.debug("result" .. result)
|
||||
api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
result, true, false, true),
|
||||
"x", true)
|
||||
end
|
||||
|
||||
_G.eq = assert.are.same
|
62
tests/utils_spec.lua
Normal file
62
tests/utils_spec.lua
Normal file
@ -0,0 +1,62 @@
|
||||
local utils = require('nvim-autopairs.utils')
|
||||
|
||||
local eq = assert.are.same
|
||||
|
||||
local data = {
|
||||
{
|
||||
text = "add normal bracket",
|
||||
start = 2,
|
||||
num = 2,
|
||||
result = 'dd'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
text = "iood",
|
||||
start = 1,
|
||||
num = 2,
|
||||
result = 'io'
|
||||
},
|
||||
{
|
||||
text = "add normal bracket",
|
||||
start = 0,
|
||||
num = -2,
|
||||
result = ''
|
||||
},
|
||||
|
||||
{
|
||||
text = "add normal bracket",
|
||||
start = 3,
|
||||
num = -2,
|
||||
result = 'dd'
|
||||
},
|
||||
{
|
||||
text = [["""]],
|
||||
start = 3,
|
||||
num = -3,
|
||||
result = '"""'
|
||||
},
|
||||
|
||||
{
|
||||
text = [["""]],
|
||||
start = 3,
|
||||
num = 3,
|
||||
result = '"'
|
||||
},
|
||||
|
||||
{
|
||||
text = [["""]],
|
||||
start = 2,
|
||||
num = 2,
|
||||
result = '""'
|
||||
},
|
||||
}
|
||||
|
||||
describe('utils test substring ', function()
|
||||
for _, value in pairs(data) do
|
||||
it('test sub: ' .. value.text, function()
|
||||
local result = utils.text_sub_char(value.text, value.start, value.num)
|
||||
eq(value.result, result, 'start ' .. value.start .. ' num' .. value.num)
|
||||
end)
|
||||
end
|
||||
end)
|
Loading…
Reference in New Issue
Block a user