xynovim

A personal Neovim configuration for Rust, built on LazyVim and inspired by JetBrains' tools. Instant diagnostics, a debugger and test UI, a git safety net, and a test suite you can run yourself.

  • CI workflow
  • Neovim 0.12
  • license Apache-2.0
  • tests 906 passing
  • Two diagnostic tiers: rust-analyzer while you type, clippy about half a second later.
  • Every save is a git ref you can restore, and the AI agent runs inside a sandbox.
  • 906 passing checks across 32 spec files, one command to run them.
Install
git clone https://github.com/xynorash/xynovim ~/.config/nvim   # or ln -s <checkout> ~/.config/nvim
~/.config/nvim/scripts/bootstrap.sh
xynovim editing the netwatch demo crate: Island Dark theme, inlay hints, sticky scope from treesitter-context, statusline with git branch, server state and clippy state
The real config on the demo crate: Island Dark, inlay hints, the sticky scope, the statusline with git branch, server state and clippy state.

What you get

Why xynovim

Built on LazyVim, developed on Linux (Arch) and also run in CI on Windows and macOS (see Platforms), with the Island Dark colour scheme generated from my own colour-scheme export. Everything on this page was recorded from the real config running on the small demo crate: nothing is mocked up.

  • Two diagnostic tiers: rust-analyzer answers while you type, clippy follows about half a second later, on every keystroke and before any save.

  • A debugger and a test runner that look like the ones in an IDE: breakpoints with Rust-aware variable views, a test summary tree, coverage in the gutter.

  • A safety net: every save is snapshotted as a git ref (a “Local History”), and the AI agent runs inside a sandbox.

  • Treesitter everywhere: sticky scope, text objects, SQL injected into sqlx strings, a live syntax-tree view.

  • Tested: 906 passing checks across 32 spec files, one per feature area, runnable with one command after a clone (below).

Feature tour

A tour, from the real config

Each recording plays when it scrolls into view (and never with reduced motion enabled); click a screenshot for the full-size image.

01 diagnostics

Two-tier diagnostics

rust-analyzer’s own diagnostics appear as you type (type errors in about 0.01 to 0.15 s). bacon-ls runs clippy against a hardlinked shadow of your workspace on every buffer change (about 0.56 s median), so lints show up before you save. Each message shows its first line plus the source; the full text is one <leader>cd away.

  • <leader>cd
Recording: typing a type error, then a clippy lint, then the full message in a float. MP4
A type error shown inline the moment it is typed
rust-analyzer, while typing
Diagnostic float with the full clippy message and its help text
the full message, with its suggestion
02 treesitter

Treesitter, visibly

Treesitter drives the highlighting, the sticky scope at the top of the window (the for / match / arm headers you have scrolled past stay pinned), the text objects and the sqlx SQL injection. Two built-in views make it concrete: :Inspect and :InspectTree.

vaf selects a whole function through the treesitter text objects.

  • :Inspect
  • :InspectTree
  • vaf
Recording: the sticky scope, :Inspect, :InspectTree and the vaf text object. MP4
:InspectTree split with the syntax tree following the cursor
:InspectTree: the live syntax tree
vaf selecting the function parse_ports with its doc comment in visual mode
vaf: the text object
treesitter-context pinning the enclosing for, match and arm headers at the top of the window
the sticky scope
03 refactoring

Refactoring and rust-analyzer commands

Every rust-analyzer command rustaceanvim offers has a key under <leader>r, discoverable through which-key: extract variable / function / constant / module, inline, structural search and replace, semantic join lines, move item, expand macro, view HIR / MIR, explain error code, workspace symbol including dependencies, go to super method, and more.

  • <leader>rv
  • <leader>rf
  • <leader>rc
  • <leader>ri
  • <leader>rs
Recording: the <leader>r menu and a code action lookup on a selection. MP4
which-key popup listing the leader r group of rust-analyzer commands
which-key lists the <leader>r group
A selection in visual mode with a notification reading No code actions available
no code action is offered for this selection
04 tests

Tests and coverage

neotest with the rustaceanvim adapter and cargo-nextest: a summary tree with per-test results, and line coverage from cargo-llvm-cov shown in the gutter.

  • <leader>ts
  • <leader>tt
  • <leader>tr
  • <leader>tc
  • <leader>tg
Recording: running tests from the summary tree and toggling the coverage signs. MP4
neotest summary tree: 5 tests, 3 passed, a tick per test
the summary tree
Coverage bars in the gutter next to the covered lines of parse_ports
coverage in the gutter
05 debugging

Debugging

nvim-dap with codelldb, a dap-ui layout sized for Rust’s long type names, and lldb’s Rust formatters loaded automatically (a String shows as text and a struct as {host:"127.0.0.1", ...}, not as raw memory). <leader>db sets a breakpoint, <leader>dR lists every debuggable target of the workspace, and a panic stops at the panicking frame.

  • <leader>db
  • <leader>dc
  • <leader>dr
  • <leader>dR
  • <leader>du
Recording: setting a breakpoint, launching and inspecting variables. MP4
dap-ui stopped at a breakpoint: locals, stack, console and inline values
stopped at a breakpoint
Picker listing the debuggable targets of the workspace
every debuggable target
06 features and target

One feature set for both tiers: :RustContext

Cargo features and the build target are chosen per project and applied to both rust-analyzer and bacon-ls, so the two tiers never disagree. In the demo ssr and csr are mutually exclusive: with all features on, both tiers report the conflict; choosing only ssr makes it go away in both.

The choice is stored per workspace and survives restarts. :RustTargets lists every bin / example / test / bench with run, test, build, profile and flamegraph actions; :RustTools covers cargo-deny, audit, machete, bloat and build timings.

  • :RustContext
  • :RustTargets
  • :RustTools
  • <leader>rF
  • <leader>rX
Recording: choosing features and a target, and the conflict going away. MP4
Feature picker listing all features, default only, no-default, csr, json and ssr
choose features (Tab multi-selects)
Target picker: host default, wasm32, x86_64 linux
choose the target
The csr side greyed out as inactive; the statusline is back to clippy ok
resolved
07 git

Git, and a safety net

lazygit (with delta), diffview for diffs, merge conflicts and file history, mergiraf as a syntax-aware merge driver, and Local History: every save (manual or auto-save, throttled) also writes the whole worktree, untracked files included, as a commit under refs/lochist/ using a private index. Deleted files and git reset --hard become recoverable without touching your real index, stash or branches.

:LocalHistory browses and diffs, :LocalHistoryRestore restores, :LocalHistoryPrune cleans up.

  • <leader>gg
  • <leader>gv
  • <leader>gH
  • :LocalHistory
Recording: lazygit, diffview and the local history picker. MP4
Local history picker listing the snapshots of src/lib.rs
local history
diffview file panel and a side-by-side diff
diffview
08 theme

Island Dark

The colour scheme is generated from my own colour-scheme export, which is not distributed (the generated palette is lua/island/palette.lua), by tools/icls2nvim.py, which converts a scheme file you supply yourself: colours, italics, underlines and the org.rust.* entries that colour structs, enums, macros and lifetimes. Contrast was checked against WCAG targets and lifted where the export was too dim. Floats and the completion menu stay solid on a transparent editor (<leader>uO toggles the editor background).

  • background
    #1e1f22
  • panel
    #2b2d30
  • text
    #bcbec4
  • muted
    #9da0a8
  • blue
    #56a8f5
  • green
    #6aab73
  • orange
    #cf8e6d
  • purple
    #c77dbb
  • yellow
    #f2c55c
  • red
    #f75464
Recording: completion with documentation, hover and the picker in Island Dark. MP4
snacks file picker in Island Dark
picker
blink.cmp menu next to a documentation window
completion with documentation
09 macros and dependencies

Macros and dependencies

Adding a crate used to leave its macros and features half used: no completion inside #[serde(, no use for a crate that is not a dependency yet, a missing derive feature that nothing pointed at, a stale cannot find crate error after cargo add. Everything runs in nvim on top of rust-analyzer, cargo and treesitter; no extra language server.

Attribute completion is data driven: one JSON file per crate in data/macro_attrs/ of the xyno-macros.nvim plugin (serde, clap, thiserror, tokio, strum, derive_more, sqlx, utoipa, schemars, bon), and a project can add its own in .xynovim/macro_attrs/.

add a crate

Adding a crate that is no dependency yet

uuid::Uuid::new_v4() without uuid in Cargo.toml: the code action offers “Add crate uuid”, the picker lists the crates.io results and the features of the chosen release (here v4 toggled on), the target package is asked, then cargo add runs and the error goes away without waiting. Typing Uuid afterwards asks to import it.

  • <leader>rA
  • :CrateAdd
  • :CrateFeatures
  • <leader>rI
Recording: the unknown crate uuid, the code action, the feature picker and the import. MP4
The unknown crate uuid in a path, with the error
the hint on the unknown crate
crates.io search results for uuid
crates.io search
Cargo.toml with the new uuid dependency
the new dependency
attributes and derives

The missing feature, derive and attribute completion

serde without its derive feature gives cannot find derive macro Serialize; <leader>rG enables the feature in Cargo.toml. #[derive(Des completes derive names with docs and adds the use on accept; #[serde( and #[arg( offer keys with their docs, and rename_all = " offers its values.

  • <leader>rG
  • #[serde(
  • #[arg(
  • #[derive(
Recording: the missing derive feature, enabling it, and attribute completion. MP4
Error: cannot find derive macro Serialize in this scope
derive macro not found
serde attribute keys offered with their documentation
serde keys
rename_all values offered inside the string
rename_all values
imports and macros

Ranked imports, macro expansion and signature help

Error exists in std, std::io, std::fmt and clap: <leader>rI ranks them with the reasons; the pick is remembered, so the next file offers it as the single import. <leader>rx shows the expansion of a derive, gi lists what it generated, and <C-k> shows the matcher arms of a macro_rules! call (the arm that fits the arguments typed so far is highlighted).

  • <leader>rI
  • <leader>rO
  • <leader>rx
  • <C-k>
Recording: ranked Error imports, the macro expansion and the signature help. MP4
The remembered choice offered in another file
the choice, remembered
Macro expansion of derive(Parser) in a read-only split
macro expansion
Signature help on a macro_rules call with the matching arm highlighted
signature help on a macro_rules call
10 new projects

New projects

Start an egui app, a binary, a library or a workspace from the dashboard or a command, with the prompts, the name rules and the failure cleanup done for you.

egui

New egui project

The dashboard has a New egui Project entry (e) and there is the command :EguiNew [name]. Both follow the steps of emilk/eframe_template against the current template: the ZIP of its main branch is downloaded every time (never a copy kept in this config) and personalised, so a new egui or eframe release of the template is picked up without touching the config.

It asks for the project name, author name and e-mail (prefilled from git config) and the parent directory; the template’s toolchain pin is not copied, so your own Rust is used.

  • :EguiNew
  • dashboard e
Recording: the dashboard entry, the prompts and the created project. MP4
The dashboard with the New egui Project entry
the dashboard entry
Author name prefilled, with crate name weather_panel shown
prompts, prefilled from git config
src/main.rs using weather_panel::TemplateApp
the personalised project
binary, library, workspace

New Rust binary, library and workspace

Three entries on the dashboard, New Rust Binary (b), New Rust Library (i) and New Rust Workspace (w), and the commands :RustNewBin, :RustNewLib, :RustNewWorkspace and :RustNewMember.

A binary or library is cargo new --vcs git in a chosen parent directory. A workspace has no one-step cargo command, so it is built here: a root Cargo.toml with members = ["crates/*"], [workspace.package] and an empty [workspace.dependencies], a first member that inherits version and edition, and git init -b main. :RustNewMember adds a member to the workspace of the current buffer.

  • :RustNewBin
  • :RustNewLib
  • :RustNewWorkspace
  • :RustNewMember
Recording: the workspace flow, its generated tree and manifests, then a binary. MP4
The dashboard with the three Rust entries and New egui Project
the dashboard entries
Root Cargo.toml with workspace, resolver and workspace.package
the root manifest
11 agent

The AI agent, sandboxed

99 with the Claude Code provider is wired in (<leader>9), and its claude --dangerously-skip-permissions runs inside bubblewrap, which exists only on Linux, so the agent only runs where a sandbox exists (Linux with bwrap); without one, 99 refuses to start a request unless you opt out explicitly (vim.g.xynovim_99_sandbox = false, or vim.g.xynovim_99_allow_unsandboxed = true when there is no sandbox backend), and every unsandboxed request warns. Where bwrap works: the filesystem is read-only except the project and Claude’s own state, credentials and agent sockets are hidden, .git/hooks, .git/config and Claude’s settings are locked read-only, the environment is scrubbed of tokens, and every request is preceded by a Local History snapshot with auto-save paused. It is a seatbelt, not a jail: the network stays open (details in docs/DETAILS.md). There are no screenshots: the sandbox has no UI, and a real request needs an account.

Use the parts on their own

Plugins

These are the original parts of my config that I extracted into standalone plugins, so anyone can use them without the rest of xynovim. There are nine, all public, tagged v0.1.0 with a release on GitHub (xyno-sandbox is at v0.1.1). The plugins are MIT licensed and install with lazy.nvim; xynovim itself stays Apache-2.0. Linux is the tested platform, and each card says what is and is not verified elsewhere. The plugins page has the details, the install order and the questions I expect.

Which plugin needs which. In the Rust toolkit each block stands on what it needs: xyno-rust.nvim is the base, xyno-new.nvim and xyno-imports.nvim need only it, and xyno-crates.nvim and xyno-macros.nvim need both xyno-rust.nvim and xyno-imports.nvim.

Standalone

  • xyno-history.nvim

    Local History for Neovim: every throttled save is snapshotted into private git refs, so deletions, resets and bad edits can be recovered.

    Needs Neovim 0.12+, git; no other plugin

    Linux tested; Windows and macOS not verified

    { "xynorash/xyno-history.nvim", event = "VeryLazy", opts = {} }
  • xyno-sandbox.nvim

    Runs a command-line coding agent inside a bubblewrap sandbox and refuses to start it without one. Linux only.

    Needs Neovim 0.12+, Linux with bubblewrap (bwrap); no other plugin

    Linux only

    {
      "xynorash/xyno-sandbox.nvim",
      cmd = { "XynoSandboxStatus", "XynoSandboxRun" },
      opts = {},
    }
  • xyno-clipboard.nvim

    A clipboard provider for sessions whose yanks must reach another machine: tmux, SSH and herdr panes get OSC 52 copy, with no change anywhere else.

    Needs Neovim 0.12+, Linux; wl-copy and wl-paste optional

    Linux only

    {
      "xynorash/xyno-clipboard.nvim",
      lazy = false, -- the provider should exist before the first yank
      opts = {},
    }
  • xyno-guard.nvim

    Keeps auto-save away from files it must never write: dependency and standard-library sources, files changed on disk, and similar. Works with any auto-save plugin.

    Needs Neovim 0.12+; an auto-save plugin with a condition function (I use okuuva/auto-save.nvim)

    Linux tested; Windows and macOS not verified

    {
      "okuuva/auto-save.nvim",
      event = { "InsertLeave", "TextChanged", "TextChangedI" },
      dependencies = { "xynorash/xyno-guard.nvim" },
      opts = function()
        require("xyno_guard").setup()
        return { condition = require("xyno_guard").can_save }
      end,
    }

Rust toolkit

  • xyno-rust.nvim

    Rust project plumbing for Neovim: a per-project Cargo context, a targets picker, an HTTP route picker, navigation helpers, language-server restart handling and a statusline readiness indicator.

    Needs Neovim 0.12+, cargo, snacks.nvim for the pickers; rust-analyzer for the navigation helpers

    Linux tested; Windows and macOS not verified

    {
      "xynorash/xyno-rust.nvim",
      dependencies = { "folke/snacks.nvim" }, -- pickers and terminals
      ft = "rust",
      cmd = { "RustContext", "RustTargets", "RustTools", "RustRoutes", "RustNew", "RustRestart", "ActJob" },
      opts = {},
    }
  • xyno-new.nvim

    New Rust projects from inside Neovim: a binary, a library, a workspace or an egui app, each behind a few guarded prompts.

    Needs xyno-rust.nvim, Neovim 0.12+, cargo; git optional; curl and unzip for :EguiNew

    Linux tested; Windows and macOS not verified

    {
      "xynorash/xyno-new.nvim",
      dependencies = { "xynorash/xyno-rust.nvim" },
      cmd = { "RustNewBin", "RustNewLib", "RustNewWorkspace", "RustNewMember", "EguiNew" },
      opts = {},
    }
  • xyno-imports.nvim

    Imports without the menu for Rust: auto-import of unresolved names, ranked disambiguation with a per-project memory, and organize imports, on top of rust-analyzer code actions.

    Needs xyno-rust.nvim, Neovim 0.12+, cargo, rust-analyzer, tree-sitter rust parser

    Linux tested; Windows and macOS not verified

    {
      "xynorash/xyno-imports.nvim",
      dependencies = { "xynorash/xyno-rust.nvim" },
      ft = "rust",
      cmd = { "ImportName", "ImportForget", "ImportOrganize" },
      opts = {},
    }
  • xyno-crates.nvim

    Cargo dependencies from inside Neovim: search crates.io, add crates with their features, enable a missing feature from a code action, and import from crates that are not dependencies yet.

    Needs xyno-rust.nvim, xyno-imports.nvim, snacks.nvim, Neovim 0.12+, cargo, network for crates.io

    Linux tested; Windows and macOS not verified

    {
      "xynorash/xyno-crates.nvim",
      dependencies = {
        "xynorash/xyno-rust.nvim",
        "xynorash/xyno-imports.nvim",
        "folke/snacks.nvim", -- pickers
      },
      ft = "rust",
      cmd = { "CrateAdd", "CrateFeatures" },
      opts = {},
    }
  • xyno-macros.nvim

    Rust macro help in Neovim: completion inside helper attributes and derives (serde, clap, tokio, sqlx and more), macro_rules! signature help, :MacroExpand and proc-macro status.

    Needs xyno-rust.nvim, xyno-imports.nvim, Neovim 0.12+, cargo, rust-analyzer; blink.cmp optional

    Linux tested; Windows and macOS not verified

    {
      "xynorash/xyno-macros.nvim",
      dependencies = { "xynorash/xyno-rust.nvim", "xynorash/xyno-imports.nvim" },
      ft = "rust",
      cmd = { "MacroExpand", "MacroFormatFix", "MacroSignature", "ProcMacroStatus", "MacroAttrs" },
      opts = {},
    }

All nine plugins, the full install spec and the FAQ

Run them yourself

Tested

The config ships with an automated suite. Each spec file runs in its own headless Neovim with the full config and a hard timeout, so a hanging test cannot stall the rest.

  • 32spec files
  • 906checks passing
  • 35skipped with a stated reason
  • 0failing
scripts/test.sh                  # everything (or: make test)
scripts/test.sh routes smoke     # only spec files whose path contains one of the words
scripts/test.sh --list           # the spec files, nothing run
scripts/test.sh --coverage       # also a per-file line-coverage report
  • Nothing of yours is touched: the specs run against a temp config / state / cache. Missing tools (rust-analyzer, tmux, bubblewrap, lazygit, ...) make their specs skip with a message, never fail.
  • One spec per feature area: tests/COVERAGE.md maps every feature to the spec that tests it and lists what has no test and why.
  • CI: the ci workflow bootstraps the plugins on their locked commits, runs a startup smoke test and the whole suite on a clean Ubuntu machine for every push.
  • How the harness works and how to write a spec: docs/TESTING.md.
The test runner finishing four spec files: 129 passed, 0 failed
The runner finishing four spec files: 129 passed, 0 failed.

Get it

Install

Two commands. scripts/bootstrap.sh checks the prerequisites it needs and prints what is missing; :checkhealth xynovim checks the rest later, with what each one is for.

git clone https://github.com/xynorash/xynovim ~/.config/nvim   # or ln -s <checkout> ~/.config/nvim
~/.config/nvim/scripts/bootstrap.sh

A plain nvim --headless '+Lazy! restore' +qa on an empty plugin directory makes lazy.nvim install in several rounds and rewrite lazy-lock.json after every one, so the pins of the plugins found later are dropped and those land on their newest commit. The script runs Lazy! install, puts the original lockfile back, runs Lazy! restore and fails if lazy-lock.json differs afterwards; CI runs it too.

Full prerequisites and details in the README

Prerequisites, in short

  • To bring the config up: nvim 0.12, git, curl, tar, unzip, gzip, gcc, the tree-sitter CLI, node and npm.
  • For the Rust workflow: cargo, rustup (with the stable toolchain, its clippy and llvm-tools components) and rust-analyzer on PATH.
  • Installed by Mason: bacon-ls, codelldb, taplo, marksman, lua-language-server, stylua and the other language servers and tools.
  • Optional, each one only costs its feature: mold + clang, cargo-nextest, cargo-deny, cargo-expand, lazygit, delta, bwrap (the 99 sandbox, Linux only; without it 99 refuses to run).

Platforms

The shell scripts are bash conveniences for Linux and macOS, with PowerShell counterparts for Windows (scripts/bootstrap.ps1). The config itself is Lua and is meant to run wherever Neovim 0.12 runs with the prerequisites. What CI shows, and no more:

  • Linux: developed on (Arch), fully tested. Ubuntu ci run 39695896272: 1749 passed, 0 failed, 76 skipped.
  • Windows: the plugin restore from the lockfile, a silent headless start and the specs that are not Linux-only pass. platforms run 39673715062: 1077 passed, 0 failed, 87 skipped; 10 of the 38 spec files are skipped whole there and not demonstrated. Green in 5 of the 6 runs from 39660597368 on (the one red run was a spec path assertion, fixed afterwards).
  • macOS: not reliably green. Neovim starts and most specs pass, but the job did not pass in 4 of the 5 runs that finished from 39660597368 on (green once: run 39663956677, 1431 passed, 0 failed, 73 skipped).
  • Linux only by design: the 99 agent sandbox (bubblewrap; without it 99 refuses to run), the remote clipboard, the tmux-based and bash-stub test tooling (scripts/test.sh) and the mold linker setup.
  • Not demonstrated on Windows or macOS: Local History, startup options, new Rust and egui project creation, live rust-analyzer flows on Windows, and debugging through codelldb. docs/KNOWN_ISSUES.md has the list.

Reference

Keys and commands

<leader> is Space; which-key shows the menu of every prefix.

Keys you will use

KeysWhat
<leader>r…rust-analyzer: rv extract variable, rf function, rc constant, ri inline, rs structural search / replace, rm expand macro, rh / rH HIR / MIR, re explain error code, rw / rW workspace symbol (+ dependencies), rF features / target, rX targets, rZ cargo tools; dependencies and macros: rA add crate, rG enable the missing feature, rI import name (ranked), rO organize imports, rx expand macro (lens); <A-j> / <A-k> move item
<leader>d…debugger: db breakpoint, dc continue, dr / dR debuggables (file / workspace), du dap-ui
<leader>t…tests: tt file, tr nearest, tT all, ts summary, to output, tw watch, tD doc-tests, tc run coverage, tg toggle coverage signs
<leader>g…git: gg lazygit, gv diffview, gV branch vs origin, gF file history, gH local history
<leader>c…cd diagnostic float, cj split / join (treesj), cI / cO incoming / outgoing call trees, cn doc comment stub
<leader>9…the 99 agent: 9v vibe, 9s search, 9o last interaction, 9x stop
<leader>H, <C-e>, <M-1..4>harpoon: add file, menu, jump
<leader>uO, uB, uutoggle editor transparency, colour-blind diagnostics, undotree
dashboard b, i, w, enew Rust binary, library, workspace, egui project

Commands

  • :RustContext
  • :RustTargets
  • :RustTools
  • :RustNew
  • :RustNewBin
  • :RustNewLib
  • :RustNewWorkspace
  • :RustNewMember
  • :EguiNew
  • :RustRoutes
  • :RustRestart
  • :CrateAdd
  • :CrateFeatures
  • :ImportName
  • :ImportForget
  • :ImportOrganize
  • :MacroAttrs
  • :MacroExpand
  • :MacroSignature
  • :MacroFormatFix
  • :ProcMacroStatus
  • :ActJob
  • :LocalHistory
  • :LocalHistoryRestore
  • :LocalHistoryPrune
  • :ColorblindDiagnostics
  • :checkhealth xynovim

Plugin management is stock LazyVim: :Lazy sync updates (the update checker is off), :LazyExtras toggles extras, :Mason manages language servers.

Honest edges

Known limitations

  • Neovim 0.12; developed on Linux. Windows is exercised in CI and macOS is not reliably green (Platforms). The previous from-scratch Windows config lives on the windows-legacy branch.
  • The agent sandbox is a seatbelt, not a jail. The network stays open, and no real request to the agent was driven in the test suite.
  • The macros and dependencies work is tested headless. The suite uses real cargo and rust-analyzer, but the pickers and key presses were not driven in a real terminal; the unknown-crate hint is deliberately conservative (a miss is better than a false hint), and a “(guess)” import can miss.
  • Two Neovim instances on the same workspace share bacon-ls’s shadow, so one’s unsaved text can show up as clippy errors in the other (upstream; open one Neovim per workspace). A multi-file rename is undone per buffer: use <leader>gH local history to revert it.

The complete list, with what was decided and why: docs/KNOWN_ISSUES.md.