From a5d66dd9929b28c35ec7c49e95ef465233319581 Mon Sep 17 00:00:00 2001 From: Charlie Gruenwald Date: Sun, 15 Mar 2026 11:59:25 -0600 Subject: [PATCH] feat: add overlap option to reduce virtual padding for overlapping images When an image overlaps existing buffer lines (e.g. a rendered diagram overlapping its code block), the new `overlap` option specifies how many buffer lines the image covers. Virtual padding is reduced accordingly so content below isn't pushed down unnecessarily. Also simplifies render_offset_top handling to support negative values, allowing images to be shifted upward relative to their anchor position. --- lua/image/image.lua | 8 +++++--- lua/image/renderer.lua | 12 ++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lua/image/image.lua b/lua/image/image.lua index 9108084..a135a71 100644 --- a/lua/image/image.lua +++ b/lua/image/image.lua @@ -108,7 +108,8 @@ function Image:render(geometry) -- create extmark if was_rendered then - local total_height = height + (self.render_offset_top or 0) + -- subtract overlap lines to allow the rendered image to overlap with them + local total_height = math.max(0, height + (self.render_offset_top or 0) - (self.overlap or 0) + 1) local has_up_to_date_extmark = previous_extmark and previous_extmark.height == total_height if not has_up_to_date_extmark then @@ -121,8 +122,7 @@ function Image:render(geometry) local filler = {} local extmark_opts = { id = self.internal_id, strict = false } if self.with_virtual_padding then - -- only reserve real height for the extmark, padding is applied during rendering - local total_lines = height + local total_lines = math.max(0, height + (self.render_offset_top or 0) - (self.overlap or 0) + 1) for _ = 0, total_lines - 1 do filler[#filler + 1] = { { " ", "" } } end @@ -298,6 +298,7 @@ local from_file = function(path, options, state) inline = opts.inline or opts.with_virtual_padding or false, is_rendered = false, render_offset_top = opts.render_offset_top or 0, + overlap = opts.overlap or 0, crop_hash = nil, resize_hash = nil, namespace = opts.namespace or nil, @@ -357,6 +358,7 @@ local from_file = function(path, options, state) inline = opts.inline or opts.with_virtual_padding or false, is_rendered = false, render_offset_top = opts.render_offset_top or 0, + overlap = opts.overlap or 0, crop_hash = nil, resize_hash = nil, namespace = opts.namespace or nil, diff --git a/lua/image/renderer.lua b/lua/image/renderer.lua index 3287ca9..c676938 100644 --- a/lua/image/renderer.lua +++ b/lua/image/renderer.lua @@ -194,11 +194,7 @@ local render = function(image) if image.window == nil then absolute_x = original_x absolute_y = original_y - -- apply render_offset_top - if image.render_offset_top and image.render_offset_top > 0 then - -- - absolute_y = absolute_y + image.render_offset_top - end + absolute_y = absolute_y + (image.render_offset_top or 0) else -- get window object local window = nil @@ -317,10 +313,10 @@ local render = function(image) absolute_x = screen_pos.col - 1 absolute_y = screen_pos.row end - -- apply render_offset_top offset if set (but not for floating windows and not during partial scroll) + -- apply render_offset_top except for floating windows or during partial scroll local is_floating = window and window.is_floating or false - if image.render_offset_top and image.render_offset_top > 0 and not is_floating and not is_partial_scroll then - absolute_y = absolute_y + image.render_offset_top + if not is_floating and not is_partial_scroll then + absolute_y = absolute_y + (image.render_offset_top or 0) end end