summary refs log tree commit diff
path: root/.config/nvim/lua/config/snippets.lua
blob: 9cd0632d39b950592ff275161410a9246cc2f021 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
local ls = require('luasnip')
local types = require('luasnip.util.types')

-- configure luasnip
ls.config.set_config({
  enable_autosnippets = true,
  history = true,
  updateevents = 'TextChanged,TextChangedI',
  exit_roots = false, -- dont exit when reaching last node
  ext_opts = {
    [types.choiceNode] = {
      passive = {
        virt_text = { { '󰬊 ', 'Conceal' } },
        virt_text_pos = 'inline',
      },
    },
    [types.insertNode] = {
      passive = {
        virt_text = { { '󰬐 ', 'Conceal' } },
        virt_text_pos = 'inline',
      },
    },
    [types.exitNode] = {
      passive = {
        virt_text = { { '$', 'Conceal' } },
        virt_text_pos = 'inline',
      },
    },
  },
  snip_env = vim.tbl_deep_extend('error', ls.session.config.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,
    },
  }),
})

-- snippet loaders
require('luasnip.loaders.from_lua').lazy_load()
require('luasnip.loaders.from_vscode').lazy_load({ include = {} })

-- usercmds
vim.api.nvim_create_user_command('EditSnippets', require('luasnip.loaders').edit_snippet_files, {})

-- autocmds
-- 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,
-- })

-- unlink luasnip session on <esc>
vim.api.nvim_create_autocmd('ModeChanged', {
  pattern = '*',
  callback = function()
    if
      ((vim.v.event.old_mode == 's' or vim.v.event.old_mode == 'i') and vim.v.event.new_mode == 'n')
      and ls.session.current_nodes[vim.api.nvim_get_current_buf()]
      and not ls.session.jump_active
      and not require('blink.cmp').is_visible()
    then
      vim.schedule(ls.unlink_current)
    end
  end,
})

-- expand/jump keymaps handled by blink

vim.keymap.set({ 'i', 's' }, '<c-n>', function()
  return ls.choice_active() and ls.change_choice(1)
end, { silent = true, desc = 'luasnip: next choice' })

vim.keymap.set({ 'i', 's' }, '<c-p>', function()
  return ls.choice_active() and ls.change_choice(-1)
end, { silent = true, desc = 'luasnip: prev choice' })