diff options
author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-21 16:06:25 +0200 |
---|---|---|
committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-21 16:06:25 +0200 |
commit | 10e12bbe481af7974739060f51210f7948fc1df9 (patch) | |
tree | 83722aca11901a5bf7ad433aac6a6b0ba05cf79a /config/essentials/vis/vis-ultisnips/init.lua | |
parent | 4775688e796faece72c6621bcd94f6eb4ebac5ff (diff) | |
parent | c9cc72113521b793d1baa0d2f558b97478a6acf4 (diff) |
Merge branch 'main' of debuc.com:dotfiles
Diffstat (limited to 'config/essentials/vis/vis-ultisnips/init.lua')
-rw-r--r-- | config/essentials/vis/vis-ultisnips/init.lua | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/config/essentials/vis/vis-ultisnips/init.lua b/config/essentials/vis/vis-ultisnips/init.lua new file mode 100644 index 0000000..52faa55 --- /dev/null +++ b/config/essentials/vis/vis-ultisnips/init.lua @@ -0,0 +1,149 @@ +-------------------------------------------------------------------------------- +-- Modules + +local M = {} +local cwd = ... +local SnipMate = require(cwd .. '.snipmate-parser') +local UltiSnips = require(cwd .. '.ultisnips-parser') + + + +-------------------------------------------------------------------------------- +-- Config + +M.snipmate = '' +M.ultisnips = '' + + + +-------------------------------------------------------------------------------- +-- Helper functions + +-- Takes list of snippets and concatenates them into the string suitable +-- for passing to dmenu (or, very probably, vis-menu) +local function snippetslist(snippets) + local list = '' + + for k,v in pairs(snippets) do + if not v.description then + list = list .. k .. '\n' + else + list = list .. k .. ' - ' .. v.description .. '\n' + end + end + + return list +end + + + +local function load_ultisnips() + local snippetfile = M.ultisnips .. vis.win.syntax .. '.snippets' + local snippets, success = UltiSnips.load_snippets(snippetfile) + if not success then + vis:info('Failed to load a correct UltiSnip: ' .. snippetfile) + end + return snippets, success +end + + + +local function load_snipmate() + local snippetfile = M.snipmate .. vis.win.syntax .. '.snippets' + local snippets, success = SnipMate.load_snippets(snippetfile) + if not success then + vis:info('Failed to load a correct SnipMate: ' .. snippetfile) + end + return snippets, success +end + + + +-- Second will append to first using suffix for distinguishing +local function merge_and_override(snips1, snips2, suffix) + for k,v in pairs(snips2) do + snips1[k .. suffix] = v + end + return snips1 +end + + + +-------------------------------------------------------------------------------- +-- Plugging it all in + +vis:map(vis.modes.INSERT, "<C-x><C-j>", function() + local snippets = merge_and_override(load_snipmate(), load_ultisnips(), '_us') + + local win = vis.win + local file = win.file + local pos = win.selection.pos + + if not pos then + return + end + -- TODO do something clever here + + -- Use prefix W if exists + local initial = ' ' + local range = file:text_object_longword(pos > 0 and pos - 1 or pos) + if range then + initial = initial .. file:content(range) + end + + -- Note, for one reason or another, using vis-menu corrupts my terminal + -- (urxvt) for exact amount of lines that vis-menu takes + -- dmenu has no such problems, but can't take initial input :-\ + --local stdout = io.popen("echo '" .. snippetslist(snippets) .. "' | dmenu -l 5", "r") + local stdout = io.popen("echo '" .. snippetslist(snippets) .. "' | vis-menu " .. initial, "r") + local chosen = stdout:lines()() + local _, msg, status = stdout:close() + if status ~= 0 or not chosen then + vis:message(msg) + return + end + + local trigger = chosen:gmatch('[^ ]+')() + local snipcontent = snippets[trigger].content + if range then + file:delete(range) + -- Update position after deleting the range + pos = pos - (range.finish - range.start) + vis:redraw() + end + + vis:insert(snipcontent.str) + + + if #snipcontent.tags > 0 then + vis:info("Use 'g>' and 'g<' to navigate between anchors.") + + -- Create selections iteratively using `:#n,#n2 p` command and `gs` to + -- save it in the jumplist + for _,v in ipairs(snipcontent.tags) do + -- Can't use 'x' command because it'd select stuff across + -- whole file + vis:command('#' .. pos + v.selstart ..',#' .. pos + v.selend .. ' p') + --vis:feedkeys('gs') -- Tested, works without this too, but just in case + --vis:message('Command: ' .. cmd) + end + + -- Backtrack through all selections we've made first + -- (so that we can use g> to move us forward)... + for _ in ipairs(snipcontent.tags) do + vis:feedkeys('g<') + end + + -- ... then set us on the first selection + vis:feedkeys('g>') + else + win.selection.pos = pos + #snipcontent.str + end +end, "Insert a snippet") + + + +-------------------------------------------------------------------------------- +-- End module + +return M
\ No newline at end of file |