return { { "hrsh7th/nvim-cmp", dependencies = { "windwp/nvim-autopairs", opts = {}, }, opts = function() local cmp = require("cmp") local cmp_autopairs = require("nvim-autopairs.completion.cmp") local ts_utils = require("nvim-treesitter.ts_utils") local ts_node_func_parens_disabled = { -- ecma named_imports = true, -- rust use_declaration = true, } local npairs = require("nvim-autopairs") local Rule = require("nvim-autopairs.rule") local cond = require("nvim-autopairs.conds") local brackets = { { "(", ")" }, { "[", "]" }, { "{", "}" } } local default_handler = cmp_autopairs.filetypes["*"]["("].handler cmp_autopairs.filetypes["*"]["("].handler = function(char, item, bufnr, rules, commit_character) local node_type = ts_utils.get_node_at_cursor():type() if ts_node_func_parens_disabled[node_type] then if item.data then item.data.funcParensDisabled = true else char = "" end end default_handler(char, item, bufnr, rules, commit_character) end cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) npairs.add_rules({ -- Rule for a pair with left-side ' ' and right side ' ' Rule(" ", " ") -- Pair will only occur if the conditional function returns true :with_pair(function(opts) -- We are checking if we are inserting a space in (), [], or {} local pair = opts.line:sub(opts.col - 1, opts.col) return vim.tbl_contains({ brackets[1][1] .. brackets[1][2], brackets[2][1] .. brackets[2][2], brackets[3][1] .. brackets[3][2], }, pair) end) :with_move(cond.none()) :with_cr(cond.none()) -- We only want to delete the pair of spaces when the cursor is as such: ( | ) :with_del( function(opts) local col = vim.api.nvim_win_get_cursor(0)[2] local context = opts.line:sub(col - 1, col + 2) return vim.tbl_contains({ brackets[1][1] .. " " .. brackets[1][2], brackets[2][1] .. " " .. brackets[2][2], brackets[3][1] .. " " .. brackets[3][2], }, context) end ), -- Javascript arrow key Rule("%(.*%)%s*%=>$", " { }", { "typescript", "typescriptreact", "javascript" }) :use_regex(true) :set_end_pair_length(2), -- Auto addspace on = Rule("=", "") :with_pair(cond.not_inside_quote()) :with_pair(function(opts) local last_char = opts.line:sub(opts.col - 1, opts.col - 1) if last_char:match("[%w%=%s]") then return true end return false end) :replace_endpair(function(opts) local prev_2char = opts.line:sub(opts.col - 2, opts.col - 1) local next_char = opts.line:sub(opts.col, opts.col) next_char = next_char == " " and "" or " " if prev_2char:match("%w$") then return " =" .. next_char end if prev_2char:match("%=$") then return next_char end if prev_2char:match("=") then return "=" .. next_char end return "" end) :set_end_pair_length(0) :with_move(cond.none()) :with_del(cond.none()), }) -- For each pair of brackets we will add another rule for _, bracket in pairs(brackets) do npairs.add_rules({ -- Each of these rules is for a pair with left-side '( ' and right-side ' )' for each bracket type Rule(bracket[1] .. " ", " " .. bracket[2]) :with_pair(cond.none()) :with_move(function(opts) return opts.char == bracket[2] end) :with_del(cond.none()) :use_key(bracket[2]) -- Removes the trailing whitespace that can occur without this :replace_map_cr(function(_) return "2xiO" end), }) end end, }, { "echasnovski/mini.pairs", enabled = false, }, }