mirror of
https://github.com/ilyakooo0/nvim-autopairs.git
synced 2024-09-11 07:15:44 +03:00
update
This commit is contained in:
parent
d55ab8ae10
commit
fd20894296
74
README.md
74
README.md
@ -1,6 +1,7 @@
|
||||
## nvim-autopairs
|
||||
|
||||
A minimalist autopairs for Neovim written by Lua.
|
||||
It can support multipple character
|
||||
|
||||
Requires neovim 0.5+
|
||||
|
||||
@ -13,17 +14,8 @@ require('nvim-autopairs').setup()
|
||||
## Default values
|
||||
|
||||
``` lua
|
||||
local pairs_map = {
|
||||
["'"] = "'",
|
||||
['"'] = '"',
|
||||
['('] = ')',
|
||||
['['] = ']',
|
||||
['{'] = '}',
|
||||
['`'] = '`',
|
||||
}
|
||||
|
||||
local disable_filetype = { "TelescopePrompt" }
|
||||
local break_line_filetype = nil -- mean all file type
|
||||
local html_break_line_filetype = {'html' , 'vue' , 'typescriptreact' , 'svelte' , 'javascriptreact'}
|
||||
local ignored_next_char = "%w"
|
||||
|
||||
```
|
||||
@ -37,8 +29,49 @@ require('nvim-autopairs').setup({
|
||||
```
|
||||
### Rule
|
||||
|
||||
- Pairs map only accept 1 character
|
||||
- You can use regex on filetype
|
||||
It can support multipple character
|
||||
|
||||
``` lua
|
||||
local Rule = require('nvim-autopairs.rule')
|
||||
local npairs = require('nvim-autopairs')
|
||||
|
||||
npairs.add_rule({
|
||||
Rule("$$","$$","tex")
|
||||
})
|
||||
-- you can use some builtin condition
|
||||
|
||||
local cond = require('nvim-autopairs.cond')
|
||||
print(vim.inspect(cond))
|
||||
|
||||
npairs.add_rules({
|
||||
Rule("$", "$",{"tex", "latex"})
|
||||
-- don't add a pair if the next character is %
|
||||
:with_pair(cond.not_after_regex_check("%%"))
|
||||
-- don't add a pair if the previous character is xxx
|
||||
:with_pair(cond.not_before_regex_check("xxx", 3))
|
||||
-- don't move right when repeat character
|
||||
:with_move(cond.none())
|
||||
-- don't delete if the next character is xx
|
||||
:with_del(cond.not_after_regex_check("xx"))
|
||||
-- disable add newline when press <cr>
|
||||
:with_cr(cond.none())
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
npairs.add_rules({
|
||||
Rule("$$","$$","tex")
|
||||
:with_pair(function(otps)
|
||||
print(vim.inspect(otps))
|
||||
if opts.line=="aa $$" then
|
||||
-- don't add pair on that line
|
||||
return false
|
||||
end
|
||||
end)
|
||||
}
|
||||
)
|
||||
--- check ./lua/nvim-autopairs/rules/basic.lua
|
||||
```
|
||||
|
||||
### Break line on html or inside pairs
|
||||
|
||||
@ -81,7 +114,7 @@ MUtils.completion_confirm=function()
|
||||
return npairs.esc("<c-n><c-y>")
|
||||
end
|
||||
else
|
||||
return npairs.check_break_line_char()
|
||||
return npairs.autopairs_cr()
|
||||
end
|
||||
end
|
||||
|
||||
@ -89,6 +122,7 @@ end
|
||||
remap('i' , '<CR>','v:lua.MUtils.completion_confirm()', {expr = true , noremap = true})
|
||||
```
|
||||
#### using nvim-compe
|
||||
|
||||
``` lua
|
||||
local remap = vim.api.nvim_set_keymap
|
||||
local npairs = require('nvim-autopairs')
|
||||
@ -108,7 +142,7 @@ MUtils.completion_confirm=function()
|
||||
return npairs.esc("<c-n>")
|
||||
end
|
||||
else
|
||||
return npairs.check_break_line_char()
|
||||
return npairs.autopairs_cr()
|
||||
end
|
||||
end
|
||||
|
||||
@ -166,16 +200,4 @@ Before Input After
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
- Is this support autopair of 2 character?
|
||||
> No, Any PR is welcome :)
|
||||
|
||||
- Do you have any plan to add more feature (flymode ,end-wise) ?
|
||||
>No, It is a minimalist autopairs.
|
||||
>I don't want to make everything complicated.
|
||||
>
|
||||
>If you want a flymode or something else you can use [jiangmiao autopairs](https://github.com/jiangmiao/auto-pairs)
|
||||
>
|
||||
>If you want more feature please try to use [lexima](https://github.com/cohama/lexima.vim)
|
||||
|
||||
https://github.com/tpope/vim-endwise
|
||||
|
@ -23,7 +23,27 @@ M.setup = function(opt)
|
||||
]],false)
|
||||
end
|
||||
|
||||
M.add_rule = function (rule)
|
||||
table.insert(M.config.rules, rule)
|
||||
end
|
||||
|
||||
|
||||
M.disable=function()
|
||||
state.disabled = true
|
||||
end
|
||||
|
||||
M.enable = function()
|
||||
state.disabled = false
|
||||
end
|
||||
|
||||
M.add_rules = function (rules)
|
||||
for _, rule in pairs(rules) do
|
||||
table.insert(M.config.rules, rule)
|
||||
end
|
||||
end
|
||||
|
||||
M.on_attach = function(bufnr)
|
||||
if state.disabled then return end
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
if not utils.check_disable_ft(M.config.disable_filetype, vim.bo.filetype) then return end
|
||||
local rules = {};
|
||||
@ -55,6 +75,7 @@ M.on_attach = function(bufnr)
|
||||
end
|
||||
|
||||
M.autopairs_bs = function(bufnr)
|
||||
if state.disabled then return end
|
||||
local line = utils.text_get_current_line(bufnr)
|
||||
local _, col = utils.get_cursor()
|
||||
local filetype = vim.bo.filetype
|
||||
@ -92,55 +113,56 @@ end
|
||||
local skip_next = false
|
||||
|
||||
M.autopairs_insert = function(bufnr, char)
|
||||
if state.disabled then 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)
|
||||
-- log.debug("char:" .. char)
|
||||
local _, col = utils.get_cursor()
|
||||
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
|
||||
if rule.start_pair then
|
||||
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)
|
||||
if prev_char == rule.start_pair then
|
||||
-- log.debug("start_pair" .. rule.start_pair)
|
||||
-- log.debug('prev_char' .. prev_char)
|
||||
-- log.debug('next_char' .. next_char)
|
||||
local cond_opt = {
|
||||
text = new_text,
|
||||
rule = rule,
|
||||
bufnr = bufnr,
|
||||
col = col,
|
||||
char = char,
|
||||
line = line,
|
||||
prev_char = prev_char,
|
||||
next_char = next_char,
|
||||
}
|
||||
local next_char = utils.text_sub_char(new_text, col + 2,#rule.end_pair)
|
||||
local cond_opt = {
|
||||
text = new_text,
|
||||
rule = rule,
|
||||
bufnr = bufnr,
|
||||
col = col,
|
||||
char = char,
|
||||
line = line,
|
||||
prev_char = prev_char,
|
||||
next_char = next_char,
|
||||
}
|
||||
-- log.debug("start_pair" .. rule.start_pair)
|
||||
-- log.debug('prev_char' .. prev_char)
|
||||
-- log.debug('next_char' .. next_char)
|
||||
if
|
||||
next_char == rule.end_pair
|
||||
and rule:can_move(cond_opt)
|
||||
then
|
||||
utils.reset_vchar()
|
||||
vim.schedule(function()
|
||||
utils.feed(utils.key.right, -1)
|
||||
end)
|
||||
return false
|
||||
end
|
||||
|
||||
if rule:can_move(cond_opt) then
|
||||
utils.reset_vchar()
|
||||
vim.schedule(function()
|
||||
utils.feed(utils.key.right, -1)
|
||||
end)
|
||||
return false
|
||||
end
|
||||
|
||||
if rule:can_pair(cond_opt) then
|
||||
vim.schedule(function()
|
||||
utils.insert_char(rule.end_pair)
|
||||
utils.feed(utils.key.left, #rule.end_pair)
|
||||
end)
|
||||
return
|
||||
end
|
||||
if
|
||||
prev_char == rule.start_pair
|
||||
and rule:can_pair(cond_opt)
|
||||
then
|
||||
vim.schedule(function()
|
||||
utils.insert_char(rule.end_pair)
|
||||
utils.feed(utils.key.left, #rule.end_pair)
|
||||
end)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
M.autopairs_cr = function(bufnr)
|
||||
if state.disabled then return end
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local line = utils.text_get_current_line(bufnr)
|
||||
local _, col = utils.get_cursor()
|
||||
@ -148,10 +170,16 @@ M.autopairs_cr = function(bufnr)
|
||||
for _, rule in pairs(state.rules) do
|
||||
if rule.start_pair and utils.check_filetype(rule.filetypes, filetype) then
|
||||
local prev_char = utils.text_sub_char(line, col,-#rule.start_pair)
|
||||
local next_char = utils.text_sub_char(line, col+1,#rule.start_pair)
|
||||
local next_char = utils.text_sub_char(line, col+1,#rule.end_pair)
|
||||
if
|
||||
rule.start_pair == prev_char
|
||||
and rule.end_pair == next_char
|
||||
and rule:can_cr({
|
||||
bufnr = bufnr,
|
||||
prev_char = prev_char,
|
||||
next_char = next_char,
|
||||
line = line
|
||||
})
|
||||
then
|
||||
return utils.esc("<cr><c-o>O")
|
||||
end
|
||||
|
@ -1,14 +0,0 @@
|
||||
local M={}
|
||||
|
||||
|
||||
M.check_previous_word = function (regex)
|
||||
return function(opt)
|
||||
return opt.pre_word:match(regex) ~= nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
return
|
||||
|
@ -2,53 +2,94 @@ local utils = require('nvim-autopairs.utils')
|
||||
local log = require('nvim-autopairs._log')
|
||||
local cond={}
|
||||
|
||||
-- cond
|
||||
-- @return false when it is not correct
|
||||
-- true when it is correct
|
||||
-- nil when it is not determine
|
||||
|
||||
|
||||
cond.none = function()
|
||||
return function() return false end
|
||||
end
|
||||
|
||||
|
||||
cond.done = function()
|
||||
return function() return true end
|
||||
end
|
||||
|
||||
cond.not_before_regex_check = function(regex, length)
|
||||
length = length or 1
|
||||
return function(opts)
|
||||
log.debug('not_before_regex_check')
|
||||
local str = utils.text_sub_char(opts.line, opts.col, - length)
|
||||
if str:match(regex) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
cond.not_after_regex_check = function(regex, length)
|
||||
length = length or 1
|
||||
return function(opts)
|
||||
log.debug('not_after_regex_check')
|
||||
local str = utils.text_sub_char(opts.line, opts.col + 1, length)
|
||||
if str:match(regex) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
cond.not_add_quote_inside_quote=function()
|
||||
cond.check_is_bracket_line=function ()
|
||||
return function(opts)
|
||||
log.debug('check_is_bracket_line')
|
||||
if
|
||||
utils.is_bracket(opts.char)
|
||||
and opts.next_char == opts.rule.end_pair
|
||||
then
|
||||
-- (( many char |)) => add
|
||||
-- ( many char |)) => not add
|
||||
local count_prev_char = 0
|
||||
local count_next_char = 0
|
||||
for i = 1, #opts.line, 1 do
|
||||
local c = opts.line:sub(i, i)
|
||||
if c == opts.char then
|
||||
count_prev_char = count_prev_char + 1
|
||||
elseif c == opts.rule.end_pair then
|
||||
count_next_char = count_next_char + 1
|
||||
end
|
||||
end
|
||||
if count_prev_char ~= count_next_char then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cond.not_add_quote_inside_quote = function()
|
||||
return function(opts)
|
||||
log.debug('not_add_quote_inside_quote')
|
||||
if
|
||||
utils.is_quote(opts.char)
|
||||
and utils.is_in_quote(opts.text, opts.col, opts.char)
|
||||
then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
cond.move_right = function ()
|
||||
return function(opts)
|
||||
log.debug("move_right")
|
||||
if utils.is_close_bracket(opts.char) then
|
||||
return true
|
||||
end
|
||||
-- move right when have quote on end line or in quote
|
||||
-- situtaion |" => "|
|
||||
if
|
||||
utils.is_quote(opts.char)
|
||||
and opts.next_char == opts.char
|
||||
then
|
||||
if opts.col + 1 == string.len(opts.line) then
|
||||
log.debug("move right correct")
|
||||
return true
|
||||
end
|
||||
-- ("|") => (""|)
|
||||
|
@ -23,9 +23,9 @@ function Rule.new(...)
|
||||
-- allow move when press close_pairs
|
||||
move_cond = nil,
|
||||
-- allow delete when press bs
|
||||
del_cond = {function() return true end},
|
||||
cr_cond = {function() return true end},
|
||||
pair_cond = {function() return true end},
|
||||
del_cond = {},
|
||||
cr_cond = {},
|
||||
pair_cond = {},
|
||||
},opt)
|
||||
return setmetatable(opt, {__index = Rule})
|
||||
end
|
||||
@ -42,18 +42,31 @@ function Rule:with_del(cond)
|
||||
return self
|
||||
end
|
||||
|
||||
function Rule:with_pair(cond)
|
||||
if self.pair_cond == nil then self.pair_cond = {}end
|
||||
table.insert(self.pair_cond, cond)
|
||||
|
||||
function Rule:with_cr(cond)
|
||||
if self.cr_cond == nil then self.cr_cond = {}end
|
||||
table.insert(self.cr_cond, cond)
|
||||
return self
|
||||
end
|
||||
|
||||
function Rule:with_pair(cond)
|
||||
if self.pair_cond == nil then self.pair_cond = {}end
|
||||
table.insert(self.pair_cond, cond)
|
||||
if self=="dafs" the
|
||||
return self
|
||||
end
|
||||
|
||||
function Rule:end_wise()
|
||||
|
||||
return self
|
||||
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
|
||||
local result = cond(opt)
|
||||
if result ~= nil then
|
||||
return result
|
||||
end
|
||||
end
|
||||
return true
|
||||
@ -81,4 +94,4 @@ function Rule:can_cr(opt)
|
||||
return can_do(self.cr_cond, opt)
|
||||
end
|
||||
|
||||
return {new = Rule.new}
|
||||
return Rule.new
|
||||
|
@ -1,9 +1,6 @@
|
||||
|
||||
local Rule = require('nvim-autopairs.rule').new
|
||||
local log = require('nvim-autopairs._log')
|
||||
local Rule = require('nvim-autopairs.rule')
|
||||
local cond = require('nvim-autopairs.conds')
|
||||
|
||||
|
||||
local function setup(opt)
|
||||
local basic = function(...)
|
||||
return Rule(...)
|
||||
@ -12,15 +9,19 @@ local function setup(opt)
|
||||
:with_pair(cond.not_add_quote_inside_quote())
|
||||
end
|
||||
local rules = {
|
||||
Rule("<!--", "-->", 'html'):with_cr(cond.none()),
|
||||
Rule("```", "```", 'markdown'),
|
||||
Rule('"""', '"""', 'python'),
|
||||
basic("'", "'")
|
||||
:with_pair(cond.not_before_regex_check("%w")) ,
|
||||
basic("`", "`"),
|
||||
basic('"', '"'),
|
||||
basic("(", ")"),
|
||||
basic("[", "]"),
|
||||
basic("{", "}"),
|
||||
basic("(", ")")
|
||||
:with_pair(cond.check_is_bracket_line()),
|
||||
basic("[", "]")
|
||||
:with_pair(cond.check_is_bracket_line()),
|
||||
basic("{", "}")
|
||||
:with_pair(cond.check_is_bracket_line()),
|
||||
Rule(">", "<",
|
||||
{ 'html', 'typescript', 'typescriptreact', 'svelte', 'vue'})
|
||||
:with_move(cond.none())
|
||||
|
@ -17,6 +17,15 @@ M.is_quote = function (char)
|
||||
return char == "'" or char == '"' or char == '`'
|
||||
end
|
||||
|
||||
M.is_bracket = function (char)
|
||||
return char == "(" or char == '[' or char == '{'
|
||||
end
|
||||
|
||||
|
||||
M.is_close_bracket = function (char)
|
||||
return char == ")" or char == ']' or char == '}'
|
||||
end
|
||||
|
||||
M.is_in_quote = function(line, pos, quote)
|
||||
local cIndex = 0
|
||||
local result = false
|
||||
|
@ -18,7 +18,7 @@ set nosmartindent
|
||||
set indentexpr=
|
||||
|
||||
lua << EOF
|
||||
_G.__is_log = true
|
||||
-- _G.__is_log = true
|
||||
require("plenary/busted")
|
||||
vim.cmd[[luafile ./tests/test_utils.lua]]
|
||||
require("nvim-autopairs").setup()
|
||||
|
@ -107,7 +107,12 @@ local data = {
|
||||
before = [[aa |.aa]],
|
||||
after = [[aa (|.aa]]
|
||||
},
|
||||
|
||||
{
|
||||
name = "don't add bracket have open bracket in same line" ,
|
||||
key = [[(]],
|
||||
before = [[( many char |))]],
|
||||
after = [[( many char (|))]]
|
||||
},
|
||||
{
|
||||
name = "move right end line " ,
|
||||
key = [["]],
|
||||
@ -121,6 +126,18 @@ local data = {
|
||||
after = [[("abcd"|)]]
|
||||
},
|
||||
|
||||
{
|
||||
name = "move right square bracket" ,
|
||||
key = [[)]],
|
||||
before = [[("abcd|) ]],
|
||||
after = [[("abcd)| ]]
|
||||
},
|
||||
{
|
||||
name = "move right bracket" ,
|
||||
key = [[}]],
|
||||
before = [[("abcd|}} ]],
|
||||
after = [[("abcd}|} ]]
|
||||
},
|
||||
{
|
||||
name = "move right when inside grave with special slash" ,
|
||||
key = [[`]],
|
||||
@ -133,6 +150,7 @@ local data = {
|
||||
before = [[("abcd\"|")]],
|
||||
after = [[("abcd\""|)]]
|
||||
},
|
||||
|
||||
{
|
||||
name = "move right when inside single quote with special slash",
|
||||
filetype="javascript",
|
||||
@ -199,7 +217,6 @@ if #run_data == 0 then run_data = data end
|
||||
local function Test(test_data)
|
||||
for _, value in pairs(test_data) do
|
||||
it("test "..value.name, function()
|
||||
log.debug("Start" .. value.name)
|
||||
local before = string.gsub(value.before , '%|' , "")
|
||||
local after = string.gsub(value.after , '%|' , "")
|
||||
local p_before = string.find(value.before , '%|')
|
||||
@ -213,7 +230,6 @@ local function Test(test_data)
|
||||
npairs.on_attach(vim.api.nvim_get_current_buf())
|
||||
vim.fn.setline(line , before)
|
||||
vim.fn.setpos('.' ,{0, line, p_before , 0})
|
||||
log.debug("insert " .. value.key)
|
||||
helpers.insert(value.key)
|
||||
vim.wait(10)
|
||||
helpers.feed("<esc>")
|
||||
|
@ -17,7 +17,7 @@ utils.feed = function(text,num)
|
||||
for _ = 1, num, 1 do
|
||||
result = result .. text
|
||||
end
|
||||
log.debug("result" .. result)
|
||||
-- log.debug("result" .. result)
|
||||
api.nvim_feedkeys (api.nvim_replace_termcodes(
|
||||
result, true, false, true),
|
||||
"x", true)
|
||||
|
Loading…
Reference in New Issue
Block a user