@@ -19,15 +19,13 @@ local default = {
1919 disable_filetype = { 'TelescopePrompt', 'spectre_panel' },
2020 disable_in_macro = false,
2121 disable_in_visualblock = false,
22− disable_in_replace_mode = true,
23− ignored_next_char = [=[[%w%%%'%[%"%.%`%$]]=],
22+ ignored_next_char = [=[[%w%%%'%[%"%.]]=],
2423 break_undo = true,
2524 check_ts = false,
2625 enable_moveright = true,
2726 enable_afterquote = true,
2827 enable_check_bracket_line = true,
2928 enable_bracket_in_quote = true,
30− enable_abbr = false,
3129 ts_config = {
3230 lua = { 'string', 'source' },
3331 javascript = { 'string', 'template_string' },
@@ -54,21 +52,18 @@ M.setup = function(opt)
5452 end
5553
5654 M.force_attach()
57− local group = api.nvim_create_augroup('autopairs_buf', { clear = true })
58− api.nvim_create_autocmd({ 'BufEnter', 'BufWinEnter' }, {
59− group = group, pattern = '*',
60− callback = function() M.on_attach() end
61− })
62− api.nvim_create_autocmd('BufDelete', {
63− group = group, pattern = '*',
64− callback = function(data)
65− M.set_buf_rule(nil, tonumber(data.buf) or 0)
66− end,
67− })
68− api.nvim_create_autocmd('FileType', {
69− group = group, pattern = '*',
70− callback = function() M.force_attach() end
71− })
55+
56+ api.nvim_exec(
57+ [[
58+ augroup autopairs_buf
59+ autocmd!
60+ autocmd BufEnter,BufWinEnter * lua require("nvim-autopairs").on_attach()
61+ autocmd BufDelete * lua require("nvim-autopairs").set_buf_rule(nil,tonumber(vim.fn.expand("<abuf>")))
62+ autocmd FileType * lua require("nvim-autopairs").force_attach()
63+ augroup end
64+ ]],
65+ false
66+ )
7267end
7368
7469M.add_rule = function(rule)
@@ -103,10 +98,10 @@ M.remove_rule = function(pair)
10398 if r.start_pair ~= pair then
10499 table.insert(state_tbl, r)
105100 elseif r.key_map and r.key_map ~= '' then
106− api.nvim_buf_del_keymap(0, 'i', r.key_map)
101+ vim.api.nvim_buf_del_keymap(0, 'i', r.key_map)
107102 end
108103 end
109− M.set_buf_rule(state_tbl, 0)
104+ M.set_buf_rule(state_tbl)
110105 end
111106 M.force_attach()
112107end
@@ -137,15 +132,6 @@ M.force_attach = function(bufnr)
137132 M.on_attach(bufnr)
138133end
139134
140−local del_keymaps = function()
141− local status, autopairs_keymaps = pcall(api.nvim_buf_get_var, 0, 'autopairs_keymaps')
142− if status and autopairs_keymaps and #autopairs_keymaps > 0 then
143− for _, key in pairs(autopairs_keymaps) do
144− pcall(api.nvim_buf_del_keymap, 0, 'i', key)
145− end
146− end
147−end
148−
149135local function is_disable()
150136 if M.state.disabled then
151137 return true
@@ -160,23 +146,22 @@ local function is_disable()
160146 return true
161147 end
162148
163− if M.config.disable_in_macro
149+ if
150+ M.config.disable_in_macro
164151 and (vim.fn.reg_recording() ~= '' or vim.fn.reg_executing() ~= '')
165152 then
166153 return true
167154 end
168155
169− if M.config.disable_in_replace_mode and vim.api.nvim_get_mode().mode == "R" then
170− return true
171− end
172−
173156 if M.config.disable_in_visualblock and utils.is_block_wise_mode() then
174157 return true
175158 end
176159
177160 if utils.check_filetype(M.config.disable_filetype, vim.bo.filetype) then
178− del_keymaps()
179− M.set_buf_rule({}, 0)
161+ -- should have a way to remove the mapping when vim.bo.filetype = ''
162+ -- now we only remove a rule
163+ -- the event FileType happen after BufEnter
164+ M.set_buf_rule({})
180165 return true
181166 end
182167 return false
@@ -184,14 +169,14 @@ end
184169
185170---@return table <number, Rule>
186171M.get_buf_rules = function(bufnr)
187− return M.state.rules[bufnr or api.nvim_get_current_buf()] or {}
172+ return M.state.rules[bufnr or vim.api.nvim_get_current_buf()] or {}
188173end
189174
190−---@param rules nil|table list or rule
175+---@param rules table list or rule
191176---@param bufnr number buffer number
192177M.set_buf_rule = function(rules, bufnr)
193178 if bufnr == 0 or bufnr == nil then
194− bufnr = api.nvim_get_current_buf()
179+ bufnr = vim.api.nvim_get_current_buf()
195180 end
196181 M.state.rules[bufnr] = rules
197182end
@@ -205,7 +190,8 @@ M.on_attach = function(bufnr)
205190
206191 local rules = {}
207192 for _, rule in pairs(M.config.rules) do
208− if utils.check_filetype(rule.filetypes, vim.bo.filetype)
193+ if
194+ utils.check_filetype(rule.filetypes, vim.bo.filetype)
209195 and utils.check_not_filetype(rule.not_filetypes, vim.bo.filetype)
210196 then
211197 table.insert(rules, rule)
@@ -241,50 +227,78 @@ M.on_attach = function(bufnr)
241227 if utils.is_attached(bufnr) then
242228 return
243229 end
244− del_keymaps()
245230 local enable_insert_auto = false
246− local autopairs_keymaps = {}
247− local expr_map = function(key)
248− api.nvim_buf_set_keymap(bufnr, 'i', key, '', {
249− expr = true,
250− noremap = true,
251− desc = "autopairs map key",
252− callback = function() return M.autopairs_map(bufnr, key) end,
253− })
254− table.insert(autopairs_keymaps, key)
255− end
256231 for _, rule in pairs(rules) do
257232 if rule.key_map ~= nil then
258233 if rule.is_regex == false then
259234 if rule.key_map == '' then
260235 rule.key_map = rule.start_pair:sub(#rule.start_pair)
261236 end
262− expr_map(rule.key_map)
237+ local key = string.format('"%s"', rule.key_map)
238+ if rule.key_map == '"' then
239+ key = [['"']]
240+ end
241+ local mapping = string.format('v:lua.MPairs.autopairs_map(%d,%s)', bufnr, key)
242+ api.nvim_buf_set_keymap(
243+ bufnr,
244+ 'i',
245+ rule.key_map,
246+ mapping,
247+ { expr = true, noremap = true }
248+ )
249+
263250 local key_end = rule.key_end or rule.end_pair:sub(1, 1)
264251 if #key_end >= 1 and key_end ~= rule.key_map and rule.move_cond ~= nil then
265− expr_map(key_end)
252+ mapping = string.format(
253+ [[v:lua.MPairs.autopairs_map(%d, '%s')]],
254+ bufnr,
255+ key_end
256+ )
257+ vim.api.nvim_buf_set_keymap(
258+ bufnr,
259+ 'i',
260+ key_end,
261+ mapping,
262+ { expr = true, noremap = true }
263+ )
266264 end
267265 else
268266 if rule.key_map ~= '' then
269− expr_map(rule.key_map)
267+ local mapping = string.format(
268+ "v:lua.MPairs.autopairs_map(%d,'%s')",
269+ bufnr,
270+ rule.key_map
271+ )
272+ api.nvim_buf_set_keymap(
273+ bufnr,
274+ 'i',
275+ rule.key_map,
276+ mapping,
277+ { expr = true, noremap = true }
278+ )
270279 elseif rule.is_endwise == false then
271280 enable_insert_auto = true
272281 end
273282 end
274283 end
275284 end
276− api.nvim_buf_set_var(bufnr, 'autopairs_keymaps', autopairs_keymaps)
277285
278286 if enable_insert_auto then
279287 -- capture all key use it to trigger regex pairs
280288 -- it can make an issue with paste from register
281− api.nvim_create_autocmd('InsertCharPre', {
282− group = api.nvim_create_augroup(string.format("autopairs_insert_%d", bufnr), { clear = true }),
283− buffer = bufnr,
284− callback = function()
285− M.autopairs_insert(bufnr, vim.v.char)
286− end
287− })
289+ api.nvim_exec(
290+ string.format(
291+ [[
292+ augroup autopairs_insert_%d
293+ autocmd!
294+ autocmd InsertCharPre <buffer=%d> call luaeval("require('nvim-autopairs').autopairs_insert(%d, _A)", v:char)
295+ augroup end ]],
296+ bufnr,
297+ bufnr,
298+ bufnr
299+ ),
300+ false
301+ )
288302 end
289303
290304 if M.config.fast_wrap and M.config.fast_wrap.map then
@@ -302,7 +316,7 @@ M.on_attach = function(bufnr)
302316 bufnr,
303317 'i',
304318 '<bs>',
305− 'v:lua.MPairs.autopairs_bs()',
319+ string.format('v:lua.MPairs.autopairs_bs(%d)', bufnr),
306320 { expr = true, noremap = true }
307321 )
308322 end
@@ -313,7 +327,7 @@ M.on_attach = function(bufnr)
313327 "i",
314328 utils.key.c_h,
315329 string.format("v:lua.MPairs.autopairs_c_h(%d)", bufnr),
316− { expr = true, noremap = true }
330+ {expr = true, noremap = true}
317331 )
318332 end
319333
@@ -333,7 +347,7 @@ local autopairs_delete = function(bufnr, key)
333347 if is_disable() then
334348 return utils.esc(key)
335349 end
336− bufnr = bufnr or api.nvim_get_current_buf()
350+ bufnr = bufnr or 0
337351 local line = utils.text_get_current_line(bufnr)
338352 local _, col = utils.get_cursor()
339353 local rules = M.get_buf_rules(bufnr)
@@ -346,23 +360,22 @@ local autopairs_delete = function(bufnr, key)
346360 #rule.end_pair,
347361 rule.is_regex
348362 )
349− if utils.compare(rule.start_pair, prev_char, rule.is_regex)
363+ if
364+ utils.compare(rule.start_pair, prev_char, rule.is_regex)
350365 and utils.compare(rule.end_pair, next_char, rule.is_regex)
351366 and rule:can_del({
352367 ts_node = M.state.ts_node,
353− rule = rule,
354368 bufnr = bufnr,
355369 prev_char = prev_char,
356370 next_char = next_char,
357371 line = line,
358− col = col,
359372 })
360373 then
361374 local input = ''
362− for _ = 1, api.nvim_strwidth(rule.start_pair), 1 do
375+ for _ = 1, vim.api.nvim_strwidth(rule.start_pair), 1 do
363376 input = input .. utils.key.bs
364377 end
365− for _ = 1, api.nvim_strwidth(rule.end_pair), 1 do
378+ for _ = 1, vim.api.nvim_strwidth(rule.end_pair), 1 do
366379 input = input .. utils.key.del
367380 end
368381 return utils.esc('<c-g>U' .. input)
@@ -395,8 +408,8 @@ M.autopairs_map = function(bufnr, char)
395408 local rules = M.get_buf_rules(bufnr)
396409 for _, rule in pairs(rules) do
397410 if rule.start_pair then
398− if char:match('<.*>') then
399− new_text = line
411+ if rule.key_map and rule.key_map:match('<.*>') then
412+ new_text = line:sub(1, col) .. line:sub(col + 1, #line)
400413 add_char = 0
401414 else
402415 new_text = line:sub(1, col) .. char .. line:sub(col + 1, #line)
@@ -425,7 +438,8 @@ M.autopairs_map = function(bufnr, char)
425438 -- log.debug("start_pair" .. rule.start_pair)
426439 -- log.debug('prev_char' .. prev_char)
427440 -- log.debug('next_char' .. next_char)
428− if utils.compare(rule.end_pair, next_char, rule.is_regex)
441+ if
442+ utils.compare(rule.end_pair, next_char, rule.is_regex)
429443 and rule:can_move(cond_opt)
430444 then
431445 local end_pair = rule:get_end_pair(cond_opt)
@@ -433,8 +447,8 @@ M.autopairs_map = function(bufnr, char)
433447 return utils.esc(utils.repeat_key(utils.key.join_right, end_pair_length))
434448 end
435449
436− if rule.key_map == char
437− and utils.compare(rule.start_pair, prev_char, rule.is_regex)
450+ if
451+ utils.compare(rule.start_pair, prev_char, rule.is_regex)
438452 and rule:can_pair(cond_opt)
439453 then
440454 local end_pair = rule:get_end_pair(cond_opt)
@@ -447,19 +461,16 @@ M.autopairs_map = function(bufnr, char)
447461 if end_pair:match('<.*>') then
448462 end_pair = utils.esc(end_pair)
449463 end
450− local result = char .. end_pair .. utils.esc(move_text)
464+ local result= char .. end_pair .. utils.esc(move_text)
451465 if rule.is_undo then
452− result = utils.esc(utils.key.undo_sequence) .. result .. utils.esc(utils.key.undo_sequence)
453− end
454− if M.config.enable_abbr then
455− result = utils.esc(utils.key.abbr) .. result
466+ result = utils.esc(utils.key.undo_sequence) .. result..utils.esc(utils.key.undo_sequence)
456467 end
457468 log.debug("key_map :" .. result)
458469 return result
459470 end
460471 end
461472 end
462− return M.autopairs_afterquote(new_text, utils.esc(char))
473+ return M.autopairs_afterquote(new_text, char)
463474end
464475
465476M.autopairs_insert = function(bufnr, char)
@@ -501,7 +512,8 @@ M.autopairs_insert = function(bufnr, char)
501512 return false
502513 end
503514
504− if utils.compare(rule.start_pair, prev_char, rule.is_regex)
515+ if
516+ utils.compare(rule.start_pair, prev_char, rule.is_regex)
505517 and rule:can_pair(cond_opt)
506518 then
507519 local end_pair = rule:get_end_pair(cond_opt)
@@ -545,31 +557,35 @@ M.autopairs_cr = function(bufnr)
545557 prev_char = prev_char,
546558 next_char = next_char,
547559 }
560+
561+ local end_pair = rule:get_end_pair(cond_opt)
562+ local end_pair_length = rule:get_end_pair_length(end_pair)
563+
548564 -- log.debug('prev_char' .. rule.start_pair)
549565 -- log.debug('prev_char' .. prev_char)
550566 -- log.debug('next_char' .. next_char)
551− if rule.is_endwise
567+ if
568+ rule.is_endwise
552569 and utils.compare(rule.start_pair, prev_char, rule.is_regex)
553570 and rule:can_cr(cond_opt)
554571 then
555− local end_pair = rule:get_end_pair(cond_opt)
556− local end_pair_length = rule:get_end_pair_length(end_pair)
557572 return utils.esc(
558573 end_pair
559− .. utils.repeat_key(utils.key.join_left, end_pair_length)
560− -- FIXME do i need to re indent twice #118
561− .. '<cr><esc>====O'
574+ .. utils.repeat_key(utils.key.join_left, end_pair_length)
575+ -- FIXME do i need to re indent twice #118
576+ .. '<cr><esc>====O'
562577 )
563578 end
564579
565580 cond_opt.check_endwise_ts = false
566581
567− if utils.compare(rule.start_pair, prev_char, rule.is_regex)
582+ if
583+ utils.compare(rule.start_pair, prev_char, rule.is_regex)
568584 and utils.compare(rule.end_pair, next_char, rule.is_regex)
569585 and rule:can_cr(cond_opt)
570586 then
571587 log.debug('do_cr')
572− return utils.esc(rule:get_map_cr({ rule = rule, line = line, color = col, bufnr = bufnr }))
588+ return utils.esc(rule:get_map_cr({rule = rule, line = line, color = col, bufnr = bufnr}))
573589 end
574590 end
575591 end
@@ -582,7 +598,8 @@ M.autopairs_afterquote = function(line, key_char)
582598 line = line or utils.text_get_current_line(0)
583599 local _, col = utils.get_cursor()
584600 local prev_char, next_char = utils.text_cusor_line(line, col + 1, 1, 1, false)
585− if utils.is_bracket(prev_char)
601+ if
602+ utils.is_bracket(prev_char)
586603 and utils.is_quote(next_char)
587604 and not utils.is_in_quotes(line, col, next_char)
588605 then
@@ -600,7 +617,7 @@ M.autopairs_afterquote = function(line, key_char)
600617 is_prev_slash = char == '\\'
601618 end
602619 if count == 2 and index >= (#line - 2) then
603− local rules = M.get_buf_rules(api.nvim_get_current_buf())
620+ local rules = M.get_buf_rules(vim.api.nvim_get_current_buf())
604621 for _, rule in pairs(rules) do
605622 if rule.start_pair == prev_char and char_end ~= rule.end_pair then
606623 local new_text = line:sub(0, index)
@@ -632,13 +649,13 @@ end
632649
633650M.map_cr = function()
634651 M.completion_confirm = function()
635− if vim.fn.pumvisible() ~= 0 then
652+ if vim.fn.pumvisible() ~= 0 then
636653 return M.esc("<cr>")
637654 else
638655 return M.autopairs_cr()
639656 end
640657 end
641− api.nvim_set_keymap(
658+ vim.api.nvim_set_keymap(
642659 'i',
643660 '<CR>',
644661 'v:lua.MPairs.completion_confirm()',