CoHDL
  1. Docs
  2. Editor support

Editor support

CoHDL ships one language server, cohdl lsp, built into the compiler binary. VS Code gets a packaged extension; every other editor with a Language Server Protocol client gets the same server with a few lines of configuration.

Status The language server ships inside the compiler — install CoHDL and cohdl lsp is on your machine. The VS Code extension is published to the Visual Studio Marketplace as conol.cohdl.

The language server

cohdl lsp speaks the Language Server Protocol — the JSON-RPC protocol editors use to talk to compilers — over stdio. It is a thin frontend over the exact same pipeline cohdl check runs: the same dependency resolution, the same checks, the same diagnostics. Nothing is re-implemented for the editor, so the editor and the CLI can never disagree about whether a design is correct.

  • Diagnostics as you type. On open, change and save, the server re-checks the file's containing project: it walks up to cohdl.toml, resolves and lock-verifies every direct dependency, and falls back to single-file-plus-std when there is no manifest. The published diagnostics are field-for-field the ones cohdl check --json reports — an equivalence test suite holds the two to that. Unsaved edits count: buffer contents override the on-disk file. A project that fails to load — a bad manifest, a broken lock — is reported as a visible editor message, never as a deceptively clean file.
  • Hover. Over an impl block: the resolved pin-to-requirement mappings. Over a pin declaration or use site: its connection obligation and role. Over a unit literal: its unit type and the allowed prefixes. Over a part: its MPN, manufacturer, resolved footprint and reference documents. Over pads, mount holes, use imports, place statements and physics attributes: the resolved facts of each.
  • Go to definition. A device, trait, function, part, footprint or pad name at any reference site jumps to its declaration — including declarations that live in a dependency's source. Instance and pin references resolve the same way.
  • Find references. On a trait or device name: every impl involving it, across the project and its loaded dependencies.

Beyond those four capabilities the server also offers keyword completion — the contextual grammar words and attribute names. Every request re-runs the full check from scratch; there is no incremental compilation, which is acceptable at the scale of current designs. Code actions, rename, semantic tokens and workspace symbols are deliberately out of scope. The server runs on POSIX hosts.

VS Code

The VS Code extension is thin packaging over the server, and that is the point: it adds no diagnostics or compiler behavior of its own. It registers the .cohdl file type, ships a hand-authored TextMate grammar for syntax color — the one thing the LSP protocol has no verb for — and spawns cohdl lsp through vscode-languageclient when the first CoHDL file opens. A grammar-coverage test in CI asserts that every keyword and literal class gets a real scope rather than falling through to unstyled text.

There is exactly one setting: cohdl.path, the path to the cohdl binary. It defaults to cohdl, resolved via PATH; point it at a workspace build if needed:

{
  "cohdl.path": "${workspaceFolder}/target/debug/cohdl"
}

If the binary cannot be started, the extension shows a visible error notification — never a silently blank Problems panel.

The extension is on the Visual Studio Marketplace as conol.cohdl — install it from the extensions view, or grab the plain .vsix attached to each vscode-v* release. It is only a client for cohdl lsp, so it needs the compiler installed; if cohdl is not on VS Code's PATH, point the cohdl.path setting at the binary.

Any LSP editor

Editors other than VS Code do not need a package at all — a launch configuration is enough. Point any LSP client at cohdl lsp, associate the cohdl file type with the .cohdl extension, and use cohdl.toml as the project-root marker. For a generic LSP client, the entire configuration is:

{
  "command": ["/path/to/cohdl", "lsp"],
  "languageId": "cohdl",
  "filetypes": ["cohdl"],
  "rootPatterns": ["cohdl.toml"]
}

With Neovim's built-in LSP client:

init.lua Neovim
vim.api.nvim_create_autocmd("FileType", {
  pattern = "cohdl",
  callback = function()
    vim.lsp.start({
      name = "cohdl",
      cmd = { "/path/to/cohdl", "lsp" },
      root_dir = vim.fs.dirname(vim.fs.find({ "cohdl.toml" }, { upward = true })[1]),
    })
  end,
})
vim.filetype.add({ extension = { cohdl = "cohdl" } })

Formatting

CoHDL has exactly one formatter and exactly one canonical form. cohdl fmt rewrites a file or directory into that form, and cohdl fmt --check verifies without writing — the usual CI gate. Because the canonical form is defined by the toolchain rather than by taste, there are no style options to configure and no formatting debates to have.

The language server does not expose formatting over LSP today, so editors run the CLI directly: wire cohdl fmt as your editor's external formatter or as a format-on-save hook.