Skip to content

Repository files navigation

quarto-render.nvim

Run the Quarto CLI on the document you're editing. That's the whole plugin.

demo

Its one real idea: a document can declare several output formats at once, so rendering is two actions, not one.

format:
  html:
    toc: true
  pdf: default
  docx: default

<leader>rr builds html. <leader>ra builds all three. Everything is buffer-local to the quarto filetype — in any other buffer the commands don't exist and the mappings are unset.

Install

Requires Neovim 0.10+ and the Quarto CLI. No Lua dependencies.

{ "matthewgson/quarto-render.nvim", ft = "quarto", opts = {} }

setup() is optional — the defaults work untouched.

Mappings

Key Action
<leader>rr Render the first declared format
<leader>ra Render all declared formats
<leader>rf Pick a format, then render it
<leader>rp Toggle the live preview
<leader>rk Stop this buffer's jobs
<leader>ro Open the output, or the live preview

Buffer-local, so nothing outside a .qmd buffer changes. See LazyVim for how these sit alongside the distro's own bindings.

LazyVim

Built and tested against the LazyVim distro, with defaults chosen to fit its conventions rather than fight them.

<leader>r is unclaimed by LazyVim core and by every lang.* extra. The one extra that does claim it is editor.refactoring (+refactor, which includes rf and rp) — and because these mappings are buffer-local, they shadow it only inside .qmd and leave it untouched everywhere else.

Left alone on purpose:

<leader>c code — cf format, cr rename, cp markdown preview
<leader>q quit / session
<leader>a <leader>g <leader>G ai, git
<localleader>, <CR> R.nvim, inside quarto buffers
<C-Space> <C-h/j/k/l> <C-\> tmux navigation

With the lang.r extra, R.nvim is already live in .qmd buffers: it owns <CR> for sending lines to R, and a <localleader>q group labelled quarto whose bindings render through your R session. Nothing here touches either, and this plugin's which-key group is labelled quarto render so the two read differently at a glance. (<leader>cp markdown preview is registered ft = "markdown", so it never applied to .qmd to begin with.)

Keep ft = "quarto" in the spec: the LazyVim starter sets defaults.lazy = false, so without it this would load at startup.

Commands

Command
:QuartoRender First declared format
:QuartoRender all Every declared format
:QuartoRender {format} A named format (completion offers what the document declares)
:QuartoRenderPick Choose a format via vim.ui.select()
:QuartoRenderPreview Toggle quarto preview — live reload on save
:QuartoRenderStop Stop this buffer's jobs
:QuartoRenderOpen Open the output, or the preview URL
:QuartoRenderFormats Show detected formats and where they came from

The QuartoRender prefix avoids shadowing quarto-nvim's global :QuartoPreview.

Configuration

opts = {
  quarto_cmd         = "quarto",
  render_args        = {},        -- extra args per render, e.g. { "--no-clean" }
  preview_args       = {},        -- extra args per preview, e.g. { "--no-browser" }
  save_before_render = true,      -- quarto reads from disk
  open_after_render  = false,     -- <leader>ro opens on demand regardless
  verbosity          = "normal",  -- silent | errors | normal | verbose

  keys = {                        -- `keys = false` disables all of them
    group       = "<leader>r",    -- which-key group anchor; a label, not a prefix
    render      = "<leader>rr",
    render_all  = "<leader>ra",
    render_pick = "<leader>rf",
    preview     = "<leader>rp",
    stop        = "<leader>rk",
    open        = "<leader>ro",
  },
}

Each value is a complete mapping, not a suffix, so overriding one leaves the others alone; any single entry can be false.

Note

This keys table lives inside opts. It is not lazy.nvim's spec-level keys.

Format detection

The front matter is scanned for a top-level format: key — scalar, flow sequence ([html, pdf]), block mapping, or block sequence. Only column-zero keys count, so nested options and a format: under metadata: are ignored. Extension formats (acm-pdf) work. Declaring nothing falls back to _quarto.yml, then to html; :QuartoRenderFormats says which happened.

Limitations

  • Not a YAML parser: no anchors, aliases, or multi-line flow collections.
  • Formats from metadata-files: or --profile aren't detected, though :QuartoRender all still renders them: it passes no --to.
  • Before the first render of a session, :QuartoRenderOpen predicts the output path and can't know about a project output-dir:. Afterwards it uses what quarto reported.

Related

This plugin renders documents — it doesn't run cells, complete inside them, or display images. For those: quarto-nvim, otter.nvim, R.nvim, molten-nvim. They coexist with this one.

Development

nvim --headless -u NONE -i NONE -l tests/run.lua   # tests
stylua --check .
vhs assets/demo.tape                               # re-record the demo

License

MIT

About

Render Quarto documents from Neovim. Small, dependency-free, and multi-format aware.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages