-- Copyright (c) 2023-2024 Florian Fischer. All rights reserved. -- -- vis-snippets is free software: you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free Software -- Foundation, either version 3 of the License, or (at your option) any later -- version. -- -- vis-snippets is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License along with -- vis-snippets found in the LICENSE file. -- If not, see . -- local M = {snippets = {}} M.menu_cmd = 'vis-menu' -- check if fzf is available and use fzf instead of vis-menu per default if os.execute('type fzf >/dev/null 2>/dev/null') then M.menu_cmd = 'fzf' end local source_str = debug.getinfo(1, 'S').source:sub(2) local script_path = source_str:match('(.*/)') local snippets_path = script_path .. 'snippets' local function available_snippets() local snippets = {} -- available string snippets for k, _ in ipairs(M.snippets) do snippets[k] = true end -- available file snippets local cmd = 'ls ' .. snippets_path local proc = io.popen(cmd) local out = assert(proc:read("*a")) -- TODO: error handling proc:close() for filename in out:gmatch("(.-)\n") do snippets[filename] = true end local _snippets = {} for k, _ in pairs(snippets) do table.insert(_snippets, k) end return _snippets end -- select implementation copied from vis-lspc. -- concatenate all numeric values in choices and pass it on stdin to M.menu_cmd local function lspc_select(choices) local menu_input = '' local i = 0 for _, c in ipairs(choices) do i = i + 1 menu_input = menu_input .. c .. '\n' end -- select the only possible choice if i < 2 then return choices[1] end local status, output local cmd = 'printf "' .. menu_input .. '" | ' .. M.menu_cmd if M.menu_cmd:sub(0, 8) == 'vis-menu' then status, output = vis:pipe(vis.win.file, {start = 0, finish = 0}, cmd) else local menu = io.popen(cmd) output = menu:read('*a') local _, _, _status = menu:close() status = _status end local choice = nil if status == 0 then -- trim newline from selection if output:sub(-1) == '\n' then choice = output:sub(1, -2) else choice = output end end vis:redraw() return choice end local function select_avail_snippet() return lspc_select(available_snippets()) end local function read_file_snippet(name) local snippet_path = snippets_path .. '/' .. name local file = io.open(snippet_path, "rb") -- r read mode and b binary mode if not file then return end local content = file:read("*a") file:close() return content end vis:command_register('snippet', function(argv, _, win, _, _) local snippet = argv[1] or select_avail_snippet() if not snippet then return end local pos = win.selection.pos if not M.snippets[snippet] then local content = read_file_snippet(snippet) M.snippets[snippet] = content win.file:insert(pos, content) else win.file:insert(pos, M.snippets[snippet]) end end, 'Insert a snippet after the primary selection') return M