Move code to lua/ folder

This commit is contained in:
2025-01-24 02:49:21 +03:00
parent 509602d781
commit cce5ee4097
2 changed files with 590 additions and 270 deletions

548
init.lua
View File

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

312
lua/picvim.lua Normal file
View File

@@ -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", "<Left>", function()
keypress_state.o_x = keypress_state.o_x - 30
schedule_redraw()
end, { buffer = buf, noremap = true, silent = true })
vim.keymap.set("n", "<Right>", function()
keypress_state.o_x = keypress_state.o_x + 30
schedule_redraw()
end, { buffer = buf, noremap = true, silent = true })
vim.keymap.set("n", "<Down>", function()
keypress_state.o_y = keypress_state.o_y + 30
schedule_redraw()
end, { buffer = buf, noremap = true, silent = true })
vim.keymap.set("n", "<Up>", 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