diff --git a/doc/rules.md b/doc/rules.md index c8d750a..df5bdda 100644 --- a/doc/rules.md +++ b/doc/rules.md @@ -1,17 +1,29 @@ ## Rules -| function | usage | -|---------------------------|-----------------------------------------------------------| -| with_pair(cond) | add condition to check for pair event | -| with_move(cond) | add condition to check for move right event | -| with_cr(cond) | add condition to check for break line event | -| with_del(cond) | add condition to check for delete pair event | -| only_cr(cond) | disable move,del and pair event Only use break line event | -| use_regex(bool,"") | input pair use regex and trigger by key | -| use_key('') | change trigger key | -| replace_endpair(function) | change a map pair with function | -| end_wise(cond) | expand pair only on enter key | +| function | usage | +|---------------------------------------|-----------------------------------------------------------| +| with_pair(cond) | add condition to check for pair event | +| with_move(cond) | add condition to check for move right event | +| with_cr(cond) | add condition to check for break line event | +| with_del(cond) | add condition to check for delete pair event | +| only_cr(cond) | disable move,del and pair event Only use break line event | +| use_regex(bool,"") | input pair use regex and trigger by key | +| use_key('') | change trigger key | +| replace_endpair(fucn,{bool,func,nil}) | change a map pair with function | +| end_wise(cond) | expand pair only on enter key | +#### replace_endpair + param 2 of replace_endpair use to combine with with_pair function +``` lua + Rule("(",")") + :use_key("") + :replace_endpair(function() return "" end, true) + -- it is a shot version of this + Rule("(","") + :use_key("") + :with_pair(cond.after_text_check(")")) -- check text after cursor is ) + :replace_endpair(function() return "" end) +``` ### Condition ```lua local cond = require('nvim-autopairs.conds') @@ -20,6 +32,10 @@ local cond = require('nvim-autopairs.conds') |--------------------------------------|---------------------------------------| | none() | always wrong | | done() | always correct | +| before_text_check | check character before | +| after_text_check | check character after | +| before_regex_check | check character before with lua regex | +| after_regex_check | check character after with lua regex | | not_before_text_check(text) | check character before | | not_after_text_check(text) | check character after | | not_before_regex_check(regex,length) | check character before with lua regex | diff --git a/lua/nvim-autopairs.lua b/lua/nvim-autopairs.lua index d3bd320..b81ac94 100644 --- a/lua/nvim-autopairs.lua +++ b/lua/nvim-autopairs.lua @@ -239,7 +239,10 @@ M.autopairs_map = function(bufnr, char) local add_char = 1 for _, rule in pairs(M.state.rules) do if rule.start_pair then - if rule.is_regex and rule.key_map ~= "" then + if rule.is_regex and rule.key_map and rule.key_map ~= "" then + new_text = line:sub(1, col) .. line:sub(col + 1,#line) + add_char = 0 + elseif rule.key_map and #rule.key_map > 1 and utils.esc(rule.key_map) == char then new_text = line:sub(1, col) .. line:sub(col + 1,#line) add_char = 0 else @@ -275,14 +278,17 @@ M.autopairs_map = function(bufnr, char) local end_pair = rule:get_end_pair(cond_opt) return utils.esc(utils.repeat_key(utils.key.join_right, #end_pair)) end + if utils.is_equal(rule.start_pair, prev_char, rule.is_regex) and rule:can_pair(cond_opt) then local end_pair = rule:get_end_pair(cond_opt) + local move_text = utils.repeat_key(utils.key.join_left,#end_pair) + if rule.key_map and #rule.key_map >1 then move_text ="" end + if add_char == 0 then char = "" end - return utils.esc(char .. end_pair - .. utils.repeat_key(utils.key.join_left, #end_pair)) + return utils.esc(char .. end_pair .. move_text) end end end diff --git a/lua/nvim-autopairs/conds.lua b/lua/nvim-autopairs/conds.lua index b895990..f9bca7e 100644 --- a/lua/nvim-autopairs/conds.lua +++ b/lua/nvim-autopairs/conds.lua @@ -19,6 +19,61 @@ cond.done = function() end +cond.invert = function(func) + return function(...) + local result = func(...) + if result ~= nil then return not result end + return nil + end +end + +cond.before_regex_check = function(regex, length) + length = length or 1 + return function(opts) + log.debug('before_regex_check') + local str = utils.text_sub_char(opts.line, opts.col, - length) + if str:match(regex) then + return true + end + return false + end +end +cond.before_text_check = function(text) + local length = #text + return function(opts) + log.debug('before_text_check') + local str = utils.text_sub_char(opts.line, opts.col, - length) + if str == text then + return true + end + return false + end +end +cond.after_text_check = function(text) + local length = #text + return function(opts) + log.debug('after_text_check') + local str = utils.text_sub_char(opts.line, opts.col + 1, length) + if str == text then + return true + end + return false + end +end + +cond.after_regex_check = function(regex, length) + length = length or 1 + return function(opts) + if not regex then return end + log.debug('after_regex_check') + local str = utils.text_sub_char(opts.line, opts.col + 1, length) + if str:match(regex) then + return true + end + return false + end +end + cond.not_before_text_check = function(text) local length = #text return function(opts) diff --git a/lua/nvim-autopairs/rule.lua b/lua/nvim-autopairs/rule.lua index 285e484..1355d5c 100644 --- a/lua/nvim-autopairs/rule.lua +++ b/lua/nvim-autopairs/rule.lua @@ -1,6 +1,7 @@ local log = require('nvim-autopairs._log') local Rule = {} +local Cond = require('nvim-autopairs.conds') function Rule.new(...) local params = {...} @@ -17,6 +18,7 @@ function Rule.new(...) end end opt = vim.tbl_extend('force', { + -- set to nil mean it will skip on autopairs_map key_map = "", start_pair = nil, end_pair = nil, @@ -53,8 +55,15 @@ function Rule:get_end_pair(opts) return self.end_pair end -function Rule:replace_endpair(value) +function Rule:replace_endpair(value,check_pair) self.end_pair_func = value + if check_pair ~= nil then + if check_pair == true then + self:with_pair(Cond.after_text_check(self.end_pair)) + else + self:with_pair(check_pair) + end + end return self end diff --git a/tests/nvim-autopairs_spec.lua b/tests/nvim-autopairs_spec.lua index 31b892e..1c4c89e 100644 --- a/tests/nvim-autopairs_spec.lua +++ b/tests/nvim-autopairs_spec.lua @@ -300,27 +300,86 @@ local data = { }, { name="test javascript comment", - filetype="javascript", + filetype = "javascript", key="*", before = [[/*| ]], after = [[/**|**/ ]] }, + { + setup_func = function() + npairs.add_rules({ + Rule("(",")") + :use_key("") + :replace_endpair(function() return "" end, true) + }) + end, + name = "test map custom key" , + filetype = "latex", + key = [[]], + before = [[ abcde(|) ]], + after = [[ abcde| ]], + }, + { + setup_func = function() + npairs.add_rules { + Rule(' ', ' '):with_pair(function(opts) + local pair = opts.line:sub(opts.col, opts.col + 1) + return vim.tbl_contains({'()', '[]', '{}'}, pair) + end), + Rule('( ',' )') + :with_pair(function() return false end) + :with_del(function() return false end) + :with_move(function() return true end) + :use_regex(false,")") + } + end, + name = "test multiple move right" , + filetype = "latex", + key = [[)]], + before = [[( | ) ]], + after = [[( )| ]], + }, + { + setup_func = function() + npairs.setup({ + enable_check_bracket_line=false + }) + end, + name = "test disable check bracket line" , + filetype = "latex", + key = [[(]], + before = [[(|))) ]], + after = [[((|)))) ]], + }, + { + setup_func = function() + npairs.add_rules({ + Rule("<", ">",{"rust"}) + :with_pair(cond.before_text_check("Vec")) + }) + end, + name = "test disable check bracket line" , + filetype = "rust", + key = [[<]], + before = [[Vec| ]], + after = [[Vec<|> ]], + }, } local run_data = {} -local isOnly = false for _, value in pairs(data) do if value.only == true then table.insert(run_data, value) - isOnly = true break end end if #run_data == 0 then run_data = data end +local reset_test = function() npairs.setup() end local function Test(test_data) for _, value in pairs(test_data) do it("test "..value.name, function() + if value.setup_func then value.setup_func() end local before = string.gsub(value.before , '%|' , "") local after = string.gsub(value.after , '%|' , "") local p_before = string.find(value.before , '%|') @@ -351,65 +410,12 @@ local function Test(test_data) vim.fn.setline(line+ 1, '') vim.fn.setline(line+ 2, '') end + if value.reset_func then value.reset_func() end + if not value.reset_func and value.setup_func then reset_test() end end) end end describe('autopairs ', function() Test(run_data) - if isOnly then return end - npairs.add_rules({ - Rule("$$", "$$",{"tex", "latex"}) - -- don't add a pair if the next character is % - :with_pair(cond.not_after_regex_check("%%")) - }) - run_data = { - { - name = "test add_rules" , - filetype = "latex", - key = [[$]], - before = [[asdas$| ]], - after = [[asdas$$|$$ ]], - }, - } - Test(run_data) - npairs.setup({ - enable_check_bracket_line=false - }) - - run_data = { - { - name = "test disable check bracket line" , - filetype = "latex", - key = [[(]], - before = [[(|))) ]], - after = [[((|)))) ]], - }, - } - - Test(run_data) - - npairs.setup({}) - npairs.add_rules { - Rule(' ', ' '):with_pair(function(opts) - local pair = opts.line:sub(opts.col, opts.col + 1) - return vim.tbl_contains({'()', '[]', '{}'}, pair) - end), - Rule('( ',' )') - :with_pair(function() return false end) - :with_del(function() return false end) - :with_move(function() return true end) - :use_regex(false,")") - } - run_data={ - { - name = "test disable check bracket line" , - filetype = "latex", - key = [[)]], - before = [[( | ) ]], - after = [[( )| ]], - }, - } - - Test(run_data) end)