Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions lua/snacks/image/doc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,17 @@ end
--- Get the image at the cursor (if any)
---@param cb fun(image_src?:string, image_pos?: snacks.image.Pos)
function M.at_cursor(cb)
M.match_at_cursor(function(img)
if not img then
return cb()
end
return cb(img.src, img.pos)
end)
end

--- Get the full image match at the cursor (if any)
---@param cb fun(img?: snacks.image.match)
function M.match_at_cursor(cb)
local cursor = vim.api.nvim_win_get_cursor(0)
M.find(vim.api.nvim_get_current_buf(), function(imgs)
for _, img in ipairs(imgs) do
Expand All @@ -358,7 +369,7 @@ function M.at_cursor(cb)
(range[1] == range[3] and cursor[2] >= range[2] and cursor[2] <= range[4])
or (range[1] ~= range[3] and cursor[1] >= range[1] and cursor[1] <= range[3])
then
return cb(img.src, img.pos)
return cb(img)
end
end
end
Expand All @@ -367,25 +378,31 @@ function M.at_cursor(cb)
end

function M.hover()
local mode = vim.api.nvim_get_mode().mode:sub(1, 1):lower()
if mode ~= "n" and mode ~= "i" and mode ~= "s" then
return M.hover_close()
end

local current_win = vim.api.nvim_get_current_win()
local current_buf = vim.api.nvim_get_current_buf()

if hover and hover.win.win == current_win and hover.win:valid() then
return
end

if hover and (hover.buf ~= current_buf or vim.fn.mode() ~= "n") then
if hover and hover.buf ~= current_buf then
return M.hover_close()
end

if hover and not hover.win:valid() then
M.hover_close()
end

M.at_cursor(function(src)
if not src then
M.match_at_cursor(function(img)
if not img or img.type ~= "math" then
return M.hover_close()
end
local src = img.src

if hover and hover.img.img.src ~= src then
M.hover_close()
Expand All @@ -394,9 +411,21 @@ function M.hover()
return
end

local bufpos ---@type number[]?
if img.range then
bufpos = { img.range[3] - 1, img.range[4] }
end

local win = Snacks.win(Snacks.win.resolve(Snacks.image.config.doc, "snacks_image", {
show = false,
enter = false,
-- Place the hover preview after the end of the math expression,
-- so it doesn't cover the closing delimiters.
relative = bufpos and "win" or nil,
win = bufpos and current_win or nil,
bufpos = bufpos,
row = bufpos and 1 or nil,
col = bufpos and 0 or nil,
wo = { winblend = Snacks.image.terminal.env().placeholders and 0 or nil },
}))
win:open_buf()
Expand All @@ -418,7 +447,7 @@ function M.hover()
buf = current_buf,
img = Snacks.image.placement.new(win.buf, src, o),
}
vim.api.nvim_create_autocmd({ "BufWritePost", "CursorMoved", "ModeChanged", "BufLeave" }, {
vim.api.nvim_create_autocmd({ "BufWritePost", "CursorMoved", "CursorMovedI", "ModeChanged", "BufLeave" }, {
group = vim.api.nvim_create_augroup("snacks.image.hover", { clear = true }),
callback = function()
if not hover then
Expand All @@ -443,17 +472,19 @@ function M._attach(buf)
end
vim.b[buf].snacks_image_attached = true
local inline = Snacks.image.config.doc.inline and Snacks.image.terminal.env().placeholders
local float = Snacks.image.config.doc.float and not inline
local float = Snacks.image.config.doc.float

if not inline and not float then
return
end

if inline then
Snacks.image.inline.new(buf)
else
end

if float then
local group = vim.api.nvim_create_augroup("snacks.image.doc." .. buf, { clear = true })
vim.api.nvim_create_autocmd({ "CursorMoved" }, {
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
group = group,
buffer = buf,
callback = vim.schedule_wrap(M.hover),
Expand Down
48 changes: 48 additions & 0 deletions lua/snacks/image/inline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,33 @@ end

function M:conceal()
local mode = vim.fn.mode():sub(1, 1):lower() ---@type string
if mode == "i" or mode == "s" then
for _, img in pairs(self.imgs) do
if img.opts.conceal then
img:hide()
else
img:show()
end
end
return
end
for _, img in pairs(self.imgs) do
img:show()
end

local cursor = vim.api.nvim_win_get_cursor(0)
local row, col = cursor[1], cursor[2]
for _, img in pairs(self.imgs) do
local range = img.opts.conceal and img.opts.range
if range then
local inside = (range[1] == range[3] and row == range[1] and col >= range[2] and col <= range[4])
or (range[1] ~= range[3] and row >= range[1] and row <= range[3])
if inside then
img:hide()
end
end
end

if vim.wo.concealcursor:find(mode) then
return
end
Expand Down Expand Up @@ -116,6 +140,30 @@ function M:update()
conceal = vim.b[self.buf].snacks_image_conceal or conceal(i.lang, i.type),
type = i.type,
---@param p snacks.image.Placement
on_update_pre = function(p)
local mode = vim.api.nvim_get_mode().mode:sub(1, 1):lower()
if p.buf ~= vim.api.nvim_get_current_buf() then
p.hidden = false
return
end
if (mode == "i" or mode == "s") and p.opts.conceal then
p.hidden = true
return
end
if mode == "n" and p.opts.conceal and p.opts.range then
local cursor = vim.api.nvim_win_get_cursor(0)
local row, col = cursor[1], cursor[2]
local range = p.opts.range
local inside = (range[1] == range[3] and row == range[1] and col >= range[2] and col <= range[4])
or (range[1] ~= range[3] and row >= range[1] and row <= range[3])
if inside then
p.hidden = true
return
end
end
p.hidden = false
end,
---@param p snacks.image.Placement
on_update = function(p)
for _, eid in ipairs(p.eids) do
self.idx[eid] = p
Expand Down
Loading