From bbee894544c8239dee28039fea1b3fb72b2f5df8 Mon Sep 17 00:00:00 2001 From: Roel de Cort Date: Fri, 31 Jul 2026 23:29:34 +0200 Subject: [PATCH] feat(nixvim): add native Markdown previews Signed-off-by: Roel de Cort --- README.md | 2 +- config/default.nix | 2 +- config/plugins/utils/markdown-preview.nix | 29 ------ config/plugins/utils/md-render.nix | 114 ++++++++++++++++++++++ flake.lock | 76 ++++++++++++++- flake.nix | 11 ++- 6 files changed, 201 insertions(+), 33 deletions(-) delete mode 100644 config/plugins/utils/markdown-preview.nix create mode 100644 config/plugins/utils/md-render.nix diff --git a/README.md b/README.md index ef71420a..a82e66a1 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ home-manager.users..home.packages = [ - `extra_plugins.nix`: Configures additional plugins. - `mini.nix`: Configures the Mini plugin. - `obsidian.nix`: Confiugres the Obsidian plugin, for note-taking purposes. -- `markdown-preview.nix`: Configures the Markdown Preview plugin. +- `md-render.nix`: Provides in-terminal Markdown previews, synchronized splits, and native Mermaid rendering. - `toggleterm.nix`: Provides a floating scratch terminal; cmux owns persistent panes and sessions. Please refer to the individual `.nix` files for more detailed configuration information. diff --git a/config/default.nix b/config/default.nix index ee04dcef..884f595d 100644 --- a/config/default.nix +++ b/config/default.nix @@ -56,7 +56,7 @@ _: { ./plugins/utils/whichkey.nix ./plugins/utils/extra_plugins.nix ./plugins/utils/mini.nix - ./plugins/utils/markdown-preview.nix + ./plugins/utils/md-render.nix ./plugins/utils/obsidian.nix ./plugins/utils/toggleterm.nix ./plugins/utils/web-devicons.nix diff --git a/config/plugins/utils/markdown-preview.nix b/config/plugins/utils/markdown-preview.nix deleted file mode 100644 index 70dfc03e..00000000 --- a/config/plugins/utils/markdown-preview.nix +++ /dev/null @@ -1,29 +0,0 @@ -_: { - plugins = { - markdown-preview = { - enable = true; - settings = { - browser = "firefox"; - echo_preview_url = 1; - port = "6969"; - preview_options = { - disable_filename = 1; - disable_sync_scroll = 1; - sync_scroll_type = "middle"; - }; - theme = "dark"; - }; - }; - }; - - keymaps = [ - { - mode = "n"; - key = "mp"; - action = "MarkdownPreview"; - options = { - desc = "Toggle Markdown Preview"; - }; - } - ]; -} diff --git a/config/plugins/utils/md-render.nix b/config/plugins/utils/md-render.nix new file mode 100644 index 00000000..69c592c5 --- /dev/null +++ b/config/plugins/utils/md-render.nix @@ -0,0 +1,114 @@ +{ + lib, + mdRender, + mmdr, + pkgs, + ... +}: +let + mdRenderPlugin = pkgs.vimUtils.buildVimPlugin { + pname = "md-render.nvim"; + version = "3.4.0"; + src = mdRender; + }; + + mmdc = pkgs.writeShellApplication { + name = "mmdc"; + text = '' + input="" + output="" + theme="" + background="" + + while (( $# > 0 )); do + if (( $# < 2 )); then + echo "mmdc: missing value for $1" >&2 + exit 2 + fi + + case "$1" in + -i|--input) + input="$2" + ;; + -o|--output) + output="$2" + ;; + -t|--theme) + theme="$2" + ;; + -b|--backgroundColor) + background="$2" + ;; + -s|--scale) + ;; + *) + echo "mmdc: unsupported argument: $1" >&2 + exit 2 + ;; + esac + + shift 2 + done + + if [[ -z "$input" || -z "$output" ]]; then + echo "mmdc: input and output are required" >&2 + exit 2 + fi + + args=(-i "$input" -o "$output" -e png) + if [[ -n "$theme" ]]; then + args+=(-t "$theme") + fi + + if [[ -n "$background" ]]; then + config="$(mktemp "''${TMPDIR:-/tmp}/md-render-mmdr.XXXXXX")" + trap 'rm -f -- "$config"' EXIT + printf '{"themeVariables":{"background":"%s"}}\n' "$background" > "$config" + args+=(-c "$config") + fi + + ${lib.getExe mmdr} "''${args[@]}" + ''; + }; +in +{ + extraPlugins = [ mdRenderPlugin ]; + extraPackages = [ mmdc ]; + + keymaps = [ + { + mode = "n"; + key = "mp"; + action = lib.nixvim.mkRaw '' + function() + local columns = vim.o.columns + local width = math.min(160, math.floor(columns * 0.8), math.max(80, math.floor(columns * 0.6))) + + require("md-render").preview.show({ max_width = width - 2 }) + + local win = vim.api.nvim_get_current_win() + local config = vim.api.nvim_win_get_config(win) + if config.relative ~= "" then + vim.api.nvim_win_set_config(win, { + relative = config.relative, + width = width, + row = config.row, + col = math.floor((columns - width) / 2), + }) + end + end + ''; + options = { + desc = "Toggle Markdown preview"; + }; + } + { + mode = "n"; + key = "ms"; + action = "vertical MdRender split"; + options = { + desc = "Open synchronized Markdown split"; + }; + } + ]; +} diff --git a/flake.lock b/flake.lock index 990c6376..1e8bbea2 100644 --- a/flake.lock +++ b/flake.lock @@ -55,6 +55,63 @@ "type": "github" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "md-render": { + "flake": false, + "locked": { + "lastModified": 1783476820, + "narHash": "sha256-q/0ZRbsvADdS7LBD03uuAABdkE330jbIHY8066t0MvI=", + "owner": "delphinus", + "repo": "md-render.nvim", + "rev": "56057d92d636a45cdeac5d1857e776e10d279d69", + "type": "github" + }, + "original": { + "owner": "delphinus", + "ref": "v3.4.0", + "repo": "md-render.nvim", + "type": "github" + } + }, + "mmdr": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1783356010, + "narHash": "sha256-uekh1vJ19dAPP7+4PiqSlJizApZLpDhBWBoyN+fgS9s=", + "owner": "1jehuang", + "repo": "mermaid-rs-renderer", + "rev": "2f993bd79a55235eb59a34d807852276ba25bea7", + "type": "github" + }, + "original": { + "owner": "1jehuang", + "ref": "v0.3.1", + "repo": "mermaid-rs-renderer", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1785318670, @@ -122,7 +179,7 @@ "inputs": { "flake-parts": "flake-parts_2", "nixpkgs": "nixpkgs_2", - "systems": "systems" + "systems": "systems_2" }, "locked": { "lastModified": 1784814601, @@ -160,12 +217,29 @@ "root": { "inputs": { "flake-parts": "flake-parts", + "md-render": "md-render", + "mmdr": "mmdr", "nixpkgs": "nixpkgs", "nixvim": "nixvim", "pre-commit-hooks": "pre-commit-hooks" } }, "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { "locked": { "lastModified": 1774449309, "narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=", diff --git a/flake.nix b/flake.nix index c1940ef5..96acf752 100644 --- a/flake.nix +++ b/flake.nix @@ -10,6 +10,14 @@ pre-commit-hooks = { url = "github:cachix/pre-commit-hooks.nix"; }; + md-render = { + url = "github:delphinus/md-render.nvim/v3.4.0"; + flake = false; + }; + mmdr = { + url = "github:1jehuang/mermaid-rs-renderer/v0.3.1"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = @@ -44,7 +52,8 @@ module = import ./config; # import the module directly # You can use `extraSpecialArgs` to pass additional arguments to your module files extraSpecialArgs = { - # inherit (inputs) foo; + mdRender = inputs.md-render; + mmdr = inputs.mmdr.packages.${system}.default; }; }; nvim = nixvim'.makeNixvimWithModule nixvimModule;