local function parse_stderr(data) local message = table.concat(data, "\n") local level = "info" -- Check each line for error or warning for line in message:gmatch("[^\r\n]+") do local lower_line = line:lower() if lower_line:match("^%s*error:") then level = "error" break elseif lower_line:match("^%s*warning:") then level = "warn" -- Don't break here, in case an error appears later end end return message, level end local function typst_build_and_open_sioyek() local bufname = vim.fn.expand('%:p') local pdf_path = vim.fn.fnamemodify(bufname, ':r') .. '.pdf' local cmd = string.format('typst compile "%s"', bufname) vim.fn.jobstart(cmd, { on_exit = function(_, exit_code) if exit_code == 0 then vim.notify("Typst build completed successfully", vim.log.levels.INFO, { title = "Typst Build", timeout = 3000, }) -- Now open or reload Sioyek local sioyek_running = vim.fn.system('pgrep sioyek'):match('%d+') if sioyek_running then vim.fn.system('sioyek --execute-command reload_no_flicker') vim.notify("Sioyek reloaded", vim.log.levels.INFO, { title = "Sioyek", timeout = 2000, }) else vim.fn.jobstart('sioyek "' .. pdf_path .. '"', { on_exit = function(_, sioyek_exit_code) if sioyek_exit_code == 0 then vim.notify("Sioyek opened", vim.log.levels.INFO, { title = "Sioyek", timeout = 2000, }) else vim.notify("Failed to open Sioyek", vim.log.levels.ERROR, { title = "Sioyek", timeout = 3000, }) end end }) end else vim.notify("Typst build failed", vim.log.levels.ERROR, { title = "Typst Build", timeout = 5000, }) end end, stderr_buffered = true, on_stderr = function(_, data) if data and #data > 0 then local message, level = parse_stderr(data) vim.notify(message, vim.log.levels[level:upper()], { title = "Typst Build", timeout = 5000, }) end end, }) end vim.api.nvim_create_user_command('TypstBuild', typst_build_and_open_sioyek, {}) -- Create an autocommand group local typst_group = vim.api.nvim_create_augroup('TypstBuildGroup', { clear = true }) -- Create a command to toggle the autocommand local typst_auto_build_enabled = false -- Function to create the autocommand local function create_typst_autocmd() vim.api.nvim_create_autocmd('BufWritePost', { group = typst_group, pattern = '*.typ', callback = function() vim.cmd('TypstBuild') end, }) end -- Create a command to toggle the autocommand vim.api.nvim_create_user_command('TypstAutoBuild', function() typst_auto_build_enabled = not typst_auto_build_enabled if typst_auto_build_enabled then create_typst_autocmd() vim.notify('Typst auto-build enabled', vim.log.levels.INFO) else vim.api.nvim_clear_autocmds({ group = typst_group }) vim.notify('Typst auto-build disabled', vim.log.levels.INFO) end end, {}) return { -- { "kaarmu/typst.vim", ft = "typst", lazy = false }, -- { -- "chomosuke/typst-preview.nvim", -- lazy = false, -- or ft = 'typst' -- version = "0.3.*", -- config = function() -- require("typst-preview").setup({ -- -- Setting this true will enable printing debug information with print() -- debug = false, -- -- -- Custom format string to open the output link provided with %s -- -- Example: open_cmd = 'firefox %s -P typst-preview --class typst-preview' -- open_cmd = 'sioyek --execute-command reload_no_flicker %s', -- -- -- Setting this to 'always' will invert black and white in the preview -- -- Setting this to 'auto' will invert depending if the browser has enable -- -- dark mode -- invert_colors = "never", -- -- -- Whether the preview will follow the cursor in the source file -- follow_cursor = true, -- -- -- Provide the path to binaries for dependencies. -- -- Setting this will skip the download of the binary by the plugin. -- -- Warning: Be aware that your version might be older than the one -- -- required. -- dependencies_bin = { -- -- if you are using tinymist, just set ['typst-preview'] = "tinymist". -- ["typst-preview"] = nil, -- ["websocat"] = nil, -- }, -- -- -- This function will be called to determine the root of the typst project -- get_root = function(path_of_main_file) -- return vim.fn.fnamemodify(path_of_main_file, ":p:h") -- end, -- -- -- This function will be called to determine the main file of the typst -- -- project. -- get_main_file = function(path_of_buffer) -- return path_of_buffer -- end, -- }) -- end, -- build = function() -- require("typst-preview").update() -- end, -- }, }