Editor Setup

Configure the Kōdo Language Server for VSCode, Neovim, Helix, and other editors

Editor Setup

The Kōdo Language Server (kodoc lsp) brings real-time feedback directly into your editor. For AI agents operating through IDE integrations, LSP quality is a critical factor — hover information, diagnostics, and code actions form the tight feedback loop that enables agents to write correct code faster.

VSCode Setup

Download the .vsix file from the latest release and install it:

# Download from GitHub releases
code --install-extension kodo-lang-1.5.1.vsix

The extension provides:

  • Syntax highlighting (keywords, types, contracts, annotations)
  • LSP integration (diagnostics, hover, completions, go-to-definition)
  • Contract-aware hover (shows requires/ensures clauses)
  • Code actions from FixPatch

Option B: Manual Setup

  1. Install the Kōdo compiler — follow the Installation guide.

  2. Ensure kodoc is in your PATH:

    kodoc --version
  3. Open a .ko file — the extension automatically starts the language server.

Settings

SettingDefaultDescription
kodo.serverPathkodocPath to the kodoc binary
kodo.trace.serveroffTrace LSP communication

What You Get

Once the LSP is connected, every .ko file you open benefits from:

  • Red/yellow squiggles on errors and warnings, updated as you type
  • Hover tooltips showing types, contracts, and agent annotations
  • Autocomplete suggestions for functions, structs, enums, and builtins
  • One-click quick fixes for common issues
  • Outline view showing module structure

Available Features

Diagnostics

The LSP reports parse errors and type errors in real time. Errors appear as you type, with source spans mapped to the exact location in your file. When --json-errors is used from the CLI, the same structured error data powers the LSP diagnostics.

Each diagnostic includes:

  • The error code (e.g., E0200 for type errors)
  • A human-readable message with the source span highlighted
  • Severity level (error or warning)

Hover

Hovering over a symbol shows detailed information depending on what you are pointing at:

  • Functions: signature, parameter types, return type, contracts (requires/ensures), and all annotations
  • Parameters: name and declared type (e.g., param count: Int)
  • Variables: name and type, inferred from the initializer if no explicit annotation is present (e.g., let x: Int)

Completions

Context-aware completions are provided for:

  • 31 built-in functions with full signature details (e.g., println, file_read, sqrt)
  • User-defined functions with contract information shown in the detail
  • Struct and enum names defined in the current module
  • Enum variants after typing EnumName:: — shows all variants with their field types
  • String methods and struct field completions

Go to Definition

Jump to the definition of any function, variable, parameter, struct, or enum. Works within the current module. Press F12 or Ctrl+Click / Cmd+Click on an identifier.

Find References

Find all usages of a symbol across the current document. Supports the include_declaration option to also highlight the definition site. Use Shift+F12 in VSCode.

Rename

Rename a symbol and all its references within the document. Press F2 on any identifier to rename it consistently.

Signature Help

When typing inside a function call, parameter hints appear showing the expected argument types. This activates automatically after typing ( or ,.

Document Symbols

The outline view (Ctrl+Shift+O / Cmd+Shift+O) shows all declarations in the module — functions, structs, enums — for quick navigation.

Code Actions (Quick Fixes)

The LSP provides code actions that appear as lightbulb suggestions:

  • Add missing contract — for functions that have no requires or ensures clauses, suggests adding a contract skeleton
  • Add type annotation — for let bindings without an explicit type, suggests adding the inferred type
  • Fix patches from the type checker — machine-applicable fixes for type errors, provided as one-click workspace edits

Agent-First Features

Kōdo’s LSP is designed with AI agents as first-class consumers. Several features surface agent-specific metadata that no other language server provides.

Annotation-Aware Hover

When you hover over a function that has agent annotations, the LSP displays them with their full arguments:

  • @confidence(0.95) — the declared confidence score, not just the annotation name
  • @authored_by(agent: "claude") — the authoring agent with its identifier
  • @reviewed_by(reviewer: "human") — review status

This means an agent (or a human reviewing agent-written code) can see trust metadata without opening the source file.

Structured Diagnostics

All diagnostics emitted by the LSP carry the same structured data available through kodoc check --json-errors. This includes:

  • Error codes that agents can classify and act on
  • Source spans with byte offsets for machine-applicable patches
  • Fix suggestions that map directly to kodoc fix patches

Custom LSP Extensions

The Kōdo LSP exposes two custom request methods beyond the standard protocol:

MethodDescription
/kodo/contractStatusReturns the verification status of all contracts in the current file
/kodo/confidenceReportReturns confidence scores for all functions, mirroring kodoc confidence-report --json

These extensions allow AI agents connected via LSP to query trust and correctness metadata programmatically, without invoking the CLI.

Other Editors

The Kōdo LSP server communicates over stdin/stdout using the standard Language Server Protocol. Any editor with LSP support can connect to it.

Neovim

Kōdo provides a Vim plugin (editors/neovim/) with syntax highlighting, indentation, and filetype detection, plus a tree-sitter grammar (editors/tree-sitter-kodo/) for advanced highlighting.

Neovim 0.11+ (Native LSP)

The simplest setup — no plugins required beyond filetype detection:

vim.filetype.add({ extension = { ko = 'kodo' } })

vim.lsp.config.kodo = {
  cmd = { 'kodoc', 'lsp' },
  filetypes = { 'kodo' },
  root_markers = { '.git' },
}
vim.lsp.enable('kodo')

nvim-lspconfig

local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')

if not configs.kodo then
  configs.kodo = {
    default_config = {
      cmd = { 'kodoc', 'lsp' },
      filetypes = { 'kodo' },
      root_dir = lspconfig.util.root_pattern('.git', '.'),
    },
  }
end

lspconfig.kodo.setup({})

You also need to associate .ko files with the kodo filetype:

vim.filetype.add({ extension = { ko = 'kodo' } })

LazyVim

LazyVim manages LSP servers through Mason. Since Kōdo is not in the Mason registry, you need to call setup() directly. Create lua/plugins/kodo.lua:

return {
  {
    "LazyVim/LazyVim",
    init = function()
      vim.filetype.add({ extension = { ko = "kodo" } })
    end,
  },
  {
    "neovim/nvim-lspconfig",
    dependencies = { "saghen/blink.cmp" },
    opts = function(_, opts)
      local lspconfig = require("lspconfig")
      local configs = require("lspconfig.configs")

      if not configs.kodo then
        configs.kodo = {
          default_config = {
            cmd = { "kodoc", "lsp" },
            filetypes = { "kodo" },
            root_dir = lspconfig.util.root_pattern(".git", "."),
          },
        }
      end

      local capabilities = vim.tbl_deep_extend(
        "force",
        vim.lsp.protocol.make_client_capabilities(),
        require("blink.cmp").get_lsp_capabilities()
      )
      lspconfig.kodo.setup({ capabilities = capabilities })
    end,
  },
}

If your LazyVim uses nvim-cmp instead of blink.cmp, replace the capabilities line with require("cmp_nvim_lsp").default_capabilities().

Tree-sitter (Optional)

For advanced syntax highlighting, add the Kōdo tree-sitter grammar to nvim-treesitter:

local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
parser_config.kodo = {
  install_info = {
    url = "https://github.com/kodo-lang/tree-sitter-kodo",
    files = { "src/parser.c" },
    branch = "main",
  },
  filetype = "kodo",
}

Then run :TSInstall kodo.

Helix

Add the following to your languages.toml:

[[language]]
name = "kodo"
scope = "source.kodo"
file-types = ["ko"]
language-servers = ["kodo-lsp"]
comment-token = "//"

[language-server.kodo-lsp]
command = "kodoc"
args = ["lsp"]

Zed

In your Zed settings, add a custom language server:

{
  "lsp": {
    "kodo": {
      "binary": {
        "path": "kodoc",
        "arguments": ["lsp"]
      }
    }
  }
}

Generic LSP Client

For any other editor or tool, start the server with:

kodoc lsp

The server reads JSON-RPC messages from stdin and writes responses to stdout, following the LSP specification.

Next Steps

  • CLI Reference — full list of kodoc commands and flags
  • CLI Tools — built-in functions for file I/O, math, and process control
  • Agent Traceability@confidence, @authored_by, and compilation certificates