nvim-autopairs
A super powerful autopairs for Neovim. It support multiple character.
Requires neovim 0.5+
Setup
require('nvim-autopairs').setup{}
Default values
local map_bs = true -- map the <BS> key local disable_filetype = { "TelescopePrompt" } local ignored_next_char = string.gsub([[ [%w%%%'%[%"%.] ]],"%s+", "") local enable_moveright = true local enable_afterquote = true -- add bracket pairs after quote local enable_check_bracket_line = true --- check bracket in same line local check_ts = false
Override default values
require('nvim-autopairs').setup({ disable_filetype = { "TelescopePrompt" , "vim" }, })
Mapping <CR>
Before Input After
------------------------------------
{|} <CR> {
|
}
------------------------------------
nvim-compe
require("nvim-autopairs.completion.compe").setup({ map_cr = true, -- map <CR> on insert mode map_complete = true, -- it will auto insert `(` after select function or method item auto_select = false, -- auto select first item })
Make sure to remove mapping insert mode <CR>
binding if you have it.
nvim-cmp
-- you need setup cmp first put this after cmp.setup() require("nvim-autopairs.completion.cmp").setup({ map_cr = true, -- map <CR> on insert mode map_complete = true, -- it will auto insert `(` after select function or method item auto_select = true -- automatically select the first item })
Make sure to remove mapping insert mode <CR>
binding if you have it.
completion nvim
local remap = vim.api.nvim_set_keymap local npairs = require('nvim-autopairs') -- skip it, if you use another global object _G.MUtils= {} vim.g.completion_confirm_key = "" MUtils.completion_confirm=function() if vim.fn.pumvisible() ~= 0 then if vim.fn.complete_info()["selected"] ~= -1 then require'completion'.confirmCompletion() return npairs.esc("<c-y>") else vim.api.nvim_select_popupmenu_item(0 , false , false ,{}) require'completion'.confirmCompletion() return npairs.esc("<c-n><c-y>") end else return npairs.autopairs_cr() end end remap('i' , '<CR>','v:lua.MUtils.completion_confirm()', {expr = true , noremap = true})
coq_nvim
local remap = vim.api.nvim_set_keymap local npairs = require('nvim-autopairs') npairs.setup({ map_bs = false }) vim.g.coq_settings = { keymap = { recommended = false } } -- these mappings are coq recommended mappings unrelated to nvim-autopairs remap('i', '<esc>', [[pumvisible() ? "<c-e><esc>" : "<esc>"]], { expr = true, noremap = true }) remap('i', '<c-c>', [[pumvisible() ? "<c-e><c-c>" : "<c-c>"]], { expr = true, noremap = true }) remap('i', '<tab>', [[pumvisible() ? "<c-n>" : "<tab>"]], { expr = true, noremap = true }) remap('i', '<s-tab>', [[pumvisible() ? "<c-p>" : "<bs>"]], { expr = true, noremap = true }) -- skip it, if you use another global object _G.MUtils= {} MUtils.CR = function() if vim.fn.pumvisible() ~= 0 then if vim.fn.complete_info({ 'selected' }).selected ~= -1 then return npairs.esc('<c-y>') else -- you can change <c-g><c-g> to <c-e> if you don't use other i_CTRL-X modes return npairs.esc('<c-g><c-g>') .. npairs.autopairs_cr() end else return npairs.autopairs_cr() end end remap('i', '<cr>', 'v:lua.MUtils.CR()', { expr = true, noremap = true }) MUtils.BS = function() if vim.fn.pumvisible() ~= 0 and vim.fn.complete_info({ 'mode' }).mode == 'eval' then return npairs.esc('<c-e>') .. npairs.autopairs_bs() else return npairs.autopairs_bs() end end remap('i', '<bs>', 'v:lua.MUtils.BS()', { expr = true, noremap = true })
without completion plugin
local remap = vim.api.nvim_set_keymap local npairs = require('nvim-autopairs') -- skip it, if you use another global object _G.MUtils= {} MUtils.completion_confirm=function() if vim.fn.pumvisible() ~= 0 then return npairs.esc("<cr>") else return npairs.autopairs_cr() end end remap('i' , '<CR>','v:lua.MUtils.completion_confirm()', {expr = true , noremap = true})
If you have a problem with indent after press <CR>
Please check setting of treesitter indent or install plugin support indent on your filetype
Rule
nvim-autopairs use rule with condition to check pair.
local Rule = require('nvim-autopairs.rule') local npairs = require('nvim-autopairs') npairs.add_rule(Rule("$$","$$","tex")) -- you can use some built-in condition local cond = require('nvim-autopairs.conds') 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(opts) print(vim.inspect(opts)) if opts.line=="aa $$" then -- don't add pair on that line return false end end) } ) -- you can use regex -- press u1234 => u1234number npairs.add_rules({ Rule("u%d%d%d%d$", "number", "lua") :use_regex(true) }) -- press x1234 => x12341234 npairs.add_rules({ Rule("x%d%d%d%d$", "number", "lua") :use_regex(true) :replace_endpair(function(opts) -- print(vim.inspect(opts)) return opts.prev_char:sub(#opts.prev_char - 3,#opts.prev_char) end) }) -- you can do anything with regex +special key -- example press tab will upper text -- press b1234s<tab> => B1234S1234S npairs.add_rules({ Rule("b%d%d%d%d%w$", "", "vim") :use_regex(true,"<tab>") :replace_endpair(function(opts) return opts.prev_char:sub(#opts.prev_char - 4,#opts.prev_char) .."<esc>viwU" end) }) -- you can exclude filetypes npairs.add_rule( Rule("$$","$$") :with_pair(cond.not_filetypes({"lua"})) ) --- check ./lua/nvim-autopairs/rules/basic.lua
Treesitter
You can use treesitter to check pair
local npairs = require("nvim-autopairs") npairs.setup({ check_ts = true, ts_config = { lua = {'string'},-- it will not add pair on that treesitter node javascript = {'template_string'}, java = false,-- don't check treesitter on java } }) require('nvim-treesitter.configs').setup { autopairs = {enable = true} } local ts_conds = require('nvim-autopairs.ts-conds') -- press % => %% is only inside comment or string npairs.add_rules({ Rule("%", "%", "lua") :with_pair(ts_conds.is_ts_node({'string','comment'})), Rule("$", "$", "lua") :with_pair(ts_conds.is_not_ts_node({'function'})) })
Don't add pairs if it already have a close pairs in same line
if next character is a close pairs and it doesn't have an open pairs in same line then it will not add a close pairs
Before Input After
------------------------------------
( |)) ( ( (|))
require('nvim-autopairs').setup({ enable_check_bracket_line = false })
Don't add pairs if the next char is alphanumeric
You can customize how nvim-autopairs will behave if it encounters a specific character
require('nvim-autopairs').setup({ ignored_next_char = "[%w%.]" -- will ignore alphanumeric and `.` symbol })
Before Input After
------------------------------------
|foobar ( (|foobar
|.foobar ( (|.foobar
Plugin Integration
require('nvim-autopairs').disable() require('nvim-autopairs').enable() require('nvim-autopairs').remove_rule('(')-- remove rule ( require('nvim-autopairs').clear_rules() -- clear all rule require('nvim-autopairs').get_rule('"') -- get rule " then modify it
FastWrap
Before Input After
--------------------------------------------------
(|foobar <M-e> then press $ (|foobar)
(|)(foobar) <M-e> then press q (|(foobar))
-- put this to setup function and press <a-e> to use fast_wrap npairs.setup({ fast_wrap = {}, }) -- change default fast_wrap npairs.setup({ fast_wrap = { map = '<M-e>', chars = { '{', '[', '(', '"', "'" }, pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]], '%s+', ''), end_key = '$', keys = 'qwertyuiopzxcvbnmasdfghjkl', check_comma = true, hightlight = 'Search' }, })