Appearance and highlights
Options underui: menus the Org menus (org-menus), default true choice_prompt "float" (default): pick one of a fixed set of values from a floating list (org-choice-list); "input": the command line with <Tab> completion imenu_depth headline levels ofimenu(gO), default 2 conceal_links show only link descriptions (conceallevel=2) hide_emphasis_markers hide * / _ = ~ + around emphasized text hide_leading_stars show only the last star of each headline (#+STARTUP: hidestars / showstars) bullets list of symbols replacing the stars, per level checkboxes { unchecked, partial, checked } icons indent_mode virtual indentation like org-indent-mode: the text of a level-n entry starts at column 2n and headlines get n-1 columns of prefix; turns on hide_leading_stars (#+STARTUP: indent / noindent) indent_mode_turns_off_adapt_indentation adapt_indentation is off in buffers with indent_mode (true) indent_indentation_per_level columns per level of indent_mode (2): the text of a level-n entry starts after n + (per - 1)(n - 1) + 1 columns, headlines after (per - 1)(n - 1); 0 = no indentation pretty_entities\alpha→ α for every entity of Emacs' org-entities (#+STARTUP: entitiespretty / entitiesplain);x^2→ x²,a_{ij}→ aᵢⱼ (pretty_entities_include_sub_superscripts, and use_sub_superscripts = true | "{}" | false): Unicode super/subscript characters when all the characters have one, else the script is highlighted with OrgSuperscript / OrgSubscript and only the markers are hidden (Neovim cannot raise text). Not in blocks, code, verbatim or links. num number headlines with virtual text like org-num-mode (#+STARTUP: num / nonum); num_max_level, num_skip_commented, num_skip_footnotes, num_skip_tags, num_skip_unnumbered and num_format_function(numbers) -> text follow the org-num options fontify_done_headline dim DONE headlines fontify_todo_headline highlight the text of TODO headlines with OrgHeadlineTodo (org-fontify-todo-headline) level_color_stars_only the level color on the stars only (org-level-color-stars-only) hidden_keywords keywords shown without their "#+KEYWORD:" part: { "title", "subtitle", "author", "date", "email" } (org-hidden-keywords) hide_macro_markers hide the {{{ }}} of macro calls (org-hide-macro-markers) highlight_latex_and_related what LaTeX-related syntax is highlighted (org-highlight-latex-and-related), none by default like Emacs: "latex" (fragments $..$, \(..\), \[..\], $$..$$ and \begin{..} environments, OrgLatex), "native" (the same with Vim's tex syntax inside), "script" (x^2, a_{i}), "entities" (\alpha) src_highlight highlight src blocks with the language syntax src_block_faces face of src block bodies by language, like todo_keyword_faces: { python = { bg = "#e5ffb8" } } ("" = blocks without a language) (org-src-block-faces) todo_keyword_faces { WAITING = ":foreground #e0af68 :weight bold" }, or a highlight table, or a group name priority_faces the same per priority (org-priority-faces): { A = "ErrorMsg", ["10"] = { fg = "gray" } } tag_faces the same per tag (org-tag-faces)
<C-c><C-x>\ Toggle pretty entities in the buffer (org-toggle-pretty-entities, toggle_pretty_entities). :Org entities_help List every entity with its LaTeX and HTML code (org-entities-help).
entities_user (org-entities-user) adds entities of your own, or replaces built-in ones, for display, completion and export:
entities_user = {
-- name, LaTeX, LaTeX needs math mode, HTML, ASCII, Latin-1, UTF-8
{ "snowman", "\\diamond", true, "☃", "[snow]", "[snow]", "☃" },
}
:Org num_mode Toggle headline numbering in the buffer (org-num-mode).
:Org indent_mode Toggle virtual indentation in the buffer
(org-indent-mode).
Turning indent mode or numbering on or off, also when a buffer starts with them, runs the User autocmd OrgIndentMode or OrgNumMode (org-indent-mode-hook, org-num-mode-hook), data.enabled telling which.
Images and LaTeX previews Image links and LaTeX fragments can be shown as images in place of their text, like Emacs (org-link-preview, org-latex-preview). A backend draws them, chosen withui.images.backend: "native"vim.ui.img, Neovim 0.13+, in a terminal with the Kitty graphics protocol (kitty, Ghostty, WezTerm...). Support is checked once by asking the terminal. Not through tmux. "snacks" Snacks.image from snacks.nvim (also inside tmux, withallow-passthrough on). For Neovim before 0.13. "image.nvim" 3rd/image.nvim. "auto" (default) the first of these that works;falseturns previews off. :checkhealth org tells which one is used. With the native backend, the text of the link is concealed behind blank inline text as wide as the image, virtual lines keep the rows the image needs under the line free, and the images are placed on the screen after every redraw, so they follow scrolling, folding, window splits and resizes, also in floating windows. Images are sized for each window and sized again when it is resized; in a window too narrow for an image the image is not drawn. When a line wraps after an image, the image is drawn under the line and the link text stays visible; on the first line of a closed fold, an image taller than one row shows its link text. An image is shown once all of it fits in the window, and hidden under floating windows and the popup menu. Only PNG can be sent to the terminal: other formats are converted with ImageMagick (magick). Sizes come from the terminal's cell size in pixels. Editing a previewed link or fragment removes its preview.
Placement,ui.images.placement: "inline" (default) the image replaces the link or fragment: its top row is on the line, at the link's column, and the text after the link moves right to make room. The rows under the line are shared by the images of that line (side by side). An image is at most as wide as the columns left after the text before it. On the cursor line of the current window the text shows again, in every mode, with the image under the line, so it can be edited; moving off the line puts the image back in place. The windows showing the buffer get 'conceallevel' 2. Inline math ($x$,\(x\)) is scaled to one row, as tall as the text; other fragments keep their size. A fragment or environment over several lines is drawn in place too (Neovim 0.11+): its other lines are hidden (conceal_lines), the image starts on its first line and the text after it on its last line follows the image; the cursor on any of its lines shows the text again, with the image under its last line. Before 0.11 such fragments use "below", and image.nvim always does. "below" under the line, at the link's column, the text left as it is (images of one line are stacked).
<prefix>xv org-link-preview (link_preview): on a link, toggle its <C-c><C-x><C-v> preview; else preview the links of the current entry, or of the Visual selection, again when called again. A count like the Emacs prefix: 4 hides the preview at the cursor, else the entry's (or the selection's); 16 previews the whole buffer, 64 hides them all; 1 also previews links with a description (entry, link or selection), 11 in the whole buffer, any other count in the whole buffer too. <prefix>xV org-link-preview-refresh (link_preview_refresh): preview <C-c><C-x><C-M-v> every image link of the buffer again. <prefix>xl org-latex-preview (latex_preview): on a fragment, toggle <C-c><C-x><C-l> its preview; else render the fragments of the current entry (or of the Visual selection). 4 hides the entry's (or selection's) previews, 16 previews the whole buffer, 64 hides them all. Rendering runs in the background.
The same as ex commands; a range limits them, a number is the count: :[range]Org link_preview [N] :[range]Org latex_preview [N] :[range]Org link_preview_region [linked] (org-link-preview-region) :[range]Org link_preview_clear (org-link-preview-clear) :Org link_preview_refresh :[range]Org clear_latex_preview (org-clear-latex-preview) Without a range the last three act on the whole buffer. The obsolete Emacs names work too: toggle_inline_images, remove_inline_images, redisplay_inline_images, toggle_latex_fragment, preview_latex_fragment.
Which links: links of a type with a preview function (org-link-set-parameters :preview), with no description, or whose description is a sole plain or angle link of such a type ([[https://example.com][file:thumb.png]] shows thumb.png); with a count of 1 (or linked) the links with a description are previewed by their own target. Built in: file: and attachment: links (bracket, plain or angle) to an existing file whose extension is in ui.images.extensions, and http(s) links to such a file name when ui.images.remote allows. Links in src, example, export and comment blocks, comments, fixed-width lines and property drawers are left alone, like Emacs.
Preview functions (org-link-set-parameters :preview) come from links.types.<type>.preview, else from org.ui.images.set_preview():
require("org.ui.images").set_preview("thumb", function(path, ctx)
return vim.fn.expand("~/thumbs/" .. path .. ".png")
end)
The function gets the link's path and a context { bufnr, row (1-based), col, end_col (0-based), type, link, refresh, callback } and returns the image file to show, nil or false for none, or true when it calls ctx.callback(file) later (after a download, say). A type org.nvim does not know becomes a link type (links.types), and a function registered for file or attachment replaces the built-in one.
set_preview({type}, {fn}) registers {fn} for {type} links, or removes it when {fn} is nil.
Remote images (org-display-remote-inline-images),ui.images.remote: "skip" (default) http(s) links are not previewed; "download" the image is fetched with curl on every preview; "cache" fetched once intostdpath("cache")/org/remote-images, and again by link_preview_refresh. Emacs applies this to TRAMP files; org.nvim has no TRAMP and uses it for http(s) image links instead.
Batches (org-link-preview-batch-size, org-link-preview-delay): the first ui.images.batch_size links (6) are previewed at once, the others in batches of that size every ui.images.preview_delay seconds (0.05), so a long file stays responsive; 0 previews all at once. Clearing previews (or editing the link) drops the links still waiting.
Size (org-display-inline-image--width):ui.images.actual_widthis true (default) the image's own size; a number that many pixels; false, { n } the:widthof the paragraph's #+ATTR_ORG, else of another #+ATTR_x with a readable width, else n pixels (or the own size).:widthis pixels (300, 300px), a percentage (50%) or a fraction from 0 to 2 (0.5, 0.7\linewidth) of the text width ('textwidth', else the window), or t (own size). An ORG-IMAGE-ACTUAL-WIDTH property (inherited: t, nil, a number or (n)) overrides it.ui.images.max_width(org-image-max-width) caps the width: "fill-column" ('textwidth', else 70 columns), "window", a number of pixels or a fraction of the window.ui.images.max_heightcaps the rows.
Alignment (org-image-align): an image link alone in its paragraph is drawn at ui.images.align ("left", "center" or "right"), or as its #+ATTR_ORG (else #+ATTR_x) says with :align center|right|left or :center t. Native backend only.
TAB cycling (org-cycle-link-previews-display): with ui.images.cycle_display, showing an entry's children previews its own links, showing the subtree previews all of them, and folding it removes them.
At startup: #+STARTUP: linkpreviews (inlineimages) and latexpreview preview a file when it opens, like ui.images.startup and ui.latex_preview.startup; the no... words turn that off, and the last word of a pair wins.
LaTeX fragments are those org-latex-preview renders: $x$ (no blank after the opening or before the closing dollar, no $ before it, a blank, punctuation or line end after it), $$x$$, \(x\) and \[x\], which may span lines of a paragraph, and \begin{env} ... \end{env} environments with the \end alone on its line. Fragments in verbatim or code markup, link targets, blocks other than quote/verse/special blocks, and keywords other than TITLE, CAPTION, AUTHOR and DATE are skipped.
Rendering follows org-create-formula-image with the process named byui.latex_preview.process(org-preview-latex-default-process), fromprocesses(org-preview-latex-process-alist): "dvipng" latex + dvipng (the Emacs default) "dvisvgm" latex + dvisvgm (SVG, converted to PNG for vim.ui.img) "xelatex" xelatex + dvisvgm "imagemagick" pdflatex + convert "tectonic" tectonic + pdftocairo (org.nvim) "pdflatex" pdflatex + pdftocairo (org.nvim) "auto" (default) uses the first of dvipng, dvisvgm, tectonic, pdflatex, imagemagick that is installed. A process is a table withprograms,message,image_input_type,image_output_type,image_size_adjust({ buffer, html }),latex_header,latex_compiler,image_converterandtransparent_image_converter; commands run in a shell in a temporary directory, with %f (input file), %F (its full path), %b (base name), %o (output directory), %O (output file), %D (DPI) and %S (scale, DPI / 140).processesadds or replaces entries.
The document is ui.latex_preview.header (org-format-latex-header, the Emacs header by default) with [DEFAULT-PACKAGES] and [PACKAGES] filled from export.latex and the file's #+LATEX_HEADER lines (SETUPFILE too), like org-latex-make-preamble for snippets. foreground is "default" (the Normal text), "auto" (the text at the fragment) or a color; background is "default" (Normal), "Transparent" or a color (:foreground, :background). Formulas are about as tall as a text line times scale. Images are written to ui.latex_preview.image_directory (org-preview-latex-image-directory, "ltximg/" next to the file; buffers without a file use stdpath("cache")/org/ltximg), or to cache_dir when set. When a step fails, its output is in the *Org Preview LaTeX Output* buffer.
Where images work Previews depend on three things outside org.nvim: the Neovim version, the terminal, and what sits between them (tmux, zellij, SSH). :checkhealth org shows what it found and which backend it uses.
Which backend draws the images ("auto"):
1. "native" (vim.ui.img) when Neovim is 0.13 or newer AND the terminal
answers the Kitty graphics query. The query is asked once, the first
time a preview is made, and waits up to 1 s when nothing answers.
2. else "snacks" when snacks.nvim is installed with its image module and
the terminal supports it with unicode placeholders;
3. else "image.nvim" when it is installed;
4. else no previews, with a message saying why.
Set ui.images.backend to a name to skip the others (and the 1 s wait).
Setups:
kitty, Ghostty (Neovim 0.13+) native: everything below works.
WezTerm (Neovim 0.13+) native. WezTerm's Kitty graphics support
is partial; snacks.nvim can't draw in it
(no unicode placeholders): with an older
Neovim use image.nvim.
Neovim 0.11 and 0.12 no vim.ui.img: snacks.nvim or
image.nvim, in a terminal they support.
tmux vim.ui.img writes straight to the
terminal and tmux drops it, so its query
gets no answer (the 1 s wait) and "auto"
falls back to snacks.nvim. It needs
set -g allow-passthrough on in
tmux.conf (snacks.nvim tries to set it).
Or run Neovim outside tmux.
zellij no passthrough: no backend can draw.
SSH native and snacks.nvim send the image
data through the connection. Images,
ImageMagick and the LaTeX programs must
be on the machine running Neovim.
Terminal.app, iTerm2, Alacritty, no Kitty graphics protocol: no native
Windows Terminal, GNU screen or snacks.nvim previews. image.nvim may
still work there (e.g. with ueberzug on
Linux).
What each backend does:
native snacks image.nvim
image in place of its link yes yes (5) no (below)
image under its link yes yes (1) yes
:align / org-image-align yes no no
follows scrolling and folds yes yes yes
under floating windows, menus hidden (2) covered (4) its backend
partly visible images hidden (3) cut cut
several windows on one buffer yes yes first only
(1) A link alone on its line gets its image at the link's column. With
text around the link, snacks.nvim draws the image at the start of
the next line and puts an icon at the link.
(2) So they don't cover menus; they come back when the float closes.
(3) vim.ui.img can't crop: an image is drawn once all of it fits.
(4) snacks.nvim draws images as text (unicode placeholders), so floats
cover them like any text.
(5) snacks.nvim conceals the text itself; an image with text after it
on a line may go under the line with an icon at the link.
When it goes wrong:
"no image backend" or "does not support the Kitty graphics protocol"
Neovim is older than 0.13, the terminal lacks the protocol, or tmux
or zellij is in between (see above). Install snacks.nvim or
image.nvim, run Neovim outside tmux, or use another terminal.
Nothing happens for a second on the first preview
The terminal query waiting for an answer (tmux, unsupported
terminals). Set ui.images.backend.
Blank rows under the link (or a blank gap in place of it) but no image
The native backend reserved the rows but the image is not fully
visible, a float covers it, or the terminal ignored it. Scroll it
into view; check :checkhealth org.
An image is not where the link is, or everything looks centered
:align and org-image-align only work with the native backend;
with snacks.nvim see (1) above. Images starting where the link text
ends was a bug fixed in org.nvim (update).
"can't convert ... to PNG"
The native backend only sends PNG: install ImageMagick (magick)
for JPEG, SVG and the rest.
An image vanished (the terminal was cleared or reset)
<prefix>xV (link_preview_refresh) draws them again.
Images the wrong size after changing the font size
Sizes come from the terminal's cell size, read again when Neovim is
resized; <prefix>xV redraws them.
LaTeX: "no LaTeX renderer found" / "you need to install the programs"
Install latex and dvipng (or tectonic and poppler for pdftocairo).
When a render fails, its output is in *Org Preview LaTeX Output*.
Emphasis follows org-emphasis-regexp-components: the markers need a space, (, ', ", { or - (or the line start) before them, may span one line break, and bold, italic, underline and strike-through can nest.
Quote and verse block contents are highlighted as ordinary Org (lists, tables, timestamps, markup) on top of OrgQuoteBlock; center, special (#+begin_note...) and dynamic (#+BEGIN:) blocks highlight only their delimiter lines. Every block ends at the next headline, whether or not it has its #+end line. #+begin_export LANG blocks get LANG's syntax, as #+begin_src LANG blocks do. A buffer's #+OPTIONS: ^:t, ^:{} or ^:nil overrides ui.use_sub_superscripts, for pretty entities and for the "script" LaTeX highlighting (^:nil displays like ^:{}, as in Emacs). Complete statistics cookies ([2/2], [100%]) use OrgStatisticDone, others OrgStatistic (org-checkbox-statistics-done/-todo); OrgSexpDate is diary sexps (<%%(...)>, %%(...) lines) and OrgArchived the text of headlines tagged ARCHIVE.
Highlight groups (all default, override with nvim_set_hl()):
OrgHeadlineLevel1..8 (linked to the colorscheme's markdown headings)
OrgTodo OrgDone OrgHeadlineDone OrgHeadlineComment
OrgPriority OrgPriorityA OrgPriorityB OrgPriorityC OrgTags
OrgTimestamp OrgTimestampInactive OrgPlanning OrgClockDuration OrgClockSum
OrgDrawer OrgPropertyKey OrgPropertyValue OrgKeyword OrgKeywordValue
OrgTitle OrgComment OrgBlock OrgQuoteBlock OrgBlockDelimiter
OrgBold OrgItalic OrgUnderline OrgStrikethrough OrgVerbatim OrgCode
OrgLink OrgListBullet OrgListTerm OrgCheckbox OrgCheckboxChecked
OrgCheckboxPartial OrgStatistic OrgStatisticDone OrgTable
OrgTableSeparator OrgTableFormula OrgSexpDate OrgArchived
OrgInlineSrc OrgInlineSrcMarker OrgInlineSrcLang
OrgExportSnippetMarker OrgExportSnippetBackend
OrgFootnote OrgTarget OrgLatex OrgHorizontalRule OrgMacro
OrgHiddenStars OrgSuperscript OrgSubscript OrgInlinetask OrgSparseMatch
OrgMenuKey OrgMenuHeading OrgMenuDesc OrgMenuMore OrgMenuOn OrgMenuOff
OrgMenuValue OrgMenuSelected (org-key-menus, org-choice-list)
OrgAgenda*