local ls = require("luasnip"); -- auto_pairs {{{ local get_visual = function(args, parent) if #parent.snippet.env.SELECT_RAW > 0 then return sn(nil, i(1, parent.snippet.env.SELECT_RAW)) else return sn(nil, i(1, "")) end end local function char_count_same(c1, c2) local line = vim.api.nvim_get_current_line() -- '%'-escape chars to force explicit match (gsub accepts patterns). -- second return value is number of substitutions. local _, ct1 = string.gsub(line, "%" .. c1, "") local _, ct2 = string.gsub(line, "%" .. c2, "") return ct1 == ct2 end local function even_count(c, ...) local line = vim.api.nvim_get_current_line() local _, ct = string.gsub(line, c, "") return ct % 2 == 0 end -- This makes creation of pair-type snippets easier. local function pair(pair_begin, pair_end, file_types, condition_function) -- FIXME(@Soispha): This only works if file_types == nil, otherwise the snippet does not expand. -- It would be nice, if it would support both an empty array (`{}`) and nil <2023-08-27> -- file_types = file_types or {}; return s( { trig = pair_begin; wordTrig = false; snippetType = "autosnippet"; }, { t({ pair_begin; }); d(1, get_visual); t({ pair_end; }); }, { condition = function() local filetype_check = true; if file_types ~= nil then filetype_check = file_types[vim.bo.filetype] or false; end; return (not condition_function(pair_begin, pair_end)) and filetype_check end; } ) end local auto_pairs = { pair("(", ")", nil, char_count_same); pair("{", "}", nil, char_count_same); pair("[", "]", nil, char_count_same); pair("<", ">", { ["rust"] = true; ["tex"] = true; }, char_count_same); pair("'", "'", nil, even_count); pair('"', '"', nil, even_count); pair("`", "`", nil, even_count); } ls.add_snippets("all", auto_pairs, { type = "snippets"; key = "auto_pairs"; }) -- }}}