From 7fc2e5c543d83102e0f5233e93e5563719b433dc Mon Sep 17 00:00:00 2001 From: Nikolai Papin Date: Fri, 4 Jul 2025 23:22:13 +0300 Subject: [PATCH] refactor: frontmatter for markdown; feat: plugin for rendering images in markdown; feat: pastify; feat: markdown preview in browser --- nvim/lua/mappings.lua | 7 ++++ nvim/lua/options.lua | 9 +++++ nvim/lua/plugins/image.lua | 48 +++++++++++++++++++++++++++ nvim/lua/plugins/markdown-preview.lua | 11 ++++++ nvim/lua/plugins/pastify.lua | 41 +++++++++++++++++++++++ nvim/lua/snippets/markdown.lua | 27 ++++++--------- 6 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 nvim/lua/plugins/image.lua create mode 100644 nvim/lua/plugins/markdown-preview.lua create mode 100644 nvim/lua/plugins/pastify.lua diff --git a/nvim/lua/mappings.lua b/nvim/lua/mappings.lua index 8440248..87836a9 100644 --- a/nvim/lua/mappings.lua +++ b/nvim/lua/mappings.lua @@ -102,6 +102,13 @@ vim.keymap.set("n", "gpg", function() os.execute("gpg --detach-sign " .. opened_file_path) -- Execute the GPG sign command end, { desc = "Sign currently open file with GPG" }) +vim.api.nvim_create_autocmd({ "CursorMoved", "WinEnter", "BufEnter" }, { + callback = function() + vim.defer_fn(function() + vim.cmd("redraw!") + end, 50) + end, +}) function Leave_snippet() if diff --git a/nvim/lua/options.lua b/nvim/lua/options.lua index ef8cd92..37abe90 100644 --- a/nvim/lua/options.lua +++ b/nvim/lua/options.lua @@ -5,6 +5,15 @@ require "nvchad.options" -- local o = vim.o -- o.cursorlineopt ='both' -- to enable cursorline! +local enable_providers = { + "python3_provider", + } + + for _, plugin in pairs(enable_providers) do + vim.g["loaded_" .. plugin] = nil + vim.cmd("runtime " .. plugin) + end + -- disable wrap vim.o.wrap = false diff --git a/nvim/lua/plugins/image.lua b/nvim/lua/plugins/image.lua new file mode 100644 index 0000000..7f432dd --- /dev/null +++ b/nvim/lua/plugins/image.lua @@ -0,0 +1,48 @@ +return { + "3rd/image.nvim", + event = 'BufEnter', + build = false, -- so that it doesn't build the rock https://github.com/3rd/image.nvim/issues/91#issuecomment-2453430239 + config = function() + require("image").setup({ + backend = "kitty", + processor = "magick_cli", -- or "magick_rock" + integrations = { + markdown = { + enabled = true, + clear_in_insert_mode = true, + download_remote_images = true, + only_render_image_at_cursor = false, + only_render_image_at_cursor_mode = "popup", + floating_windows = false, -- if true, images will be rendered in floating markdown windows + filetypes = { "markdown", "vimwiki" }, -- markdown extensions (ie. quarto) can go here + }, + neorg = { + enabled = true, + filetypes = { "norg" }, + }, + typst = { + enabled = true, + filetypes = { "typst" }, + }, + html = { + enabled = false, + }, + css = { + enabled = false, + }, + }, + max_width = 800, + max_height = 400, + max_width_window_percentage = nil, + max_height_window_percentage = nil, + window_overlap_clear_enabled = false, -- toggles images when windows are overlapped + window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "snacks_notif", "scrollview", "scrollview_sign" }, + editor_only_render_when_focused = false, -- auto show/hide images when the editor gains/looses focus + tmux_show_only_in_active_window = false, -- auto show/hide images in the correct Tmux window (needs visual-activity off) + hijack_file_patterns = { "*.png", "*.jpg", "*.jpeg", "*.gif", "*.webp", "*.avif" }, -- render image files as images when opened + }) + end, + opts = { + processor = "magick_cli", + } +} diff --git a/nvim/lua/plugins/markdown-preview.lua b/nvim/lua/plugins/markdown-preview.lua new file mode 100644 index 0000000..9584aec --- /dev/null +++ b/nvim/lua/plugins/markdown-preview.lua @@ -0,0 +1,11 @@ +return { + { + "iamcco/markdown-preview.nvim", + cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, + build = "cd app && npm install", + init = function() + vim.g.mkdp_filetypes = { "markdown" } + end, + ft = { "markdown" }, + }, +} diff --git a/nvim/lua/plugins/pastify.lua b/nvim/lua/plugins/pastify.lua new file mode 100644 index 0000000..3131b09 --- /dev/null +++ b/nvim/lua/plugins/pastify.lua @@ -0,0 +1,41 @@ +return { + 'TobinPalmer/pastify.nvim', + cmd = { 'Pastify', 'PastifyAfter' }, + config = function() + require('pastify').setup { + opts = { + absolute_path = false, -- use absolute or relative path to the working directory + apikey = '', -- Api key, required for online saving + local_path = '/assets/imgs/', -- The path to put local files in, ex /assets/images/.png + save = 'local', -- Either 'local' or 'online' or 'local_file' + filename = function() return vim.fn.expand("%:t:r") .. '_' .. os.date("%H-%M-%S_%d.%m.Y") end, -- The file name to save the image as, if empty pastify will ask for a name + -- Example function for the file name that I like to use: + -- filename = function() return vim.fn.expand("%:t:r") .. '_' .. os.date("%Y-%m-%d_%H-%M-%S") end, + -- Example result: 'file_2021-08-01_12-00-00' + default_ft = 'markdown', -- Default filetype to use + }, + ft = { -- Custom snippets for different filetypes, will replace $IMG$ with the image url + html = '', + markdown = '![]($IMG$)', + tex = [[\includegraphics[width=\linewidth]{$IMG$}]], + css = 'background-image: url("$IMG$");', + js = 'const img = new Image(); img.src = "$IMG$";', + xml = '', + php = '"; ?>', + python = '# $IMG$', + java = '// $IMG$', + c = '// $IMG$', + cpp = '// $IMG$', + swift = '// $IMG$', + kotlin = '// $IMG$', + go = '// $IMG$', + typescript = '// $IMG$', + ruby = '# $IMG$', + vhdl = '-- $IMG$', + verilog = '// $IMG$', + systemverilog = '// $IMG$', + lua = '-- $IMG$', + }, + } + end +} diff --git a/nvim/lua/snippets/markdown.lua b/nvim/lua/snippets/markdown.lua index d318691..3d10f6d 100644 --- a/nvim/lua/snippets/markdown.lua +++ b/nvim/lua/snippets/markdown.lua @@ -5,7 +5,6 @@ local i = ls.insert_node local f = ls.function_node local extras = require("luasnip.extras") local rep = extras.rep - local timestamp = function() return tostring(os.time()) end @@ -23,29 +22,23 @@ return { s("frontmatter", { t("---"), t({ "", "Markdown note", "" }), - t({ "", "title: \"" }), i(1), t("\""), + t({ "", "title: \"" }), i(8), t("\""), t({ "", "date: \"" }), f(get_date, {}), t("\""), t({ "", "author: \"" }), f(get_name, {}), t("\""), - t({ "", "keywords: ["}), i(2), t("]"), - t({ "", "tags: [["}), i(3), t("]]"), + t({ "", "keywords: ["}), i(6), t("]"), + t({ "", "tags: [["}), i(7), t("]]"), t({ "", "id: " }), f(timestamp, {}), - t({ "", "---", "", "# " }), - rep(1), -- Reuses the first insert node - t({ "", ""}), - t({ "", ""}), - i(4) -- Final cursor position - }), - - -- Creates a mood report template - s("wellbeingreport", { - t("---"), - t({ "", "Well-being report", "" }), - t({ "", "date: " }), f(get_date, {}), + t({ "", "" }), t({ "", "sleep: " }), i(1), t("/5"), t({ "", "emotions: [" }), i(2), t("]"), t({ "", "comfort: " }), i(3), t("/5"), t({ "", "complaints: ["}), i(4), t("]"), t({ "", "mood: " }), i(5), t("/10"), - t({ "", "---" }), + + t({ "", "---", "", "# " }), + rep(8), -- Reuses the first insert node + t({ "", ""}), + t({ "", ""}), + i(9) -- Final cursor position }), }