diff --git a/users/jrpotter/neovim/config/python/snippets.lua b/users/jrpotter/neovim/config/python/snippets.lua index 995e7bc..c559d67 100644 --- a/users/jrpotter/neovim/config/python/snippets.lua +++ b/users/jrpotter/neovim/config/python/snippets.lua @@ -1,16 +1,58 @@ -local s = require('luasnip').snippet +local c = require('luasnip').choice_node +local d = require('luasnip').dynamic_node local i = require('luasnip').insert_node +local sn = require('luasnip').snippet_node +local t = require('luasnip').text_node + +local s = require('luasnip').snippet local fmt = require('luasnip.extras.fmt').fmt -local v = require('utils.snippets').visual_dynamic_node +local VISUAL = require('utils.luasnip').VISUAL return { s( { name = 'for', trig = 'for' }, fmt([[ for {} in {}: - {}]], - { i(1, ''), i(2, ''), v(3) } + {}]], + { + c(1, { + i(1, 'i'), + i(2, 'k'), + i(3, 'v'), + sn(4, { i(1, 'k'), t(', '), i(2, 'v') }), + }), + d(2, function(args, _, old_state) + local default = i(nil, 'val') + local snip = old_state or default + + if args[1][1] == 'i' then + snip = sn(nil, c(1, { + { t('range('), i(1, 'n'), t(')') }, + default, + })) + elseif args[1][1] == 'k' then + snip = sn(nil, c(1, { + { i(1, 'dict'), t('.keys()') }, + default, + })) + elseif args[1][1] == 'v' then + snip = sn(nil, c(1, { + { i(1, 'dict'), t('.values()') }, + default, + })) + elseif args[1][1] == 'k, v' then + snip = sn(nil, c(1, { + { i(1, 'dict'), t('.items()') }, + default, + })) + end + + snip.old_state = snip + return snip + end, { 1 }), + VISUAL, + } ) ), } diff --git a/users/jrpotter/neovim/config/utils/cmp.lua b/users/jrpotter/neovim/config/utils/cmp.lua index ebd6c1a..295083b 100644 --- a/users/jrpotter/neovim/config/utils/cmp.lua +++ b/users/jrpotter/neovim/config/utils/cmp.lua @@ -2,7 +2,7 @@ local M = {} local cmp = require('cmp') local cmp_buffer = require('cmp_buffer') -local luasnip = require("luasnip") +local luasnip = require('luasnip') function M.setup() cmp.setup { @@ -12,9 +12,8 @@ function M.setup() end, }, sources = { - { - name = 'nvim_lsp', - }, + { name = 'luasnip' }, + { name = 'nvim_lsp' }, { name = 'buffer', option = { @@ -31,29 +30,24 @@ function M.setup() }, sorting = { comparators = { - function (...) - -- This also sorts completion results coming from other sources (e.g. - -- LSPs). + function(...) + -- This also sorts completion results coming from other sources. return cmp_buffer:compare_locality(...) end, }, }, mapping = { - [''] = cmp.mapping(function(fallback) - if cmp.visible() then cmp.select_next_item() else fallback() end - end, { 'i', 's' }), - - [''] = cmp.mapping(function(fallback) - if cmp.visible() then cmp.select_prev_item() else fallback() end + [''] = cmp.mapping(function(fallback) + if cmp.get_active_entry() then cmp.confirm() else fallback() end end, { 'i', 's' }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.abort() else fallback() end end, { 'i', 's' }), - [''] = cmp.mapping(function(fallback) - if cmp.get_active_entry() then - cmp.confirm() + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() elseif luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() else @@ -61,8 +55,10 @@ function M.setup() end end, { 'i', 's' }), - [''] = cmp.mapping(function(fallback) - if luasnip.jumpable(-1) then + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.locally_jumpable(-1) then luasnip.jump(-1) else fallback() diff --git a/users/jrpotter/neovim/config/utils/luasnip.lua b/users/jrpotter/neovim/config/utils/luasnip.lua new file mode 100644 index 0000000..ef3ad69 --- /dev/null +++ b/users/jrpotter/neovim/config/utils/luasnip.lua @@ -0,0 +1,64 @@ +local M = {} + +local luasnip = require('luasnip') +local types = require('luasnip.util.types') +local f = require('luasnip').function_node + +M.VISUAL = f(function(_, snip) + local res, env = {}, snip.env + for _, ele in ipairs(env.LS_SELECT_RAW) do + table.insert(res, ele) + end + return res +end, {}) + +function M.setup() + luasnip.config.setup { + region_check_events = 'InsertEnter', + delete_check_events = 'InsertLeave', + store_selection_keys = '', + ext_opts = { + [types.snippet] = { + active = { + virt_text = { { '●', 'DiagnosticWarn' } }, + }, + }, + [types.choiceNode] = { + active = { + virt_text = { { '⧨', 'DiagnosticHint' } }, + -- Include in case one of our choice options is an empty string. + hl_group = 'DiagnosticOk', + }, + }, + }, + } + + vim.keymap.set( + { 'i', 's' }, + '', + function() + if luasnip.choice_active() then + luasnip.change_choice(1) + end + end, + { silent = true } + ) + vim.keymap.set( + { 'i', 's' }, + '', + function() + if luasnip.choice_active() then + luasnip.change_choice(-1) + end + end, + { silent = true } + ) + -- Allow aborting the active snippet at any point in time. + vim.keymap.set( + { 'n', 'i', 's' }, + '', + 'LuaSnipUnlinkCurrent' + ) +end + +return M diff --git a/users/jrpotter/neovim/config/utils/snippets.lua b/users/jrpotter/neovim/config/utils/snippets.lua deleted file mode 100644 index c1f5c6d..0000000 --- a/users/jrpotter/neovim/config/utils/snippets.lua +++ /dev/null @@ -1,28 +0,0 @@ -local M = {} - -local luasnip = require('luasnip') -local d = luasnip.dynamic_node -local i = luasnip.insert_node -local sn = luasnip.snippet_node - --- Creates an insertion node with a default value of whatever was stored in the --- visual selection prior to entering insert mode (refer to the configuration --- field `store_selection_keys`). -function M.visual_dynamic_node(index, default) - return d(index, function(_, parent) - local res, env = {}, parent.snippet.env - if type(env.LS_SELECT_RAW) ~= 'table' then - return sn(nil, { i(1, default or '') }, '') - end - for k, v in ipairs(env.LS_SELECT_RAW) do - local indent = env.CUSTOM_POS[2] - 1 - table.insert(res, (k == 1 and v) or string.rep(' ', indent) .. v) - end - if table.concat(res):match('^%s*$') then - return sn(nil, { i(1, default or '') }, '') - end - return sn(nil, { i(1, res) }, '') - end, {}) -end - -return M diff --git a/users/jrpotter/neovim/default.nix b/users/jrpotter/neovim/default.nix index e10d520..290a2b3 100644 --- a/users/jrpotter/neovim/default.nix +++ b/users/jrpotter/neovim/default.nix @@ -30,6 +30,7 @@ let luasnip = { plugin = pkgs.vimPlugins.luasnip; config = '' + require('utils.luasnip').setup() ${config.programs.neovim.nvim-snippets} ''; };