diff options
Diffstat (limited to '')
| -rw-r--r-- | .vim/lua/internal/snippets.lua | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/.vim/lua/internal/snippets.lua b/.vim/lua/internal/snippets.lua new file mode 100644 index 0000000..be00884 --- /dev/null +++ b/.vim/lua/internal/snippets.lua @@ -0,0 +1,129 @@ +local ls = require('luasnip') +local types = require('luasnip.util.types') + +-- attach to builtin snippet hooks + +vim.snippet.expand = ls.lsp_expand + +---@diagnostic disable-next-line: duplicate-set-field +vim.snippet.active = function(filter) + filter = filter or {} + filter.direction = filter.direction or 1 + + if filter.direction == 1 then + return ls.expand_or_jumpable() + else + return ls.jumpable(filter.direction) + end +end + +---@diagnostic disable-next-line: duplicate-set-field +vim.snippet.jump = function(direction) + if direction == 1 then + if ls.expandable() then + return ls.expand_or_jump() + else + return ls.jumpable(1) and ls.jump(1) + end + else + return ls.jumpable(-1) and ls.jump(-1) + end +end + +vim.snippet.stop = ls.unlink_current + +local snip_env = { + -- snippet helpers + nl = function() + return ls.t({ '', '' }) + end, + exec = function(command) + return ls.f(function(_, _, ...) + local job = require('plenary.job'):new({ + command = vim.env.SHELL, + args = { '-c', ... }, + enable_recording = true, + }) + local res, exitcode = job:sync() + if not exitcode == 0 or #res == 0 then + error(string.format('exec "%s" failed', ...)) + end + return res + end, {}, { user_args = { command } }) + end, + -- condition helpers + cond = { + ts = function(capture) + return function() + return vim.tbl_contains(vim.treesitter.get_captures_at_cursor(), capture) + end + end, + }, +} + +ls.config.set_config({ + enable_autosnippets = true, + history = true, + updateevents = 'TextChanged,TextChangedI', + override_builtin = true, + snip_env = vim.tbl_deep_extend('error', ls.session.config.snip_env, snip_env), + ext_opts = { + [types.choiceNode] = { + active = { + virt_text = { { '◂ ', 'NonText' } }, + }, + }, + [types.insertNode] = { + active = { + virt_text = { { '◂ ', 'NonText' } }, + }, + }, + }, +}) + +require('luasnip.loaders.from_lua').lazy_load({ paths = './snippets' }) + +vim.keymap.set({ 'i', 's' }, '<c-j>', function() + return vim.snippet.active({ direction = 1 }) and vim.snippet.jump(1) +end, { silent = true, desc = 'snippet: jump next' }) + +vim.keymap.set({ 'i', 's' }, '<c-k>', function() + return vim.snippet.active({ direction = -1 }) and vim.snippet.jump(-1) +end, { silent = true, desc = 'snippet: jump prev' }) + +vim.keymap.set({ 'i', 's' }, '<c-n>', function() + if ls.choice_active() then + ls.change_choice(1) + end +end, { silent = true, desc = 'snippet: next choice' }) + +vim.keymap.set({ 'i', 's' }, '<c-p>', function() + if ls.choice_active() then + ls.change_choice(-1) + end +end, { silent = true, desc = 'snippet: prev choice' }) + +vim.api.nvim_create_user_command('EditSnippets', require('luasnip.loaders').edit_snippet_files, {}) + +-- vim.api.nvim_create_autocmd('User', { +-- pattern = 'LuasnipChoiceNodeEnter', +-- callback = function() +-- vim.schedule(function() +-- assert(ls.session.active_choice_nodes[vim.api.nvim_get_current_buf()], 'No active choiceNode') +-- vim.ui.select( +-- ls.get_current_choices(), +-- -- TODO: patch luasnip.extras.select_choice to fix missing prompt +-- { prompt = 'LuaSnip: choice node', kind = 'luasnip' }, +-- function(_, idx) +-- if not idx then +-- return +-- end +-- -- feed+immediately execute i to enter INSERT after vim.ui.input closes. +-- vim.api.nvim_feedkeys('i', 'x', false) +-- ls.set_choice(idx) +-- ls.unlink_current() +-- end +-- ) +-- end) +-- end, +-- }) |