org.nvim

Literate Neovim config (literate)

Stability: experimental (org-extensions-stability)

literate makes an org file your Neovim configuration: saving it tangles its Lua blocks and runs the ones you changed, so a new option or keymap works at once, and a block's error shows on its line in the org file.

require("org").setup({
  extensions = { literate = { files = { "~/.config/nvim/init.org" } } },
})

A literate file is one of files (paths or globs; default stdpath("config")/init.org) or, with detect, an org file under a directory of allow (default: stdpath("config")) whose Lua blocks tangle by default:

#+PROPERTY: header-args:lua :tangle lua/config.lua :mkdirp yes

* Options
#+begin_src lua
vim.o.relativenumber = true
#+end_src

Trust

Saving a literate file runs Lua in your Neovim and writes the files its
blocks tangle to, so it happens only for files you chose:
  - the files in files are trusted;
  - a detected file must be under allow, and with confirm (default)
    the first save asks whether to tangle and run it; the answer is kept
    in stdpath("data")/org/literate-trust.json (delete its entry to be
    asked again);
  - any other org file with a :tangle header (a file you downloaded, a
    repository you cloned) is saved like any org file: nothing is tangled
    or run.
Opening a literate file runs and evaluates nothing: what it holds is
remembered as text (noweb and :var references, which can evaluate
blocks, are expanded only when a trusted file is tangled). literate_goto_org
only looks at trusted files. The actions below work on the current buffer
when you run them, like :Org tangle or executing a block.

Saving it

When a literate file is written it is tangled with org-babel tangle (so :tangle, :noweb, :comments... work as usual) and, with reload, the Lua blocks whose text is new since the last tangle (or since the file was opened) run in file order, in this Neovim, and so do the blocks whose tangled text changed (a block they include with noweb was edited). Blocks you did not touch don't run again. An error while tangling is reported once per save and never interrupts the write. An error, at compile or run time, is a diagnostic on the org line it comes from (for an error raised in a function the block calls, such as vim.o.nosuchoption = 1, the line of the call) (diagnostics), and in the quickfix list with quickfix; a block that failed runs again on the next save until it works. A notification says what was tangled and reloaded.

Actions

  literate_reload     run the Lua block at point, or every tangled Lua
                      block of the file outside one
  literate_run_block  run the Lua block at point (tangled or not) and show
                      the value it returns
  literate_health     compile every Lua block without running it; syntax
                      errors become diagnostics
  literate_goto_org   in the tangled file: jump to the org line the
                      cursor's line comes from, by the link comments of
                      :comments link, else by matching the text in the
                      blocks that tangle to this file
  literate_bootstrap  :Org literate_bootstrap [path] writes an init.lua
                      (default: next to the org file) for the pattern below

Bootstrapping

Neovim reads init.lua, not init.org. Tangle the blocks to another file (lua/config.lua) and let :Org literate_bootstrap write an init.lua that loads it. On startup that init.lua re-tangles init.org first when it is newer than the tangled file (edited on another machine or pulled with git), with a small tangler of its own (org.nvim is not loaded yet). It keeps the lua blocks whose :tangle is the tangled file, taking :tangle and :noweb from the block, else the nearest heading's header-args:lua / header-args property, else #+PROPERTY, and expands <<name>> references when :noweb is yes, tangle, no-export or strip-export. It does not evaluate anything: no :var, no Lisp in header arguments, no <<name()>> results, no :prologue; use saving in Neovim (the full tangle) for those. If it fails, it says so and loads the tangled file it has. Then it runs the tangled file. Blocks tangled to other files are not loaded by the stub. So the setup is:

~/.config/nvim/init.org         the configuration
~/.config/nvim/lua/config.lua   tangled from it (on save)
~/.config/nvim/init.lua         the stub (written once)

org.nvim itself is set up from the tangled file like any plugin, with the literate extension on so the next save tangles again.

Options

  files           literate org files (stdpath("config")/init.org)
  detect          also files with header-args:lua :tangle (true)
  allow           directories detect looks in ({ stdpath("config") })
  confirm         ask before the first save of a detected file (true)
  tangle_on_save  tangle when written (true)
  reload          run the changed Lua blocks (true)
  diagnostics     errors as diagnostics (true)
  quickfix        errors in the quickfix list too (false)
  notify          report what was tangled and run (true)
  bootstrap_file  init.lua of literate_bootstrap (next to the org file)