Editor Integration

Emacs (Apheleia)

Apheleia runs external formatters on buffer save, preserving cursor position.

(with-eval-after-load 'apheleia
  (push '(snapper . ("snapper" "--format" "org")) apheleia-formatters)
  (push '(org-mode . snapper) apheleia-mode-alist)
  ;; Add for other formats:
  (push '(latex-mode . snapper) apheleia-mode-alist)
  (push '(markdown-mode . snapper) apheleia-mode-alist))

The --format flag auto-detects from the file extension, so you can omit it if your files have standard extensions.

Vim / Neovim

Use formatprg to pipe through snapper:

autocmd FileType org setlocal formatprg=snapper\ --format\ org
autocmd FileType tex setlocal formatprg=snapper\ --format\ latex
autocmd FileType markdown setlocal formatprg=snapper\ --format\ markdown

Then gq to reformat selected text, or gggqG to reformat the entire buffer.

For Neovim with conform.nvim:

require("conform").setup({
  formatters = {
    snapper = {
      command = "snapper",
      args = { "--format", "$FILETYPE" },
      stdin = true,
    },
  },
  formatters_by_ft = {
    org = { "snapper" },
    tex = { "snapper" },
    markdown = { "snapper" },
  },
})

LSP (any editor with LSP support)

Snapper ships a Language Server Protocol implementation. Start it with:

snapper lsp

This provides document formatting, range formatting, and diagnostics (flags lines with multiple sentences) over the standard LSP protocol on stdin/stdout.

Neovim (native LSP)

vim.api.nvim_create_autocmd("FileType", {
  pattern = { "org", "tex", "markdown" },
  callback = function()
    vim.lsp.start({
      name = "snapper",
      cmd = { "snapper", "lsp" },
    })
  end,
})

Emacs (eglot)

(add-to-list 'eglot-server-programs
             '((org-mode latex-mode markdown-mode) "snapper" "lsp"))

VS Code

Add to settings.json (requires a generic LSP client extension):

{
  "lsp.servers": {
    "snapper": {
      "command": "snapper",
      "args": ["lsp"],
      "filetypes": ["org", "tex", "markdown"]
    }
  }
}

Helix

Add to ~/.config/helix/languages.toml:

[[language]]
name = "org"
language-servers = ["snapper"]

[language-server.snapper]
command = "snapper"
args = ["lsp"]

Generic (any editor)

Snapper reads stdin and writes stdout by default. Any editor that supports piping through an external program works:

cat paper.org | snapper --format org