Skip to content

Releases: selimacerbas/mdkite.nvim

v2.1.0

Choose a tag to compare

@selimacerbas selimacerbas released this 02 Oct 09:33

Added

  • A buffer whose filetype is dotted with a markdown part, such as rzk.markdown for a literate file, previews whole as Markdown with no config, since Neovim reads a dotted filetype as each of its parts in turn; before, only the filetype markdown did. Thanks @ddxtanx (#32).
  • filetypes option: filetypes with no markdown part, such as { "quarto", "rmd" }, preview whole as Markdown too. The list adds to markdown and never replaces it. A value that is not a list of filetype names is refused by setup() with one error, mdkite: filetypes takes a list of filetype names, such as { "quarto" }; setup changed nothing, and that call applies nothing. Thanks @ddxtanx (#32).

v2.0.0

Choose a tag to compare

@selimacerbas selimacerbas released this 02 Oct 01:12

Upgrading from markdown-preview.nvim

The plugin is mdkite.nvim from this release, and the server it runs on is kitehost.nvim, live-server.nvim's name from its v2.0.0, which this release requires. Through 2.x the former lazy.nvim spec still installs it, since GitHub redirects the repository's former name; the former module and commands still work, each warning once a session and naming its replacement, and the former opt-out global still opts out. All three are removed in 3.0.0. Everything else in the table takes the new name now.

What Before 2.0.0 From 2.0.0
Repository and lazy.nvim spec selimacerbas/markdown-preview.nvim selimacerbas/mdkite.nvim
Server dependency selimacerbas/live-server.nvim selimacerbas/kitehost.nvim, v2.0.0 or newer
Module require("markdown_preview") require("mdkite")
Commands :MarkdownPreview, :MarkdownPreviewRefresh, :MarkdownPreviewStop :MdKite with start, refresh and stop, one for each former command in that order, and the new toggle, completed by <Tab>, none taking an argument; a bare :MdKite runs start
Notices Markdown Preview: ... mdkite: ... on every notice this plugin makes (the server's own notices begin kitehost:), but a deprecation warning, which is Neovim's own text (:MarkdownPreview is deprecated, use :MdKite start instead.)
Cache directory stdpath("cache")/markdown-preview stdpath("cache")/mdkite
Opt-out global vim.g.loaded_markdown_preview vim.g.loaded_mdkite; the former one still opts out
Auto-refresh augroup MarkdownPreviewAuto MdKiteAuto
Browser console prefix [markdown-preview] [mdkite]
Page title Markdown Preview mdkite

In takeover mode, a preview of a release before 2.0.0 still running in another Neovim keeps its lock under the former cache directory: a start names it and its port in one error, starts nothing beside it and writes nothing under that directory.

A lazy.nvim spec that relies on opts or config = true and is named after neither repository (a name or dir of its own, or a fork under another name) sets main = "mdkite": two top-level modules ship through 2.x, mdkite and markdown_preview, so lazy.nvim cannot choose the one its opts go to and reports Lua module not found for config of <name>. The new spec, the former one, a fork that keeps the name mdkite.nvim and a spec with its own config function need none.

Added

  • lazy.lua: lazy.nvim installs kitehost.nvim from this plugin's own declaration, so a spec with no dependencies line still gets it.
  • :MdKite toggle starts the preview, or stops the one running, a joined one included.

Changed

  • BREAKING: The plugin runs on kitehost.nvim v2.0.0 or newer (the upgrading section above). With an older server on the runtimepath, or none, a start refuses with one error, mdkite: requires kitehost.nvim v2.0.0 or newer; install or update selimacerbas/kitehost.nvim, where a missing server raised a Lua error as the plugin loaded. Each start looks for the server again until it finds one, so one put on the runtimepath after the plugin loaded is used.
  • A kitehost.nvim without a capability the plugin requires, server.features.host_check (the Host check that keeps a DNS-rebinding page from the token the loopback page carries) or server.features.start_raises, is refused at start the same way, with one error naming the floor and the flag it lacks, mdkite: requires kitehost.nvim v2.0.0 or newer, and the installed one lacks features.host_check; update selimacerbas/kitehost.nvim, where a server without the asset route was only warned about.
  • The start-failure notification reads mdkite: failed to start server (port <port>): <reason>.
  • vim.uv replaces the deprecated vim.loop throughout.
  • When the port is taken by another program, the start-failure notification says so and how to pick another: mdkite: port <port> is in use by another program. Set port to a free one in setup(), or port = 0 with instance_mode = "multi" for an OS-assigned port. A port the OS assigns keeps the generic notification, whose reason names the port.
  • When the server binds 127.0.0.1 (the default host, and what "localhost" binds), the preview URL no longer carries the ?t= token; a server bound to any other address keeps it. The address the server bound decides, not the host setting: "localhost" opens http://127.0.0.1:<port>/, since a browser tries localhost's ::1 first, and a takeover secondary follows the address the primary's lock records. The URL is what lands in browser history, its sync and the process list, so the token stays out of all three.

Removed

  • BREAKING: Neovim 0.9, which the README listed as supported. Every release since v1.0.0 needed Neovim 0.10 and failed at first use on 0.9; the requirement is now checked at load, so on 0.9 the plugin shows one notification, "mdkite: requires Neovim 0.10 or newer", and every command refuses with the same message.
  • The unreferenced 7 MB demo gif, so a fresh checkout is smaller.

Fixed

  • A takeover-mode lock file that cannot be made private fails the start with the start-failure notification; before, the server stayed running with an empty lock and the start raised a Lua error.
  • A preview that fails to start (a taken port, an address kitehost cannot bind, a lock file that cannot be made private) keeps no autocmds, no session token and no workspace pointer, and drops a takeover role it held as a secondary; before, six autocmds kept refreshing a preview that did not exist.
  • When kitehost refuses to switch the preview to another buffer, the notice reads mdkite: could not retarget: <reason> and the preview keeps showing the buffer it showed, its text and images included. When the server reports file watching off after a switch, a warning says that changes made outside this editor may not refresh the preview. A reload or scroll update kitehost refuses is reported once per preview server. Before, all three went unreported.
  • An IPv6 host such as "::1", with instance_mode = "multi", gives a preview URL in brackets, http://[::1]:<port>/?t=<token>, which browsers open; the token stays, since only a 127.0.0.1 bind's page carries it. The IPv6 wildcard "::", however it is spelled, shows http://[::1]:<port>/?t=<token>, as kitehost.nvim does, and an IPv4-mapped address such as "::ffff:127.0.0.1" shows its IPv4 form.
  • When a second Neovim fails to start a takeover preview on the port another Neovim's preview holds (its check for the running preview timed out, say), the running preview keeps serving its own buffer and keeps its lock file, and the notification adds that another Neovim's preview may hold the port; before, the second instance overwrote the preview's files with its own buffer and a token the server refuses, and removed the lock.
  • A takeover start joins another Neovim's preview only while the process its lock names runs and the server on the lock's port takes the lock's token and refuses a request without one; before, anything listening on that port counted, so a start could join a crashed preview's lock whose port another program had since taken and send that program its scroll updates, token included.
  • A session token that cannot be made fails the start with one error notification, before any server starts. A failure after the preview server started (the preview's files, the lock file, an auto_refresh_events entry Neovim does not know) stops the server and shows one error notification with the reason and no Lua source position; before, the server kept running and the start raised a Lua error. The same holds when joining another Neovim's preview, when the workspace directory cannot be created, and when switching buffers, where a failed switch returns the preview to the buffer it showed. A write that fails no longer empties the file the preview serves, and a lock file whose port is not a valid port is treated as absent.
  • Changing host with setup() while a preview runs no longer makes the next :MdKite start on another buffer refuse; the new host applies to the next start.
  • A Neovim that joined another's takeover preview reports a scroll update the running preview refuses (after a restart with a new token) or cannot receive (the preview is gone) once, and again after :MdKite start joins anew; before, it said nothing.
  • Stopping the preview within 200 ms of starting it or switching buffers no longer raises a Lua error from the pending browser open, and no browser opens for the stopped preview.
  • On Windows, when the runtimepath lists no copy of the preview page the plugin ships, a start finds it from the plugin's own path whichever slash that path is written with; before, a path written with forward slashes failed the start with Could not locate assets/index.html in runtimepath.

Security

  • The takeover-mode lock file is made private (mode 0600) on the open file before the session token is written to it, whatever the file was before; the open's own mode applies only to a file it creates. No released version left the token readable by others: a start has removed the lock before every write since the token joined it in v1.8.0, and the 0644 lock files of v1.7.0 and earlier held no token. The loopback preview page still carries the token (SECURITY.md).

v1.10.0

Choose a tag to compare

@selimacerbas selimacerbas released this 07 Jul 16:52

Features

  • Relative images — ![](pic.png) next to your markdown file now renders in the preview, via a token-gated asset route resolved against the source file's directory (#17). Requires live-server.nvim v1.5.0+.
  • Network access — new host option (default 127.0.0.1); set "0.0.0.0" to view the preview from another machine, e.g. over SSH. Thanks @icyveins7 (#28, #30).
  • Custom CSS — new custom_css option layers your stylesheet over the bundled styles (supports ~ and $VAR). Thanks @y2w8 (#21).
  • YAML front matter — shown in a collapsible panel and stripped from the render by default; configurable via yaml_mode ("panel" / "hide" / "raw"). Closes #18. Based on work by @Al3cLee (#20).
  • allow_raw_html option — set false to render embedded HTML as plain text when previewing untrusted markdown (#27).
  • WSL — browser launch now tries wslview → explorer.exe → powershell.exe, and surfaces the preview URL if none work (#26).

Fixes

  • Task-list checkboxes now render (the plugin was loaded under the wrong global name). Thanks @tcuthbert (#25).
  • Preview no longer gets stuck on "Waiting for content…" after a Neovim restart — the token placeholder collided with a JS sentinel and broke auth on tab reuse (#31).
  • Code-block language badge and copy button stay pinned while scrolling wide code, and no longer reset scroll position on live updates. Based on work by @Al3cLee (#20).
  • Mermaid diagrams fit one page when printing to PDF. Thanks @harish2704 (#29).

Security

  • Removed a stale cors = true that emitted Access-Control-Allow-Origin: *, which could let any website read the auth token cross-origin.
  • On a non-loopback host, the token is no longer baked into the served page and the preview page itself is token-gated (the browser bootstraps from the ?t= URL).
  • New Security section in the README covering the token model, raw-HTML trade-off, CDN loading, and network-bind exposure.

Note: relative-image support needs live-server.nvim v1.5.0+; the plugin warns once if the installed version is older.

v1.9.0

Choose a tag to compare

@selimacerbas selimacerbas released this 24 May 16:23
545cf3b
  • Feature: Lifecycle hooks via setup({ hooks = { on_start = fn, on_stop = fn } }). on_start(url) runs after the preview is ready and receives the full URL (with the auth token included), useful when open_browser = false. on_stop() runs after the server stops and cleanup completes. Both default to nil. (#24, thanks @gogongxt)

v1.8.0

Choose a tag to compare

@selimacerbas selimacerbas released this 24 May 09:56
e8e231f
  • Feature: default_theme = "dark" | "light" config option to set the initial preview theme. The in-browser sun/moon toggle still works after page load. Closes #19. (#16, thanks @gogongxt)
  • Feature: mermaid_elk = true enables the ELK layout engine for mermaid diagrams, producing cleaner layouts for medium and large flowcharts and class diagrams. Off by default (adds ~800 KB CDN fetch). Enable per-diagram with %%{init: {"layout": "elk"}}%%. (#22, thanks @fuzzybear3)
  • Security: Token auth on content.md and the live-reload control endpoints. A 128-bit token is generated at server start, threaded through the auto-opened browser URL, and stashed in sessionStorage. No user-facing config needed. (#23)
  • Requires: live-server.nvim v1.4.0+ for the token auth feature. If you pin versions, upgrade both together. Lazy.nvim users on branch = "main" or version = "*" are fine.

v1.7.0

Choose a tag to compare

@selimacerbas selimacerbas released this 19 Apr 21:36
  • Feature: browser config option to override the system default browser (#11)
    • browser = nil (default): system default
    • browser = "Firefox": browser by app/binary name (macOS uses open -a)
    • browser = { "google-chrome", "--incognito" }: full command with args

v1.6.0

Choose a tag to compare

@selimacerbas selimacerbas released this 19 Apr 21:25
  • Fix: overlay zoom-in no longer cuts off content. The fullscreen mermaid viewer now properly scrolls when zoomed beyond the viewport (#11)
  • Feature: bottom_padding config option (0–1 fraction) controls how far the last line can scroll. Default 0.5 means the final line scrolls to the viewport midpoint (#12)
  • Feature: WSL support — the preview now opens via explorer.exe on Windows Subsystem for Linux (#14)

v1.5.3

Choose a tag to compare

@selimacerbas selimacerbas released this 24 Mar 14:58
  • Strip YAML front matter from preview — metadata blocks no longer render as headings/text

v1.5.2

Choose a tag to compare

@selimacerbas selimacerbas released this 21 Mar 00:16
  • Add task list checkbox rendering (- [ ] / - [x]) via markdown-it-task-lists

v1.5.1

Choose a tag to compare

@selimacerbas selimacerbas released this 13 Mar 08:41
  • Remove heading anchor permalink symbols (#) from preview for cleaner readability