Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

51 Commits

Folders and files

Repository files navigation

nvim

Fast · Minimal · Embedded-first
A modern Neovim configuration for embedded development (C/C++ · Rust · Python), technical writing (LaTeX · Markdown · prose), and AI-assisted coding.

Neovim lazy.nvim leader

🌐 中文文档 · English


Table of Contents


✨ Features

  • Blazing-fast startup — everything is lazy-loaded; the embedded debug stack and AI tools cost zero until you ask for them.
  • Full LSP for four languages — clangd, pyright + ruff, rust-analyzer, lua-language-server: go-to-definition, references, rename, code actions.
  • One-key ARM debug — <leader>dd flashes and debugs Cortex-M targets over OpenOCD + GDB, with automatic MCU detection.
  • Writing toolkit — live Markdown rendering, VimTeX + Synctex forward/inverse search, spell-check and soft wrap for prose.
  • AI, built in but optional — blink.cmp completion and Claude Code in a terminal; both behind explicit toggles, with agent stats (/cost, /status) for free.
  • Git in the gutter — inline hunks, per-hunk stage/reset, buffer diff review, line blame.

📦 Prerequisites

Purpose Tools
Base Neovim ≥ 0.12 · git
C/C++ LSP clangd (auto-installed by Mason); a compile_commands.json for full project semantics — see guide
Embedded debug arm-none-eabi-gdb or gdb-multiarch · openocd · ARM toolchain (gcc-arm-none-eabi)
LaTeX TeX Live (provides latexmk) · zathura + zathura-pdf-poppler for PDF with forward/inverse search

clangd note: if clangd reports 'iostream' file not found on C++ files, see the C/C++ guide.

🚀 Installation

git clone https://github.com/<your-name>/<repo>.git ~/.config/nvim
nvim            # lazy.nvim bootstraps itself, then installs all plugins
:Mason          # first run installs LSP servers (clangd / pyright / ruff)

Plugins update automatically at startup (lazy.nvim checker); run :Lazy for manual management.


⌨️ Keymaps

Leader is Space (shown as ␣), localleader is , (LaTeX).

General & Editing

Key Action
q Enter preview mode — read-only pager, see Preview Mode
Q Record macro (original q, followed by a register name)
Z Clear search highlight
R Replace all search matches — prompts :%s//, type new/g⏎ (all) or new/gc⏎ (confirm each)
S Prefix for quick insert chords — see S-Prefix Chords
viwp / visual p Paste over a word — visual p is remapped to preserve the register, so repeated viwp replaces multiple targets with the same yank
H / L Jump to first / last non-blank character of the line
_ / g_ Jump to top / bottom of the screen
<C-a> Select all
U Redo
gcc / gc Toggle line / range comment
gbc / gb Toggle block comment
<A-e> Autopairs fast-wrap (wrap a word with a delimiter)
ys{text-object}{char} · ds{char} · cs{old}{new} Surround: add / delete / change a pair
visual S Surround the visual selection

Navigation & Jumping

Key Action
s Flash jump — type a label to jump anywhere (normal / visual / operator-pending: ds-style jumps work as motions)
f / F / t / T Native char navigation (flash's char mode disabled)
<C-u> / <C-d> Smooth scroll half page
<C-b> / <C-f> Smooth scroll full page
<C-h/j/k/l> Move between windows
<A-h/j/k/l> Resize windows
␣w{hjkl} Swap window positions
␣e Toggle file tree
<C-i> / ␣th Toggle terminal / horizontal terminal

Preview Mode (q enter, Esc exit)

Key Action
j / k / e / y Scroll one line
J / K Scroll ten lines (count multiplies: 3J = 30)
d / u Scroll half page (smooth)
f / b Scroll full page (smooth)
h / l Scroll horizontally
Esc Exit preview

Absolute line numbers and read-only (edits raise E21). Scroll mappings are mounted only while the mode is active — outside preview every key keeps its native meaning (d = delete, u = undo, y = yank). Preview also auto-exits when leaving the buffer (switching to neo-tree, terminal, or another file).

S-Prefix Chords (Quick insert)

Key Action
SJ / SK Insert blank lines below/above current line
SS Smart line split
SN Split line after cursor

File Tree (neo-tree)

Key Action
/ Fuzzy filter (live) — the way to navigate large directories
f Filter on submit
N / n Open in horizontal / vertical split
zM / zR Collapse / expand all
. / u Set temporary root / navigate up
R / q Refresh / close

LSP (attached per buffer)

Key Action
gd / gr / gy / gI Definition / references / type definition / implementations (Telescope)
K / gl Hover documentation / line diagnostics
␣ds / ␣ws Document / workspace symbols
␣xx All workspace diagnostics
␣rn / ␣ca Rename symbol / code actions

LaTeX (localleader ,)

Key Action
,ll / ,lv Compile (latexmk) / view PDF with forward search
,lt / ,le Table of contents / errors
,lk / ,lc / ,lq / ,lx Stop / clean / log / reload

Debugging (DAP)

Key Action
␣db / ␣dB Toggle / conditional breakpoint
<F5> / <F10> / <F11> / <F12> Continue / step over / step into / step out
␣dr DAP REPL
␣dl / ␣dt Run to cursor / terminate
␣dd / :ArmDebug One-key ARM flash & debug (OpenOCD + GDB + DAP UI)
␣td Toggle embedded features (off ⇒ ␣dd/:ArmDebug refuse; software debugging unaffected)

Debug sessions open the DAP UI panel (variables · scopes · call stack · breakpoints) automatically; virtual text shows variable values inline. Adapters: codelldb (C/C++/Rust), debugpy (Python), arm_gdb (embedded).

Git (gitsigns)

Key Action
]c / [c Next / previous hunk
␣hs / ␣hr Stage / reset current hunk
␣hp Preview hunk
␣hd Review: diff entire buffer vs index
␣hb Blame current line

Toggles

Key Action
␣tc Toggle completion (blink.cmp)
␣ac / ␣aC Toggle Claude Code terminal / resume latest session

🗂️ File Structure

~/.config/nvim
├── init.lua                     # entry: lazy → keymaps → options → diagnostics → preview → lsp
├── PERFORMANCE.md               # performance assessment report
├── lua/
│   ├── config/
│   │   ├── lazy.lua             # lazy.nvim bootstrap, leader keys
│   │   ├── keymaps.lua          # global keymaps + S-prefix chords + embedded switch
│   │   ├── options.lua          # editor options, autocmds
│   │   ├── diagnostics.lua      # one-sign-per-line (worst severity) handler
│   │   ├── preview.lua          # preview mode (read-only pager)
│   │   └── lsp.lua              # LSP keymaps (telescope + floats)
│   └── plugins/                 # one spec file per domain
│       ├── lsp.lua              # ALL LSP configs + conform formatters (single file by design)
│       ├── dap.lua              # DAP: generic debugging + ARM flash & debug (lazy)
│       ├── latex.lua · markdown.lua · blink.lua · claude.lua · flash.lua · gitsigns.lua
│       └── …                    # UI / editing plugins
└── after/ftplugin/              # per-filetype settings
    ├── tex.lua                  # spell, soft wrap, conceallevel=2
    ├── markdown.lua · text.lua  # spell, soft wrap

🧩 Plugins

Plugin Purpose Config
lazy.nvim Plugin manager lua/config/lazy.lua
vscode.nvim Dark colorscheme colorscheme.lua
telescope.nvim (master) Fuzzy finder & LSP pickers telescope.lua
neo-tree.nvim File explorer neo-tree.lua
toggleterm.nvim Terminal toggleterm.lua
smart-splits.nvim Window movement & resizing smart-splits.lua
flash.nvim Label jump (s) flash.lua
nvim-surround Surround pairs nvim-surround.lua
Comment.nvim Comments comment.lua
nvim-autopairs Auto pairs & fast-wrap autopairs.lua
gitsigns.nvim Git hunks in the gutter gitsigns.lua
mason.nvim LSP server installer mason.lua
nvim-lspconfig LSP setup (clangd / pyright / ruff / lua_ls) lsp.lua
conform.nvim Format on save lsp.lua
rustaceanvim Rust LSP + clippy on save rust.lua
nvim-treesitter (main) Parser installs (12 parsers); highlighting via nvim core treesitter.lua
rainbow-delimiters.nvim Rainbow brackets rainbow.lua
indent-blankline.nvim Indent guides indent-blankline.lua
neoscroll.nvim Smooth scrolling neoscroll.lua
nvim-dap + dap-ui + virtual-text Debugging: codelldb / debugpy / ARM flash & debug dap.lua
render-markdown.nvim Live Markdown rendering markdown.lua
vimtex (v2.18) LaTeX compile / view / Synctex latex.lua
blink.cmp (v1) Completion (LSP / path / buffer) blink.lua
claude-code.nvim Claude Code in a terminal claude.lua

📖 Guides

C/C++ & clangd

clangd provides semantic analysis only if it knows your build flags — that's what compile_commands.json is for. Without it, cross-file symbols fail with cascading errors (the "errors everywhere" symptom).

Generate it once per project:

Build system How
CMake cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (the file is produced at configure time — no compile needed; symlink build/compile_commands.json to the project root if needed)
Makefile / anything bear -- make (sudo apt install bear)
Quick fallback Put a compile_flags.txt in the project root (one flag per line, e.g. -I./inc)

'iostream' file not found? This config ships two safeguards: --query-driver=/usr/bin/* (clangd asks your real compiler for include paths) and ~/.config/clangd/config.yaml (fallback compiler for database-less files). The root cause is usually a version mismatch between installed gcc and the libstdc++ headers — installing the matching g++-N fixes it permanently.

ARM Flash & Debug

<leader>dd (or :ArmDebug) runs the whole pipeline:

  1. Resolve the ELF: <current>.elf next to the source, or build/<current>.elf
  2. Guess the MCU from the ELF name: stm32f1/f103/bullet → STM32F1, h7/mc02 → STM32H7, otherwise → STM32F4
  3. Start OpenOCD in a terminal tab using openocd/<mcu>/daplink.cfg
  4. Wait for the probe, reset-halt, flash, and attach the DAP UI

Expected project layout:

project/
├── openocd/{stm32f1,stm32f4,stm32h7}/daplink.cfg
├── build/*.elf
└── src/*.c

The whole debug stack (nvim-dap + dap-ui + virtual-text) is lazy — it costs nothing until you press <leader>dd.

LaTeX

  • Compile: ,ll (latexmk) · view: ,lv (zathura + Synctex forward search; Ctrl+Click in zathura jumps back)
  • Conceal renders inline math; spell-check and soft wrap are on by default (after/ftplugin/tex.lua)
  • Requires TeX Live and zathura — see Prerequisites

Markdown & Prose

  • Markdown renders live (bold, headings, code blocks); spell-check and soft wrap on
  • .txt gets the same spell/wrap treatment
  • Indent guides are disabled in text/markdown/tex to keep prose clean

Lua Projects & Symbol Libraries

The Lua language server resolves symbols of the workspace it opened — and nothing else. When definitions live outside it (the Neovim runtime, a vendored SDK, a sibling library), declare them in the project, not in this config. .luarc.json in the project root is read natively by lua-language-server, is editor-agnostic, and is safe to commit:

{
  "runtime.version": "LuaJIT",
  "diagnostics.globals": ["vim"],
  "workspace.library": ["${env:VIMRUNTIME}", "../sibling-lib/src"]
}
  • Keys are dotted and unprefixed in .luarc.json (elsewhere they need the Lua. prefix)
  • LuaLS expands ${env:FOO}, ${workspaceFolder}, ${3rd} itself; relative paths resolve against the file's directory
  • Everything the library pulls in is visible for completion, hover and go-to-definition, but is read-only for renames
  • Adding a .luarc.json to an nvim-config repo is how vim.* gets resolved without a plugin and without a machine-specific path baked into the shared nvim config

To keep it on the Neovim side instead, a project-local .nvim.lua (needs vim.o.exrc = true, trusted once) does the same:

vim.lsp.config('lua_ls', { settings = { Lua = { workspace = { library = { vim.env.VIMRUNTIME } } } } })

Adding a New Language

Three steps, one rule:

  1. Add the LSP server binary to ensure_installed in mason.lua
  2. In lsp.lua: vim.lsp.config["<server>"] = { cmd = { <absolute mason bin path> } } + vim.lsp.enable("<server>")
  3. (Optional) Add a formatter to conform's formatters_by_ft

Rule: a given plugin must be declared in exactly one spec file — lazy.nvim executes only one config when the same plugin appears in multiple files. That's why all LSP/conform configs live together in lsp.lua.


🎨 Appearance

  • Colorscheme: vscode.nvim (dark) with custom group overrides — VS Code-style syntax colors tuned for Rust/C/C++
  • Indent guides: ┊ with scope highlighting; disabled in prose files
  • Rainbow delimiters for nested brackets
  • Flash highlights follow the theme palette (gold labels, orange targets, gray backdrop)
  • Gitsigns uses subtle bar glyphs in the sign column; two sign columns — git marks in column 1, diagnostics in column 2 (one sign per line, worst severity only)

🌐 中文文档 · English

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages