| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- -- 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 parse_stderr(data, filter_level)
- local messages = {}
- local current_message = {}
- local current_level = "info"
- -- Split data into blocks
- for _, line in ipairs(data) do
- if line:match("^%s*$") then
- -- Empty line, end of block
- if #current_message > 0 then
- table.insert(messages, { message = table.concat(current_message, "\n"), level = current_level })
- current_message = {}
- current_level = "info"
- end
- else
- -- Check for error/warning/info at the beginning of the block
- local lower_line = line:lower()
- if lower_line:match("^%s*error:") then
- current_level = "error"
- elseif lower_line:match("^%s*warning:") then
- current_level = "warn"
- elseif lower_line:match("^%s*info:") then
- current_level = "info"
- end
- table.insert(current_message, line)
- end
- end
- -- Add last block if exists
- if #current_message > 0 then
- table.insert(messages, { message = table.concat(current_message, "\n"), level = current_level })
- end
- -- Filter messages based on filter_level
- local filtered_messages = {}
- for _, msg in ipairs(messages) do
- if not filter_level or msg.level == filter_level then
- table.insert(filtered_messages, msg)
- end
- end
- return filtered_messages
- 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 messages = parse_stderr(data)
- local error_count = 0
- local warning_count = 0
- local info_count = 0
- for _, msg in ipairs(messages) do
- if msg.level == "error" then
- error_count = error_count + 1
- elseif msg.level == "warn" then
- warning_count = warning_count + 1
- elseif msg.level == "info" then
- info_count = info_count + 1
- end
- end
- local notify = require("notify")
- local original_opts = vim.deepcopy(notify.options)
- notify.setup({
- stages = "static",
- -- Add any other temporary options here
- })
- for _, msg in ipairs(messages) do
- if msg.level ~= "error" then
- -- Route warnings and info to notify without displaying
- vim.notify(msg.message, vim.log.levels[msg.level:upper()], {
- title = "Typst Build " .. msg.level,
- timeout = 0,
- silent = true,
- log = true,
- })
- end
- end
- notify.setup(original_opts)
- for _, msg in ipairs(messages) do
- if msg.level == "error" then
- vim.notify(msg.message, vim.log.levels.ERROR, {
- title = "Typst Build Error",
- timeout = 5000,
- })
- end
- end
- if warning_count > 0 then
- vim.notify(string.format("%d warning(s)", warning_count), vim.log.levels.WARN, {
- title = "Typst Build Summary",
- timeout = 3000,
- })
- end
- if info_count > 0 then
- vim.notify(string.format("%d info message(s)", info_count), vim.log.levels.INFO, {
- title = "Typst Build Summary",
- timeout = 2000,
- })
- end
- 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,
- -- },
- }
|