Files
nvim/lua/plugins/pdf-viewer.lua
zias 6ec8190beb refactor: modularize nvim config into lua/config + lua/plugins
- Extract all options, keymaps, and autocommands into lua/config/
- Move every plugin spec into its own file under lua/plugins/
- Add custom inline orng colorscheme (dark + light) synced to macOS appearance
- Consolidate image.nvim into pdf-viewer.lua (fix duplicate spec)
- Fix image.nvim processor: magick -> magick_cli
- Remove conflicting nvim-autopairs (kept mini.pairs)
- Fix broken <C-f> keymap (was calling non-existent builtin cmd)
- Delete lua/kickstart/ and lua/custom/ folders
- Add colors/orng.vim + colors/orng-light.vim stubs for mid-session switching
- init.lua reduced from 1078 lines to 49 lines
2026-02-26 11:54:58 +01:00

108 lines
3.8 KiB
Lua

-- lua/plugins/pdf-viewer.lua
-- PDF viewer using pdftoppm + image.nvim (kitty/magick backend)
-- Requires: poppler (brew install poppler), kitty terminal
return {
'3rd/image.nvim',
opts = {
backend = 'kitty',
processor = 'magick_cli',
integrations = {
markdown = { enabled = true },
},
},
config = function(_, opts)
local image = require 'image'
image.setup(opts)
local pdf_state = {}
-- Open PDF: convert all pages to PNG via pdftoppm, then display page 1
vim.api.nvim_create_autocmd('BufReadPost', {
pattern = '*.pdf',
callback = function()
local pdf_path = vim.fn.expand '%:p'
local temp_dir = vim.fn.tempname()
vim.fn.mkdir(temp_dir, 'p')
local bufnr = vim.api.nvim_get_current_buf()
vim.notify('Converting PDF…', vim.log.levels.INFO)
vim.fn.jobstart({ 'pdftoppm', '-png', pdf_path, temp_dir .. '/page' }, {
on_exit = function(_, code)
vim.schedule(function()
if code ~= 0 then
vim.notify('Failed to convert PDF', vim.log.levels.ERROR)
return
end
-- Count pages
local handle = vim.loop.fs_scandir(temp_dir)
local page_count = 0
if handle then
while true do
local name = vim.loop.fs_scandir_next(handle)
if not name then break end
if name:match '^page%-%d+%.png$' then page_count = page_count + 1 end
end
end
pdf_state[bufnr] = { temp_dir = temp_dir, current_page = 1, total_pages = page_count }
local function show_page(page_num)
local state = pdf_state[bufnr]
if not state then return end
image.clear()
vim.bo[bufnr].modifiable = true
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { '' })
vim.bo[bufnr].modifiable = false
local page_file = string.format('%s/page-%02d.png', state.temp_dir, page_num)
local img = image.from_file(page_file, { buffer = bufnr })
if img then
img:render()
vim.notify(string.format('Page %d / %d', page_num, state.total_pages), vim.log.levels.INFO)
else
vim.notify('Failed to load page ' .. page_num, vim.log.levels.ERROR)
end
end
local function change_page(delta)
local state = pdf_state[bufnr]
if not state then return end
local new_page = state.current_page + delta
if new_page < 1 or new_page > state.total_pages then return end
state.current_page = new_page
show_page(new_page)
end
-- Buffer-local navigation keys
local map = function(lhs, fn, desc)
vim.keymap.set('n', lhs, fn, { buffer = bufnr, desc = desc })
end
map('j', function() change_page(1) end, 'PDF: next page')
map('k', function() change_page(-1) end, 'PDF: previous page')
map('<Right>', function() change_page(1) end, 'PDF: next page')
map('<Left>', function() change_page(-1) end, 'PDF: previous page')
map('q', '<cmd>bd!<cr>', 'PDF: close')
show_page(1)
end)
end,
})
end,
})
-- Cleanup temp files on buffer close
vim.api.nvim_create_autocmd('BufDelete', {
pattern = '*.pdf',
callback = function(args)
if pdf_state[args.buf] then
image.clear()
vim.fn.delete(pdf_state[args.buf].temp_dir, 'rf')
pdf_state[args.buf] = nil
end
end,
})
end,
}