Move code to lua/ folder
This commit is contained in:
548
init.lua
548
init.lua
@@ -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
312
lua/picvim.lua
Normal 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
|
||||||
Reference in New Issue
Block a user