diff --git a/init.lua b/init.lua index 27f35db..1d6cf6e 100644 --- a/init.lua +++ b/init.lua @@ -4,301 +4,309 @@ local id_counter = 0 local stdout = vim.loop.new_tty(1, false) if not stdout then - error "failed to open stdout" + error("failed to open stdout") end local uv = vim.uv if not uv then - uv = vim.loop + uv = vim.loop end local Image = {} Image.__index = Image function Image:new(filepath) - id_counter = id_counter + 1 - local obj = setmetatable({}, self) - obj.filepath_o = filepath - obj.filepath = filepath - obj.id = id_counter - obj.properties = {} - obj.properties.zoom = 0.9 - obj.properties.o_x = 0 - obj.properties.o_y = 0 - obj.properties.rotation = 0 - return obj + id_counter = id_counter + 1 + local obj = setmetatable({}, self) + obj.filepath_o = filepath + obj.filepath = filepath + obj.id = id_counter + obj.properties = {} + obj.properties.zoom = 0.9 + obj.properties.o_x = 0 + obj.properties.o_y = 0 + obj.properties.rotation = 0 + return obj end function Image:draw(x, y, w, h) - self.properties.w = w - self.properties.h = h - self:pngify() - self:rescale() - local file = io.open(self.filepath, "rb") - if not file then - print "Error: Could not open file." - return - end - local data = file:read "*all" - file:close() - local encoded_data = vim.base64.encode(data):gsub("%/", "/") - local pos = 1 - local chunk_size = 4096 - stdout:write("\27[" .. x + 2 .. ";" .. y + 4 .. "H") - while pos <= #encoded_data do - local chunk = encoded_data:sub(pos, pos + chunk_size - 1) - pos = pos + chunk_size - local m = (pos <= #encoded_data) and "1" or "0" - local cmd - cmd = "\27_Ga=T,i=10,p=" - .. self.id - .. ",q=1,r=" - .. h - .. ",c=" - .. w - .. ",C=1,f=100,m=" - .. m - .. ";" - .. chunk - .. "\27\\" - stdout:write(cmd) - uv.sleep(1) - end - stdout:write "\x1b[H" - vim.cmd "redraw" + self.properties.w = w + self.properties.h = h + self:pngify() + self:rescale() + local file = io.open(self.filepath, "rb") + if not file then + print("Error: Could not open file.") + return + end + local data = file:read("*all") + file:close() + local encoded_data = vim.base64.encode(data):gsub("%/", "/") + local pos = 1 + local chunk_size = 4096 + stdout:write("\27[" .. x + 2 .. ";" .. y + 4 .. "H") + while pos <= #encoded_data do + local chunk = encoded_data:sub(pos, pos + chunk_size - 1) + pos = pos + chunk_size + local m = (pos <= #encoded_data) and "1" or "0" + local cmd + cmd = "\27_Ga=T,i=10,p=" + .. self.id + .. ",q=1,r=" + .. h + .. ",c=" + .. w + .. ",C=1,f=100,m=" + .. m + .. ";" + .. chunk + .. "\27\\" + stdout:write(cmd) + uv.sleep(1) + end + stdout:write("\x1b[H") + vim.cmd("redraw") end function Image:unload() - stdout:write "\27_Ga=d\27\\" + stdout:write("\27_Ga=d\27\\") end function Image:rescale() - local w, h = self.properties.w, self.properties.h - local o_x, o_y = self.properties.o_x, self.properties.o_y - local rotation = self.properties.rotation - local temp_file = "/tmp/scaled" .. self.id .. ".png" - if vim.fn.filereadable(temp_file) == 1 then - vim.fn.delete(temp_file) - end - local o_x_str = o_x >= 0 and "+" .. o_x or tostring(o_x) - local o_y_str = o_y >= 0 and "+" .. o_y or tostring(o_y) - local r_w, r_h = w * self.properties.zoom * 10, h * self.properties.zoom * 23 - local cmd = "magick " - .. self.filepath - .. " -resize " - .. r_w - .. "x" - .. r_h - .. " -background none -rotate " - .. rotation - .. " -gravity center -background none " - .. "-extent " - .. (w * 10) - .. "x" - .. (h * 23) - .. o_x_str - .. o_y_str - .. " " - .. temp_file - local result = vim.fn.system(cmd) - if vim.v.shell_error == 0 then - self.filepath = temp_file - else - vim.api.nvim_err_writeln("Error converting image: " .. result) - self.filepath = "" - end + local w, h = self.properties.w, self.properties.h + local o_x, o_y = self.properties.o_x, self.properties.o_y + local rotation = self.properties.rotation + local temp_file = "/tmp/scaled" .. self.id .. ".png" + if vim.fn.filereadable(temp_file) == 1 then + vim.fn.delete(temp_file) + end + local o_x_str = o_x >= 0 and "+" .. o_x or tostring(o_x) + local o_y_str = o_y >= 0 and "+" .. o_y or tostring(o_y) + local r_w, r_h = w * self.properties.zoom * 10, h * self.properties.zoom * 23 + local cmd = "magick " + .. self.filepath + .. " -resize " + .. r_w + .. "x" + .. r_h + .. " -background none -rotate " + .. rotation + .. " -gravity center -background none " + .. "-extent " + .. (w * 10) + .. "x" + .. (h * 23) + .. o_x_str + .. o_y_str + .. " " + .. temp_file + local result = vim.fn.system(cmd) + if vim.v.shell_error == 0 then + self.filepath = temp_file + else + vim.api.nvim_err_writeln("Error converting image: " .. result) + self.filepath = "" + end end function Image:pngify() - local temp_file = "/tmp/pngify" .. self.id .. ".png" - local file_type = vim.fn.fnamemodify(self.filepath_o, ":e") - local cmd - if file_type == "png" then - self.filepath = self.filepath_o - return - end - if file_type == "gif" then - cmd = "magick " .. self.filepath_o .. "[0] " .. temp_file - else - cmd = "magick " .. self.filepath_o .. " " .. temp_file - end - local result = vim.fn.system(cmd) - if vim.v.shell_error == 0 then - self.filepath = temp_file - self.filepath_o = temp_file - else - vim.api.nvim_err_writeln("Error converting image: " .. result) - self.filepath = "" - end + local temp_file = "/tmp/pngify" .. self.id .. ".png" + local file_type = vim.fn.fnamemodify(self.filepath_o, ":e") + local cmd + if file_type == "png" then + self.filepath = self.filepath_o + return + end + if file_type == "gif" then + cmd = "magick " .. self.filepath_o .. "[0] " .. temp_file + else + cmd = "magick " .. self.filepath_o .. " " .. temp_file + end + local result = vim.fn.system(cmd) + if vim.v.shell_error == 0 then + self.filepath = temp_file + self.filepath_o = temp_file + else + vim.api.nvim_err_writeln("Error converting image: " .. result) + self.filepath = "" + end end function M.setup() - vim.api.nvim_create_autocmd("BufEnter", { - pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", - callback = function() - if not vim.b.img then - vim.b.img = Image:new(vim.fn.expand "%:p") - end - vim.cmd "setlocal buftype=nofile" - vim.cmd "setlocal nonumber" - vim.cmd "setlocal norelativenumber" - vim.cmd "setlocal modifiable" - local buf = vim.api.nvim_get_current_buf() - -- local win = vim.api.nvim_get_current_win() - -- local window_height = vim.api.nvim_win_get_height(win) - -- local window_width = vim.api.nvim_win_get_width(win) - -- local border_top_bottom = string.rep("-", window_width - 3) - -- local border_sides = "|" .. string.rep(" ", window_width - 5) .. "|" - -- local message = " Welcome to PicVim! Displaying image: " .. vim.fn.expand "%:p" - -- local lines = {} - -- table.insert(lines, message) - -- table.insert(lines, border_top_bottom) - -- for _ = 1, window_height - 4 do - -- table.insert(lines, border_sides) - -- end - -- table.insert(lines, border_sides) - -- table.insert(lines, border_top_bottom) - -- vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) - -- vim.api.nvim_win_set_cursor(win, { 1, 0 }) - vim.api.nvim_buf_set_lines(buf, 0, -1, false, { " Welcome to PicVim! Displaying image: " .. vim.fn.expand "%:p" }) - vim.cmd "setlocal nomodifiable" - vim.cmd "setlocal nowrap" - vim.cmd "setlocal nolist" - local debounce_timer = nil - local debounce_interval = 50 - local keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } - local function redraw() - if not vim.b.img then - return - end - local image = vim.b.img - setmetatable(image, Image) - local win = vim.api.nvim_get_current_win() - local window_height = vim.api.nvim_win_get_height(win) - local window_width = vim.api.nvim_win_get_width(win) - local MAX_OFFSET_X = (window_width * 10) - 150 - local MIN_OFFSET_X = (-window_width * 10) + 150 - local MAX_OFFSET_Y = (window_height * 23) - 150 - local MIN_OFFSET_Y = (-window_height * 23) + 150 - image.properties.o_x = math.min(math.max(image.properties.o_x + keypress_state.o_x, MIN_OFFSET_X), MAX_OFFSET_X) - image.properties.o_y = math.min(math.max(image.properties.o_y + keypress_state.o_y, MIN_OFFSET_Y), MAX_OFFSET_Y) - image.properties.zoom = math.min(math.max(image.properties.zoom + keypress_state.zoom, 0.1), 5) - image.properties.rotation = (image.properties.rotation + keypress_state.rotation) % 360 - keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } - local cursor = vim.api.nvim_win_get_position(win) - local x, y = cursor[1], cursor[2] - image:draw(x, y, window_width - 6, window_height - 1) - vim.b.img = image - end - local function schedule_redraw() - if debounce_timer then - debounce_timer:stop() - debounce_timer:close() - end - debounce_timer = vim.defer_fn(function() - redraw() - debounce_timer = nil - end, debounce_interval) - end - vim.keymap.set("n", "", function() - keypress_state.o_x = keypress_state.o_x - 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "", function() - keypress_state.o_x = keypress_state.o_x + 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "", function() - keypress_state.o_y = keypress_state.o_y + 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "", function() - keypress_state.o_y = keypress_state.o_y - 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "h", function() - keypress_state.o_x = keypress_state.o_x - 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "l", function() - keypress_state.o_x = keypress_state.o_x + 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "j", function() - keypress_state.o_y = keypress_state.o_y + 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "k", function() - keypress_state.o_y = keypress_state.o_y - 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "=", function() - keypress_state.zoom = keypress_state.zoom + 0.2 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "+", function() - keypress_state.zoom = keypress_state.zoom + 0.2 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "-", function() - keypress_state.zoom = keypress_state.zoom - 0.2 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "t", function() - keypress_state.rotation = keypress_state.rotation + 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "T", function() - keypress_state.rotation = keypress_state.rotation - 30 - schedule_redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "o", function() - local image = vim.b.img - image.properties.o_x = 0 - image.properties.o_y = 0 - image.properties.rotation = 0 - vim.b.img = image - redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.keymap.set("n", "r", function() - redraw() - end, { buffer = buf, noremap = true, silent = true }) - vim.b.no_git_diff = true - redraw() - end, - }) - vim.api.nvim_create_autocmd("VimResized", { - pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", - callback = function() - if not vim.b.img then - vim.b.img = Image:new(vim.fn.expand "%:p") - end - local image = vim.b.img - if image then - setmetatable(image, Image) - end - local win_id = vim.api.nvim_get_current_win() - local cursor = vim.api.nvim_win_get_position(win_id) - local x, y = cursor[1], cursor[2] - local win = vim.api.nvim_get_current_win() - local window_height = vim.api.nvim_win_get_height(win) - local window_width = vim.api.nvim_win_get_width(win) - image:draw(x, y, window_width - 6, window_height - 1) - vim.b.img = image - end, - }) - vim.api.nvim_create_autocmd("BufLeave", { - pattern = "*", - callback = function() - local image = vim.b.img - if image then - setmetatable(image, Image) - end - if image and image.unload then - image:unload() - end - end, - }) + vim.api.nvim_create_autocmd("BufEnter", { + pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", + callback = function() + if not vim.b.img then + vim.b.img = Image:new(vim.fn.expand("%:p")) + end + vim.cmd("setlocal buftype=nofile") + vim.cmd("setlocal nonumber") + vim.cmd("setlocal norelativenumber") + vim.cmd("setlocal modifiable") + local buf = vim.api.nvim_get_current_buf() + -- local win = vim.api.nvim_get_current_win() + -- local window_height = vim.api.nvim_win_get_height(win) + -- local window_width = vim.api.nvim_win_get_width(win) + -- local border_top_bottom = string.rep("-", window_width - 3) + -- local border_sides = "|" .. string.rep(" ", window_width - 5) .. "|" + -- local message = " Welcome to PicVim! Displaying image: " .. vim.fn.expand "%:p" + -- local lines = {} + -- table.insert(lines, message) + -- table.insert(lines, border_top_bottom) + -- for _ = 1, window_height - 4 do + -- table.insert(lines, border_sides) + -- end + -- table.insert(lines, border_sides) + -- table.insert(lines, border_top_bottom) + -- vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + -- vim.api.nvim_win_set_cursor(win, { 1, 0 }) + vim.api.nvim_buf_set_lines( + buf, + 0, + -1, + false, + { " Welcome to PicVim! Displaying image: " .. vim.fn.expand("%:p") } + ) + vim.cmd("setlocal nomodifiable") + vim.cmd("setlocal nowrap") + vim.cmd("setlocal nolist") + local debounce_timer = nil + local debounce_interval = 50 + local keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } + local function redraw() + if not vim.b.img then + return + end + local image = vim.b.img + setmetatable(image, Image) + local win = vim.api.nvim_get_current_win() + local window_height = vim.api.nvim_win_get_height(win) + local window_width = vim.api.nvim_win_get_width(win) + local MAX_OFFSET_X = (window_width * 10) - 150 + local MIN_OFFSET_X = (-window_width * 10) + 150 + local MAX_OFFSET_Y = (window_height * 23) - 150 + local MIN_OFFSET_Y = (-window_height * 23) + 150 + image.properties.o_x = + math.min(math.max(image.properties.o_x + keypress_state.o_x, MIN_OFFSET_X), MAX_OFFSET_X) + image.properties.o_y = + math.min(math.max(image.properties.o_y + keypress_state.o_y, MIN_OFFSET_Y), MAX_OFFSET_Y) + image.properties.zoom = math.min(math.max(image.properties.zoom + keypress_state.zoom, 0.1), 5) + image.properties.rotation = (image.properties.rotation + keypress_state.rotation) % 360 + keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } + local cursor = vim.api.nvim_win_get_position(win) + local x, y = cursor[1], cursor[2] + image:draw(x, y, window_width - 6, window_height - 1) + vim.b.img = image + end + local function schedule_redraw() + if debounce_timer then + debounce_timer:stop() + debounce_timer:close() + end + debounce_timer = vim.defer_fn(function() + redraw() + debounce_timer = nil + end, debounce_interval) + end + vim.keymap.set("n", "", function() + keypress_state.o_x = keypress_state.o_x - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_x = keypress_state.o_x + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_y = keypress_state.o_y + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_y = keypress_state.o_y - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "h", function() + keypress_state.o_x = keypress_state.o_x - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "l", function() + keypress_state.o_x = keypress_state.o_x + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "j", function() + keypress_state.o_y = keypress_state.o_y + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "k", function() + keypress_state.o_y = keypress_state.o_y - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "=", function() + keypress_state.zoom = keypress_state.zoom + 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "+", function() + keypress_state.zoom = keypress_state.zoom + 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "-", function() + keypress_state.zoom = keypress_state.zoom - 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "t", function() + keypress_state.rotation = keypress_state.rotation + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "T", function() + keypress_state.rotation = keypress_state.rotation - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "o", function() + local image = vim.b.img + image.properties.o_x = 0 + image.properties.o_y = 0 + image.properties.rotation = 0 + vim.b.img = image + redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "r", function() + redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.b.no_git_diff = true + redraw() + end, + }) + vim.api.nvim_create_autocmd("VimResized", { + pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", + callback = function() + if not vim.b.img then + vim.b.img = Image:new(vim.fn.expand("%:p")) + end + local image = vim.b.img + if image then + setmetatable(image, Image) + end + local win_id = vim.api.nvim_get_current_win() + local cursor = vim.api.nvim_win_get_position(win_id) + local x, y = cursor[1], cursor[2] + local win = vim.api.nvim_get_current_win() + local window_height = vim.api.nvim_win_get_height(win) + local window_width = vim.api.nvim_win_get_width(win) + image:draw(x, y, window_width - 6, window_height - 1) + vim.b.img = image + end, + }) + vim.api.nvim_create_autocmd("BufLeave", { + pattern = "*", + callback = function() + local image = vim.b.img + if image then + setmetatable(image, Image) + end + if image and image.unload then + image:unload() + end + end, + }) end return M diff --git a/lua/picvim.lua b/lua/picvim.lua new file mode 100644 index 0000000..1d6cf6e --- /dev/null +++ b/lua/picvim.lua @@ -0,0 +1,312 @@ +local M = {} + +local id_counter = 0 + +local stdout = vim.loop.new_tty(1, false) +if not stdout then + error("failed to open stdout") +end + +local uv = vim.uv +if not uv then + uv = vim.loop +end + +local Image = {} +Image.__index = Image + +function Image:new(filepath) + id_counter = id_counter + 1 + local obj = setmetatable({}, self) + obj.filepath_o = filepath + obj.filepath = filepath + obj.id = id_counter + obj.properties = {} + obj.properties.zoom = 0.9 + obj.properties.o_x = 0 + obj.properties.o_y = 0 + obj.properties.rotation = 0 + return obj +end + +function Image:draw(x, y, w, h) + self.properties.w = w + self.properties.h = h + self:pngify() + self:rescale() + local file = io.open(self.filepath, "rb") + if not file then + print("Error: Could not open file.") + return + end + local data = file:read("*all") + file:close() + local encoded_data = vim.base64.encode(data):gsub("%/", "/") + local pos = 1 + local chunk_size = 4096 + stdout:write("\27[" .. x + 2 .. ";" .. y + 4 .. "H") + while pos <= #encoded_data do + local chunk = encoded_data:sub(pos, pos + chunk_size - 1) + pos = pos + chunk_size + local m = (pos <= #encoded_data) and "1" or "0" + local cmd + cmd = "\27_Ga=T,i=10,p=" + .. self.id + .. ",q=1,r=" + .. h + .. ",c=" + .. w + .. ",C=1,f=100,m=" + .. m + .. ";" + .. chunk + .. "\27\\" + stdout:write(cmd) + uv.sleep(1) + end + stdout:write("\x1b[H") + vim.cmd("redraw") +end + +function Image:unload() + stdout:write("\27_Ga=d\27\\") +end + +function Image:rescale() + local w, h = self.properties.w, self.properties.h + local o_x, o_y = self.properties.o_x, self.properties.o_y + local rotation = self.properties.rotation + local temp_file = "/tmp/scaled" .. self.id .. ".png" + if vim.fn.filereadable(temp_file) == 1 then + vim.fn.delete(temp_file) + end + local o_x_str = o_x >= 0 and "+" .. o_x or tostring(o_x) + local o_y_str = o_y >= 0 and "+" .. o_y or tostring(o_y) + local r_w, r_h = w * self.properties.zoom * 10, h * self.properties.zoom * 23 + local cmd = "magick " + .. self.filepath + .. " -resize " + .. r_w + .. "x" + .. r_h + .. " -background none -rotate " + .. rotation + .. " -gravity center -background none " + .. "-extent " + .. (w * 10) + .. "x" + .. (h * 23) + .. o_x_str + .. o_y_str + .. " " + .. temp_file + local result = vim.fn.system(cmd) + if vim.v.shell_error == 0 then + self.filepath = temp_file + else + vim.api.nvim_err_writeln("Error converting image: " .. result) + self.filepath = "" + end +end + +function Image:pngify() + local temp_file = "/tmp/pngify" .. self.id .. ".png" + local file_type = vim.fn.fnamemodify(self.filepath_o, ":e") + local cmd + if file_type == "png" then + self.filepath = self.filepath_o + return + end + if file_type == "gif" then + cmd = "magick " .. self.filepath_o .. "[0] " .. temp_file + else + cmd = "magick " .. self.filepath_o .. " " .. temp_file + end + local result = vim.fn.system(cmd) + if vim.v.shell_error == 0 then + self.filepath = temp_file + self.filepath_o = temp_file + else + vim.api.nvim_err_writeln("Error converting image: " .. result) + self.filepath = "" + end +end + +function M.setup() + vim.api.nvim_create_autocmd("BufEnter", { + pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", + callback = function() + if not vim.b.img then + vim.b.img = Image:new(vim.fn.expand("%:p")) + end + vim.cmd("setlocal buftype=nofile") + vim.cmd("setlocal nonumber") + vim.cmd("setlocal norelativenumber") + vim.cmd("setlocal modifiable") + local buf = vim.api.nvim_get_current_buf() + -- local win = vim.api.nvim_get_current_win() + -- local window_height = vim.api.nvim_win_get_height(win) + -- local window_width = vim.api.nvim_win_get_width(win) + -- local border_top_bottom = string.rep("-", window_width - 3) + -- local border_sides = "|" .. string.rep(" ", window_width - 5) .. "|" + -- local message = " Welcome to PicVim! Displaying image: " .. vim.fn.expand "%:p" + -- local lines = {} + -- table.insert(lines, message) + -- table.insert(lines, border_top_bottom) + -- for _ = 1, window_height - 4 do + -- table.insert(lines, border_sides) + -- end + -- table.insert(lines, border_sides) + -- table.insert(lines, border_top_bottom) + -- vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + -- vim.api.nvim_win_set_cursor(win, { 1, 0 }) + vim.api.nvim_buf_set_lines( + buf, + 0, + -1, + false, + { " Welcome to PicVim! Displaying image: " .. vim.fn.expand("%:p") } + ) + vim.cmd("setlocal nomodifiable") + vim.cmd("setlocal nowrap") + vim.cmd("setlocal nolist") + local debounce_timer = nil + local debounce_interval = 50 + local keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } + local function redraw() + if not vim.b.img then + return + end + local image = vim.b.img + setmetatable(image, Image) + local win = vim.api.nvim_get_current_win() + local window_height = vim.api.nvim_win_get_height(win) + local window_width = vim.api.nvim_win_get_width(win) + local MAX_OFFSET_X = (window_width * 10) - 150 + local MIN_OFFSET_X = (-window_width * 10) + 150 + local MAX_OFFSET_Y = (window_height * 23) - 150 + local MIN_OFFSET_Y = (-window_height * 23) + 150 + image.properties.o_x = + math.min(math.max(image.properties.o_x + keypress_state.o_x, MIN_OFFSET_X), MAX_OFFSET_X) + image.properties.o_y = + math.min(math.max(image.properties.o_y + keypress_state.o_y, MIN_OFFSET_Y), MAX_OFFSET_Y) + image.properties.zoom = math.min(math.max(image.properties.zoom + keypress_state.zoom, 0.1), 5) + image.properties.rotation = (image.properties.rotation + keypress_state.rotation) % 360 + keypress_state = { o_x = 0, o_y = 0, zoom = 0, rotation = 0 } + local cursor = vim.api.nvim_win_get_position(win) + local x, y = cursor[1], cursor[2] + image:draw(x, y, window_width - 6, window_height - 1) + vim.b.img = image + end + local function schedule_redraw() + if debounce_timer then + debounce_timer:stop() + debounce_timer:close() + end + debounce_timer = vim.defer_fn(function() + redraw() + debounce_timer = nil + end, debounce_interval) + end + vim.keymap.set("n", "", function() + keypress_state.o_x = keypress_state.o_x - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_x = keypress_state.o_x + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_y = keypress_state.o_y + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "", function() + keypress_state.o_y = keypress_state.o_y - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "h", function() + keypress_state.o_x = keypress_state.o_x - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "l", function() + keypress_state.o_x = keypress_state.o_x + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "j", function() + keypress_state.o_y = keypress_state.o_y + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "k", function() + keypress_state.o_y = keypress_state.o_y - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "=", function() + keypress_state.zoom = keypress_state.zoom + 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "+", function() + keypress_state.zoom = keypress_state.zoom + 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "-", function() + keypress_state.zoom = keypress_state.zoom - 0.2 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "t", function() + keypress_state.rotation = keypress_state.rotation + 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "T", function() + keypress_state.rotation = keypress_state.rotation - 30 + schedule_redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "o", function() + local image = vim.b.img + image.properties.o_x = 0 + image.properties.o_y = 0 + image.properties.rotation = 0 + vim.b.img = image + redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.keymap.set("n", "r", function() + redraw() + end, { buffer = buf, noremap = true, silent = true }) + vim.b.no_git_diff = true + redraw() + end, + }) + vim.api.nvim_create_autocmd("VimResized", { + pattern = "*.png,*.jpg,*.jpeg,*.gif,*.bmp", + callback = function() + if not vim.b.img then + vim.b.img = Image:new(vim.fn.expand("%:p")) + end + local image = vim.b.img + if image then + setmetatable(image, Image) + end + local win_id = vim.api.nvim_get_current_win() + local cursor = vim.api.nvim_win_get_position(win_id) + local x, y = cursor[1], cursor[2] + local win = vim.api.nvim_get_current_win() + local window_height = vim.api.nvim_win_get_height(win) + local window_width = vim.api.nvim_win_get_width(win) + image:draw(x, y, window_width - 6, window_height - 1) + vim.b.img = image + end, + }) + vim.api.nvim_create_autocmd("BufLeave", { + pattern = "*", + callback = function() + local image = vim.b.img + if image then + setmetatable(image, Image) + end + if image and image.unload then + image:unload() + end + end, + }) +end + +return M