Neovim
Neovim setup uses two upstream plugins you probably already have: nvim-treesitter for the grammar, nvim-lspconfig for the LSP server. httui-lang plugs into both.
Install
Section titled “Install”1. The LSP server binary
Section titled “1. The LSP server binary”cargo install httui-lspOr grab a prebuilt binary from
Releases and put
it on your PATH. Verify:
httui-lsp --version2. The tree-sitter parser
Section titled “2. The tree-sitter parser”:TSInstall httuiThis pulls tree-sitter-httui and compiles the parser into your
nvim-treesitter install. (Already registered upstream as of
nvim-treesitter v0.x.)
3. The lspconfig entry
Section titled “3. The lspconfig entry”In your Neovim config, add:
-- init.lualocal lspconfig = require("lspconfig")
-- httui-lang serverlocal configs = require("lspconfig.configs")if not configs.httui_lsp then configs.httui_lsp = { default_config = { cmd = { "httui-lsp" }, filetypes = { "httui", "markdown" }, root_dir = function(fname) return vim.fs.find( { ".httui", "runbooks", "connections.toml", "envs" }, { upward = true, path = fname } )[1] and vim.fs.dirname(vim.fs.find( { ".httui", "runbooks", "connections.toml", "envs" }, { upward = true, path = fname } )[1]) end, settings = { httui = { env = "staging", -- or read dynamically }, }, }, }endlspconfig.httui_lsp.setup({})(Upstream lspconfig will eventually ship a built-in httui_lsp
config — until then the snippet above is canonical.)
Filetype association
Section titled “Filetype association”Tell Neovim to recognise .httui as its own filetype:
vim.filetype.add({ extension = { httui = "httui", },})The LSP attaches to both httui filetype and markdown (so it
runs inside .md fenced blocks).
Tree-sitter integration
Section titled “Tree-sitter integration”Enable highlight + indent + folds via nvim-treesitter:
require("nvim-treesitter.configs").setup({ ensure_installed = { "httui", "markdown", "markdown_inline" }, highlight = { enable = true }, indent = { enable = true }, fold = { enable = true },})
-- Optional: use tree-sitter foldsvim.opt.foldmethod = "expr"vim.opt.foldexpr = "nvim_treesitter#foldexpr()"For markdown injection (httui inside .md fences), this is handled
automatically by the parsers — the markdown parser knows to
delegate to httui for http/db-* fenced regions.
Key bindings
Section titled “Key bindings”Standard LSP bindings work — define once in your on_attach:
local on_attach = function(client, bufnr) local opts = { buffer = bufnr } vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) vim.keymap.set("n", "<F2>", vim.lsp.buf.rename, opts) vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts) vim.keymap.set("n", "<leader>f", function() vim.lsp.buf.format({ async = true }) end, opts)end
lspconfig.httui_lsp.setup({ on_attach = on_attach })Completion
Section titled “Completion”Pair with nvim-cmp or your preferred completion plugin. httui-lsp
sources completions via standard LSP, no custom setup beyond having
the LSP source enabled in cmp:
require("cmp").setup({ sources = { { name = "nvim_lsp" }, -- your others },})Typing {{ triggers the completion popup with all aliases above the
cursor + env vars from the active env.
Active environment
Section titled “Active environment”The LSP picks up the active env from user.toml at vault root. To
switch from inside Neovim, use a custom command:
vim.api.nvim_create_user_command("HttuiEnv", function(opts) local clients = vim.lsp.get_active_clients({ name = "httui_lsp" }) for _, c in ipairs(clients) do c.notify("workspace/didChangeConfiguration", { settings = { httui = { env = opts.args } }, }) endend, { nargs = 1 })Then :HttuiEnv staging switches the env for hover/completion.
Run blocks from Neovim
Section titled “Run blocks from Neovim”The LSP can dispatch a “run this block” message to the httui desktop if it’s running on the same vault. Bind it via a code action or a custom command:
vim.keymap.set("n", "<leader>br", function() vim.lsp.buf.execute_command({ command = "httui.runBlock", arguments = { uri = vim.uri_from_bufnr(0), position = vim.api.nvim_win_get_cursor(0), }, })end, { desc = "Run httui block under cursor" })If the desktop isn’t running, the command is a no-op (LSP returns “no runtime”).
For headless execution, shell out to httui-tui run:
vim.keymap.set("n", "<leader>brt", function() local file = vim.api.nvim_buf_get_name(0) vim.cmd("split | terminal httui-tui run " .. file .. " --env staging")end, { desc = "Run httui runbook in TUI" })Filetype-specific options
Section titled “Filetype-specific options”vim.api.nvim_create_autocmd("FileType", { pattern = "httui", callback = function() vim.opt_local.tabstop = 2 vim.opt_local.shiftwidth = 2 vim.opt_local.expandtab = true vim.opt_local.commentstring = "# %s" end,})Troubleshooting
Section titled “Troubleshooting”:LspInfo says httui_lsp not attached
Section titled “:LspInfo says httui_lsp not attached”Check:
:LspLogCommon causes: httui-lsp not on PATH, vault root not detected
(provide explicit root_dir).
No highlight inside markdown fences
Section titled “No highlight inside markdown fences”Ensure both parsers installed:
:TSInstall httui markdown markdown_inlineAnd :TSPlayground to confirm httui shows up under http/db-*
fences.
LSP starts but no completions
Section titled “LSP starts but no completions”Likely env config missing. Add to your setup:
settings = { httui = { env = "local" } }(Even an empty envs/local.toml makes the LSP happy if local is
referenced.)
Related
Section titled “Related”- LSP capabilities — what the server gives
- Tree-sitter — node types + queries
- VS Code setup — sibling editor