Skip to content

Instantly share code, notes, and snippets.

@cjoke
Created May 22, 2025 18:07
Show Gist options
  • Save cjoke/36e8a9d28021bdc88a45e8732083dbb1 to your computer and use it in GitHub Desktop.
Save cjoke/36e8a9d28021bdc88a45e8732083dbb1 to your computer and use it in GitHub Desktop.
Show images listed in chatbuffer in codecompanion - neovim (nvim)
-- This will make image popup in current buffer when cursor hoover over the ![image_name](path_to/image.png)
-- It will also remove image when cursor leaves the link. Also when leaving buffer.
-- Autocommand to detect Markdown image syntax and render images using image.nvim
vim.api.nvim_create_autocmd({ "CursorHold", "CursorMoved" }, {
pattern = "*", -- Restrict to Markdown files
callback = function()
local bufnr = vim.api.nvim_get_current_buf()
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
local line = vim.api.nvim_buf_get_lines(bufnr, cursor_line - 1, cursor_line, false)[1]
-- Match Markdown image syntax: ![alt text](image.jpg)
local image_path = line:match("!%[.*%]%((.*)%)")
if image_path then
-- Resolve the image path relative to the current working directory
local resolved_path = vim.fn.fnamemodify(image_path, ":p")
-- Check if the image file exists
if vim.fn.filereadable(resolved_path) == 0 then
vim.notify("Image file not found: " .. resolved_path, vim.log.levels.WARN)
return
end
-- Use image.nvim to render the image
local image = require("image")
image.setup({
backend = "kitty", -- Specify the backend (e.g., "kitty" or "ueberzug")
kitty_method = "normal", -- Required for the "kitty" backend
processor = "magick_cli", -- Ensure this matches your configuration
integrations = {
markdown = {
enabled = true,
only_render_image_at_cursor = true, -- Render only the image at the cursor
only_render_image_at_cursor_mode = "popup", -- Use popup mode
},
},
})
-- Render the image using the correct function
image
.from_file(resolved_path, {
buffer = bufnr, -- Bind the image to the current buffer
x = 0, -- Adjust x-coordinate if needed
y = 0, -- Adjust y-coordinate if needed
})
:render()
end
end,
})
-- clear image when leaving buffer.
vim.api.nvim_create_autocmd("BufLeave", {
pattern = "*",
callback = function()
require("image").clear()
end,
})
-- Clear image when cursor leaves the hover state
vim.api.nvim_create_autocmd("CursorMoved", {
pattern = "*",
callback = function()
local bufnr = vim.api.nvim_get_current_buf()
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
local line = vim.api.nvim_buf_get_lines(bufnr, cursor_line - 1, cursor_line, false)[1]
-- Check if the current line contains a Markdown image syntax
local image_path = line and line:match("!%[.*%]%((.*)%)")
if not image_path then
-- Clear the image if the cursor is no longer on a Markdown image line
require("image").clear()
end
end,
})
return {
"3rd/image.nvim",
build = false, -- so that it doesn't build the rock https://github.com/3rd/image.nvim/issues/91#issuecomment-2453430239
opts = {
processor = "magick_cli",
integrations = {
markdown = {
enabled = true,
clear_in_insert_mode = true,
download_remote_images = true,
only_render_image_at_cursor = true,
only_render_image_at_cursor_mode = "popup",
floating_windows = false, -- if true, images will be rendered in floating markdown windows
filetypes = { "markdown", "vimwiki" }, -- markdown extensions (ie. quarto) can go here
},
neorg = {
enabled = true,
filetypes = { "norg" },
},
typst = {
enabled = true,
filetypes = { "typst" },
},
html = {
enabled = false,
},
css = {
enabled = false,
},
},
max_width = nil,
max_height = nil,
max_width_window_percentage = nil,
max_height_window_percentage = 50,
window_overlap_clear_enabled = false, -- toggles images when windows are overlapped
window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "snacks_notif", "scrollview", "scrollview_sign" },
editor_only_render_when_focused = false, -- auto show/hide images when the editor gains/looses focus
tmux_show_only_in_active_window = false, -- auto show/hide images in the correct Tmux window (needs visual-activity off)
hijack_file_patterns = { "*.png", "*.jpg", "*.jpeg", "*.gif", "*.webp", "*.avif" }, -- render image files as images when opened
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment