How to Make a Code Snapshot Plugin in Neovim
April 17, 2024Back in the dark days when I used VS Code ;) I loved the CodeSnap extension. It was a super simple plugin that could take your highlighted code and quickly turn it into a nice looking image. Moving to Neovim, I missed this feature. Then I saw the Charm.sh folks created a super cool new CLI tool called Freeze
So instead of continuing to feeling sad about missing CodeSnap, I thought I could throw together a few lines of Lua and make my own. Hopefully seeing how simple it is to do something like this can give you your own inspiration to make your own little extensions for Neovim.
-- I always like to prefix my commands with JR so I can easily find them
vim.api.nvim_create_user_command("JRFreeze", function()
-- snag the file type from the buffer
local file_type = vim.bo.filetype
-- get the text from the visual selection as a table
local text = vim.fn.getline(vim.fn.getpos("'<")[2], vim.fn.getpos("'>")[2])
-- join it together into one string
local full_text = table.concat(text, "\n")
-- write the file to /tmp/freeze...probably could find a better place to put this so it's
-- cross platform, but it works for me ¯\_(ツ)_/¯
local file = io.open("/tmp/freeze", "w")
if file == nil then
print("could not open file")
return
end
file:write(full_text)
file:close()
-- call the freeze command with the file type we grabbed earlier
vim.fn.system("freeze /tmp/freeze -l" .. file_type .. " -o /tmp/freeze.png")
-- This is the tricky bit. Use apple script to copy the image to the clipboard
vim.fn.system("osascript -e 'set the clipboard to (read (POSIX file \"/tmp/freeze.png\") as TIFF picture)'")
-- notify the user that the image has been copied to the clipboard
vim.notify("Image copied to clipboard", vim.log.levels.INFO)
end, {
-- make sure the command is only available in visual mode
range = true,
})