Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TL;DR: Synapse ships an LSP companion (syn lsp) so any editor that speaks LSP gets entity-aware completion, hover, go-to- definition and dangling-reference diagnostics on every .md file in a workspace. Build with the lsp feature, point your editor at the syn lsp binary, done.


1. Build with the LSP feature

cargo install synapse --features "mcp lsp"
# or, from this repo:
cargo build --release --features "mcp lsp"
# binary lands at target/release/syn

Confirm the subcommand:

syn lsp --help
# Run the LSP companion on stdio (slug/type/tag completions, hover,
# go-to-definition, dangling-ref diagnostics): SYN-130.

The server reads .synapse/index.db from the workspace root; runs syn reindex once if completions look stale.

2. What you get

  • Completion in .md files:
    • Inside [[<cursor>: every workspace entity slug.
    • After type: <cursor>: the six entity types (project, person, entity, api, task, note).
    • Inside tags: [<cursor>: every distinct tag in the workspace.
  • Hover over [[slug]]: entity title + first paragraph of the body.
  • Go-to-definition on [[slug]]: jumps to the entity’s markdown file.
  • Diagnostics: [[slug]] with no matching entity is flagged as a Warning, source: "synapse".

3. Helix

~/.config/helix/languages.toml:

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

[[language]]
name             = "markdown"
language-servers = ["syn-lsp"]
roots            = [".synapse"]

Helix auto-discovers the workspace root by walking up to .synapse/.

4. Neovim (nvim-lspconfig)

init.lua:

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

if not configs.syn_lsp then
  configs.syn_lsp = {
    default_config = {
      cmd       = { "syn", "lsp" },
      filetypes = { "markdown" },
      root_dir  = lspconfig.util.root_pattern(".synapse"),
      settings  = {},
    },
  }
end

lspconfig.syn_lsp.setup({})

5. VS Code (and Cursor)

VS Code does not auto-discover non-marketplace LSPs, so it needs the thinnest possible extension. Drop this into a folder and code --install-extension .:

// package.json
{
  "name": "synapse",
  "version": "0.0.1",
  "engines": { "vscode": "^1.94.0" },
  "activationEvents": ["onLanguage:markdown"],
  "main": "./extension.js",
  "contributes": {
    "languages": [{ "id": "markdown", "extensions": [".md"] }]
  }
}
// extension.js
const { LanguageClient, TransportKind } = require("vscode-languageclient/node");
let client;
function activate() {
  client = new LanguageClient(
    "synLsp",
    "Synapse LSP",
    {
      command: "syn",
      args: ["lsp"],
      transport: TransportKind.stdio,
    },
    {
      documentSelector: [{ scheme: "file", language: "markdown" }],
      workspaceFolder: undefined,
    },
  );
  client.start();
}
function deactivate() { return client && client.stop(); }
module.exports = { activate, deactivate };

Cursor inherits the same extension API; the config above works identically.

6. Zed

~/.config/zed/settings.json:

{
  "lsp": {
    "syn-lsp": {
      "binary": { "path": "syn", "arguments": ["lsp"] }
    }
  },
  "languages": {
    "Markdown": { "language_servers": ["syn-lsp"] }
  }
}

7. Troubleshooting

No completions. Run syn reindex in the workspace. The LSP server reads from .synapse/index.db; if it’s missing or empty nothing comes back. Also verify your editor is actually launching the server: most editors expose an “LSP log” command that shows the stdio handshake.

[[slug]] warning is wrong. The diagnostic source is synapse and it fires when no entity with that slug exists in the index. The fix is either (a) create the entity (syn project add foo, etc.) or (b) update the link.

Hover shows nothing. Hover is only implemented for [[slug]] references. Hovering on free text returns nothing by design.

Go-to-definition opens the wrong file. Each slug must be unique across the workspace: the index returns the first match. If you have two entities with the same slug in different types, rename one.

8. References