Org in any editor
The server works in any editor with an LSP client, with no org-lsp plugin
at all: point the client at org-lsp for Org files and it talks over
standard input and output. What the plugins add are keys, windows and
looks; what an editor does with plain LSP, it does here too.
Setting it up#
Tell the editor's LSP client to run org-lsp (the whole path, or put it on
your PATH) for the org file type (*.org). The server's options go in the
client's initialization options, as JSON; configuration.org has every
option with its default, and the server also reads the shared configuration
file, ~/.config/org-lsp/config.toml.
Neovim without the plugin, for example, with Neovim's own client (0.11 or newer):
vim.lsp.config('org_lsp', {
cmd = { 'org-lsp' },
filetypes = { 'org' },
root_markers = { '.git' },
init_options = { org_agenda_files = { '~/org' } },
})
vim.lsp.enable('org_lsp')
-- What Neovim's client does not turn on by itself.
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if not client or client.name ~= 'org_lsp' then
return
end
vim.wo.foldmethod = 'expr'
vim.wo.foldexpr = 'v:lua.vim.lsp.foldexpr()'
vim.wo.foldlevel = 99
vim.lsp.completion.enable(true, client.id, args.buf, { autotrigger = true })
vim.lsp.inlay_hint.enable(true, { bufnr = args.buf })
end,
})What it does#
- Colors
- The server sends the token types of the LSP specification
(
function,keyword,string…), which every color scheme colors, each Org part as the one closest to Emacs's faces: headlines by level asoutline-1and on, TODO keywords as keywords, tags as attributes. The protocol lists them. Bold and italic text get no color of their own: LSP has no standard kind for them. - Commands
- As code actions, at the cursor: the TODO state, the priority, the timestamp under the cursor, clocking, archiving, refiling, a new heading, and the agenda, the TODO list, the agenda menu and capture.
- Questions
- A choice (the agenda menu, a TODO state, a capture template)
comes as a list to pick from (
window/showMessageRequest). LSP has no way to ask for text, so a command that wants text or a date (a search, a date to schedule) says PROMPT: answer with a rename at the cursor: run the editor's rename (grnin Neovim) and type the answer as the new name;-alone is an empty answer, the prompt's default. - The agenda
- A file,
Agenda.org, that the editor opens as an Org file: colored, and with every command its keys have in Emacs as a code action: on an entry's line the entry's first (its TODO state, dates, tags, clocking, archiving, marks for a bulk action), then the view's (later, earlier, today, the span, filters, log and entry text modes, the menu). Follow mode and column view are left out: they need the editor's code. The server changes the open buffer with edits (workspace/applyEdit) when it moves or when the files change, so the editor counts the buffer as changed: save it (:wwrites the same text) or leave without saving (:qa!). - The rest of LSP
- Folding, completion, hover, diagnostics (
org-lint), formatting (tables, tags), going to a link's target, symbols, renaming a tag or a heading, and inlay hints (org-indent-mode, clocked time).
What needs a plugin: keys (cit, <Leader>oa), the calendar of the date
prompt, capture in a window of its own, the agenda in a split, images, and
everything the editors' pages list beyond LSP.
The commands that ask a question (a TODO state, the agenda, capture,
refiling) come only to an editor that says it shows the server's lists
(window.showMessage in its capabilities), or with message_prompts set to
true, or with message_requests set to false for an editor that shows no
list: the choices then come first in the code actions. The agenda and
capture come only to one that opens a document the server asks it to show
(window/showDocument), or with show_document set to true. Helix
does that without saying so and shows no list, so its configuration sets
both.