ACH-NEOVIM: A Step-by-Step Tutorial to a Supercharged Neovim
April 8, 2026·24 min read
A walkthrough of ACH-NEOVIM — my personal Neovim configuration that bootstraps a 45+ language IDE with one command. 75 dark themes, on-demand tooling, org-mode, HDL support, and zero manual setup.
I've been a Neovim user for years. Every time I rebuild my config from scratch I learn something new — but I also lose a weekend wrangling lazy.nvim, mason, LSP servers, formatters, linters, and a dozen plugins that all need to be wired together just right.
So I finally stopped rebuilding and started shipping. ACH-NEOVIM is the result — a single-command install that drops a polished, 45+ language Neovim IDE onto a fresh Mac with zero manual setup.
This post is a guided tour. By the end, you should be able to clone the repo, run one script, and start coding — or fork it and make it your own.
ACH-NEOVIMMIT01. Quick Start
| git clone https://github.com/anirbanchakraborty-dev/ACH-NEOVIM.git | |
| cd ACH-NEOVIM | |
| ./install.sh |
That's it. Launch nvim, the dashboard appears, plugins download themselves, and the first time you open a Python file the LSP, formatter, and linter install in the background.
02. What You Get
A short list of what makes this config different from a stock lazy.nvim starter:
- One-command install.
install.shprovisions Homebrew, the latest stable Neovim, and the Claude Code CLI. Re-run it any time — every step is idempotent. - On-demand everything. No
ensure_installedlists anywhere. Open a Python file andpyright + ruffinstall themselves. Open a Go file andgopls + gofumptarrive. Treesitter parsers, formatters, and linters all follow the same pattern. - Native LSP client. Uses Neovim 0.12+'s
vim.lsp.config/vim.lsp.enableflow withnvim-lspconfigproviding per-server defaults.blink.cmpcapabilities are merged into every server automatically. - 45+ languages supported out of the box, all installed lazily on first use.
- 75 dark themes. A custom theme engine adapts 74 vendored NvChad/base46 palettes plus the signature deep-ocean palette onto tokyonight. Live preview picker, keyboard cycling, and persistence across sessions — 80+ highlight overrides propagate to every plugin on each switch.
- Claude Code inside Neovim.
coder/claudecode.nvimships Claude as a snacks-themed split with native diff review and selection tracking. - Full org-mode. Agenda, capture templates, TODO cycling, and
org-roamfor a bidirectional knowledge graph — all under<leader>n. - HDL first-class support. Optional
--with-hdlflag installs verible, verilator, Icarus Verilog, Yosys, and Surfer. Dual LSPs (verible for lint/outline + svlangserver for cross-file navigation) attach in tandem. A custom verilator filelist resolver walks up to the project root for*.ffilelists. - Schema-aware JSON / YAML.
SchemaStore.nvimis wired into bothjsonlsandyamlls— you get completion + validation forpackage.json,tsconfig.json, GitHub Actions, Kubernetes manifests, docker-compose, and 1200+ other schemas with no manual setup. - Per-project LSP overrides.
neoconf.nvimauto-merges.neoconf.jsonand.vscode/settings.jsonfrom the project root into the LSP config, so cloning a JS/TS project that ships shared editor settings just works. - Harpoon quick marks.
<leader>Hto mark,<leader>1–<leader>9to jump. Persistent across sessions. - Task runner.
overseer.nvimruns make/npm/cargo/go tasks with<leader>o. - Yank ring.
yanky.nvimgives you a clipboard history with<leader>pand[y/]ycycling after paste.
03. Step 1 — Run the Installer
The installer does four things (plus an optional fifth):
- Installs Homebrew if it isn't already present (Apple Silicon aware).
- Installs or upgrades Neovim to the latest stable release (validated against the GitHub releases API — not just whatever Homebrew last cached).
- Installs the Claude Code CLI via the official native installer (
~/.local/bin/claude, auto-updates in the background) and appends the PATH export to~/.zshrcif it isn't already there. - Symlinks
nvim/to~/.config/nvim. If you already have a Neovim config, it gets moved to a timestamped backup first. - (Optional) Installs HDL tooling when you pass
--with-hdl— verible, verilator, Icarus Verilog, Yosys, Surfer, and netlistsvg (~500 MB). Skip this unless you write Verilog or SystemVerilog.
Every step prints a colored status line, and the script bails on the first error thanks to set -euo pipefail. Re-running is safe — anything already installed is skipped.
| # Standard install | |
| ./install.sh | |
| # With HDL tools | |
| ./install.sh --with-hdl |
When it finishes, you'll see something like:
| [OK] ACH-NEOVIM setup complete! | |
| Neovim: NVIM v0.11.x | |
| Claude: x.x.x | |
| Config: /Users/you/.config/nvim -> /path/to/ACH-NEOVIM/nvim | |
| [INFO] Launch Neovim with: nvim |
04. Step 2 — First Launch
Open Neovim:
| nvim |
The first launch does a few things in order:
lazy.nvimbootstraps itself (clones from GitHub on first run).- Every plugin in
nvim/lua/plugins/is downloaded. - The
snacks.dashboardstartup screen appears — an ASCII-art "ACH NEOVIM" header with quick links to find files, grep text, recent files, config, and Lazy. - As soon as you open a file in any supported language, mason starts installing the matching LSP server, formatter, and linter in the background. You'll see a
snacks.notifiertoast for every install.
05. Step 3 — Authenticate GitHub (Optional)
If you want the in-editor GitHub integration via octo.nvim (issues, PRs, code review, full-text search), authenticate the gh CLI once:
| gh auth login |
After that, <leader>gi lists issues, <leader>gp lists PRs, <leader>gP searches PRs, and <leader>gS runs a full-text GitHub search — all in fzf-lua pickers, all rendered as Neovim buffers.
06. The Configuration Tour
Here's what lives in the repo:
ACH-NEOVIM/
├── install.sh one-command installer (--with-hdl flag)
├── uninstall.sh clean removal
├── stylua.toml Lua formatter config (2-space, 120 col)
├── .markdownlint.json lint rules for docs
├── CLAUDE.md AI assistant guidelines
└── nvim/
├── init.lua entry point (4 lines)
└── lua/
├── config/
│ ├── options.lua vim.opt defaults
│ ├── keymaps.lua non-plugin keymaps
│ ├── autocmds.lua 17 autocommand groups
│ ├── lazy.lua lazy.nvim bootstrap
│ ├── icons.lua central Nerd Font glyph table (~500 icons)
│ └── tailwind_colors.lua Tailwind v3 palette data (22 families)
├── themes/
│ ├── init.lua theme loader + base46->tokyonight adapter
│ ├── base46_shim.lua no-op shim for vendored NvChad themes
│ └── nvchad/ 75 dark palettes (74 vendored + deep-ocean)
└── plugins/
├── ai.lua Claude Code (coder/claudecode.nvim)
├── coding.lua blink.cmp, mini.pairs/surround/ai, dial, refactoring, neogen, yanky, lazydev
├── colorscheme.lua tokyonight + 80+ highlight overrides + theme picker
├── editor.lua which-key, fzf-lua, flash, todo-comments, trouble, grug-far, harpoon, outline
├── formatting.lua conform.nvim + on-demand mason installer
├── git.lua gitsigns, diffview, git-conflict, lazygit, octo.nvim
├── lang.lua render-markdown, markdown-preview, vimtex, venv-selector
├── linting.lua nvim-lint + on-demand mason + verilator filelist resolver
├── lsp.lua mason + native vim.lsp client + SchemaStore + neoconf + clangd_extensions + inc-rename
├── lualine.lua NvChad-inspired statusline (palette-driven)
├── org.lua orgmode + org-bullets + org-roam
├── terminal.lua toggleterm + 7 language REPLs
├── treesitter.lua nvim-treesitter (main branch) + textobjects + context
├── ui.lua snacks, noice, bufferline, edgy, mini.icons, rainbow, colorizer, mini.hipatterns
└── util.lua persistence, vim-sleuth, overseer, scratch, vim-startuptimeEach plugin file returns a table of lazy.nvim specs. To add a new plugin, drop a new file in nvim/lua/plugins/ and lazy auto-imports it.
07. Languages Supported
The whole point of "on-demand everything" is that you don't have to think about this list — but if you're curious whether your language is covered, here's the rundown.
Core stack (used daily)
| Language | LSP | Formatter | Linter |
|---|---|---|---|
| Lua | lua_ls | stylua | — |
| Python | pyright + ruff | ruff (organize+fmt) | ruff (LSP) |
| TypeScript / JS | ts_ls + eslint (LSP) | prettierd / prettier + eslint | eslint (LSP) |
| HTML / CSS | html + emmet, cssls | prettierd / prettier | — |
| JSON / YAML | jsonls / yamlls + SchemaStore | prettierd / prettier | yamllint |
| Markdown | marksman | prettier + markdown-toc + mdlint | markdownlint |
| Bash / Zsh | bashls | shfmt | shellcheck |
| C / C++ | clangd + clangd_extensions | clang-format | — |
| Go | gopls | goimports + gofumpt | golangci-lint |
| LaTeX / BibTeX | texlab + vimtex | latexindent / bibtex-tidy | — |
Web
| Language | LSP | Formatter | Notes |
|---|---|---|---|
| Angular | angularls | prettier | |
| Astro | astro-language-server | prettier | |
| Svelte | svelte-language-server | prettier | |
| Vue | vue_ls (Volar) | prettier | standalone Volar |
| Tailwind CSS | tailwindcss-language-server | — | attaches across html/css/js/ts/... |
| Prisma | prismals | prettier | |
| Ember | ember | — | |
| Twig | twiggy_language_server | — |
Systems / Compiled
| Language | LSP | Formatter | Notes |
|---|---|---|---|
| Rust | rust_analyzer (clippy on save) | rustfmt | |
| Zig | zls | zig fmt | |
| Haskell | haskell-language-server | ormolu | heavy install (~2 GB) |
| OCaml | ocaml-lsp | ocamlformat | |
| Elixir | elixir-ls | mix format | |
| C# / VB | omnisharp | csharpier | |
| Kotlin | kotlin-language-server | ktlint | |
| Scala | metals | scalafmt | |
| Java | jdtls | google-java-format | |
| PHP | intelephense | php-cs-fixer / pint | |
| Swift | sourcekit (system) | — | Apple Xcode toolchain |
| Dart | dartls (system) | — | Flutter/Dart SDK |
HDL / Hardware
| Language | LSP | Formatter | Linter | Notes |
|---|---|---|---|---|
| SystemVerilog | verible + svlangserver (dual) | verible (brew) | verilator | verible for lint/outline, svlangserver for cross-file nav |
| Verilog | verible + svlangserver (dual) | verible (brew) | verilator | same dual-LSP setup |
| VHDL | — | — | — | treesitter highlighting + comment string |
Infra / Data
| Language | LSP | Formatter | Linter |
|---|---|---|---|
| Ansible | ansible-language-server | — | ansible-lint |
| CMake | cmake-language-server | cmake-format | cmakelint |
| Helm | helm-ls | — | — |
| Terraform | terraform-ls | terraform fmt | tflint |
| TOML | taplo | taplo | — |
| SQL | sqls | sqlfluff | sqlfluff |
| Solidity | solidity_ls_nomicfoundation | forge fmt | solhint |
| Dockerfile | — | — | hadolint |
| Nix | nil_ls | alejandra | — |
| Rego | regal | — | — |
| Typst | tinymist | — | — |
...plus Ruby, Perl, R, Julia, Lean, Elm, Erlang, Clojure, Gleam, and more. The full table is in the README.
08. Design Decisions
On-Demand Everything
This is the part I'm proudest of. Most Neovim configs hard-code an ensure_installed list — every Mason update reinstalls 50 LSPs whether you use them or not. Cloning a fresh config means staring at a progress bar for ten minutes before you can even open a file.
ACH-NEOVIM flips the model. The lsp.lua, formatting.lua, and linting.lua plugin files each register a FileType autocmd. The first time you open a buffer of a given filetype, the autocmd looks up which tools are mapped to that filetype and asks Mason to install them in the background. A snacks.notifier toast tells you when each install starts and finishes. After that, the autocmd is a no-op.
A cross-installer race guard prevents pkg:install() assertion errors when the same Mason package is targeted by the LSP, formatter, and linter autocmds simultaneously — a subtle bug that most configs don't handle.
The result: a fresh install boots in seconds. Tooling appears only as you actually need it.
Native LSP Client
Neovim 0.11 introduced vim.lsp.config / vim.lsp.enable — a built-in client that replaces the long-standing nvim-lspconfig.setup() boilerplate. ACH-NEOVIM uses the new API:
nvim-lspconfigis still pulled in, but only for its default per-server config files (paths, root markers, init options).vim.lsp.config('*', { capabilities = blink_caps })mergesblink.cmp's completion capabilities into every server.vim.lsp.enable(server_name)is called per server inside the on-demand installer.
It's leaner, faster to start, and matches where the Neovim core is going.
Notable per-server configs:
- ts_ls gets inlay hints (parameter names literals-only, types, return types, enum values), auto-import-on-rename, and complete function calls.
<leader>cMadds missing imports,<leader>cDfixes all diagnostics. - gopls uses gofumpt, enables full code lens, inlay hints, and staticcheck with a semantic tokens workaround for a known Go issue.
- clangd enables background indexing, clang-tidy, include-what-you-use, and function arg placeholders.
<leader>chswitches between source and header files. - HDL dual LSPs: verible handles lint diagnostics and document outline; svlangserver handles cross-file definition/references/navigation. Verible's broken definition/references/rename providers are disabled on attach so the two don't conflict.
75 Dark Themes
The original config had one palette — deep-ocean. Now there are 75.
The theme system lives in lua/themes/. A loader (init.lua) discovers palettes by scanning the nvchad/ subdirectory, which contains 74 vendored NvChad/base46 palettes plus my custom deep-ocean.lua. A to_tokyonight() adapter maps each palette's base_30 (30 UI colors) and base_16 (16 syntax colors) onto tokyonight's color slots.
Switching themes is instant:
| Key | Action |
|---|---|
<leader>uC | Open theme picker with live preview |
<leader>uN | Cycle to next theme |
<leader>uP | Cycle to previous theme |
The current theme persists in ~/.local/state/nvim/ach-theme.json across sessions. When you switch, apply() mutates the active palette and re-fires :colorscheme tokyonight — all 80+ highlight overrides in colorscheme.lua reference tokyonight's c.* colors, so every plugin recolors automatically. The statusline uses hi! link chains, so lualine recolors without a setup() rerun.
The signature palette is still deep-ocean: #011628 background, #011423 floats, #82AAFF blue accent, #0A64AC search highlights.
Format + Lint Pipeline
Two plugins, two clearly-separated jobs:
conform.nvimhandles format-on-save (sync, 1500ms timeout, LSP fallback). It uses aprettierd -> prettierfallback chain for web files, gated by aprettier --file-infoparser check so prettier silently falls back to the LSP formatter on filetypes it can't parse. ESLint auto-fix-on-save runs before prettier via the eslint LSP'ssource.fixAll.eslintcode action — eslint fixes lint issues, prettier has the final word on cosmetic formatting.nvim-lintruns external linters (shellcheck,markdownlint,hadolint,yamllint,golangci-lint,ansible-lint,tflint,sqlfluff,solhint,cmakelint,verilator) via a debounced dispatcher (100ms) and feeds results intovim.diagnostic. An executable guard checksvim.fn.executablebefore spawning to prevent ENOENT errors on cold starts.
Markdown gets two conditional formatters: markdown-toc only fires on buffers with a <!-- toc --> marker, markdownlint-cli2 only fires when there are existing markdownlint diagnostics. Cheap and surgical.
ESLint is intentionally absent from nvim-lint — diagnostics come from the eslint LSP server instead, avoiding double-counted warnings.
Verilator Filelist Resolver
If you write SystemVerilog or Verilog, the linter (verilator) needs to know about all the files in your project to resolve cross-module references. Most configs punt on this.
ACH-NEOVIM's linting.lua includes a custom resolver that walks up from the current buffer's directory to find a *.f filelist at the project root. It appends -f <filelist> to verilator's args. The lookup is cached per-directory with a 5-second TTL. If no filelist is found, verilator falls back to single-file mode. Default flags: -sv -Wall --language 1800-2017 -Wno-MULTITOP -Wno-MODDUP --bbox-sys --bbox-unsup --lint-only.
Central Icon Table
Every Nerd Font glyph used in the config — roughly 500 across diagnostics, git symbols, file types, LSP kinds, UI elements, org-mode, and more — lives in nvim/lua/config/icons.lua. Plugin files reference them by name (icons.diagnostics.Error, icons.git.added, icons.org.todo).
Want to swap a glyph? Change it once. It propagates everywhere. No more grep-and-replace across 15 files.
NvChad-Inspired Statusline
The statusline layout:
| [MODE] | branch | +1 ~2 -0 | 2 1 | filename | ...spinner... | lsp: lua_ls | lua | 42:8 | project |
Every section is palette-driven via hi! link chains defined in colorscheme.lua's on_highlights. The mode badge recolors per mode: blue for normal, green for insert, purple for visual, red for replace, orange for command, cyan for terminal. Switching themes re-fires the highlight chain — the entire statusline recolors instantly with no setup() call needed.
Components include an animated LSP progress spinner (driven by a LspProgress autocmd), attached LSP client names, state-aware filename (cyan normal, orange modified, red readonly), and the cwd basename that hides on narrow terminals.
Sticky Scope Header
nvim-treesitter-context pins the current function/class/method signature to the top of the buffer when you scroll past its definition. Cursor-mode tracking with a 3-line cap so deeply-nested scopes never take over the screen. Toggle with <leader>ut.
Tailwind Class Highlighting
mini.hipatterns renders Tailwind utility class names like bg-blue-500 or text-emerald-300 with the actual color inline (background tint + contrasting fg). Works across 18 filetypes including html, css, js, ts, vue, svelte, astro, handlebars, twig, and postcss. The Tailwind palette lives in config/tailwind_colors.lua as a pure data module — 22 color families, 11 shades each.
It coexists with nvim-colorizer (which still handles hex / rgb / hsl / CSS named colors) — zero overlap.
Org Mode
A full Emacs-style org-mode stack lives in org.lua:
- orgmode — agenda views, capture templates (Todo, Note, Journal), TODO state cycling, date stamps, clocking, refile, export. Files live in
~/org/. - org-bullets.nvim — concealed heading stars replaced with clean unicode bullets.
- org-roam.nvim — bidirectional linking and a knowledge graph for notes in
~/org/roam/.
Scoped fzf-lua searches (<leader>nf find org files, <leader>ns grep org content) keep org-mode navigation fast. The orgmode completion source is registered in blink.cmp for org buffers, so link and tag completion works in the standard popup.
Treesitter Main Branch
ACH-NEOVIM runs nvim-treesitter on the main branch — the complete rewrite targeting Neovim 0.12+. This means lazy = false (required), async parser installation via the new API, and vim.treesitter.start() per-buffer with a defensive wrapper for missing parsers.
The main branch dropped the incremental_selection module, so ACH-NEOVIM ships a custom implementation: <C-Space> initializes or grows the selection by walking up the treesitter node tree, <BS> shrinks it by popping the node stack. The stack is cleared on mode change to prevent stale state.
Supercharged Increment/Decrement
dial.nvim turns <C-a> / <C-x> into context-aware togglers. Beyond the obvious numbers and dates, it cycles:
true/false,&&/||, weekday names, month nameslet/constin TypeScript- Hex colors in CSS
- Markdown checkboxes (
[ ]/[x]) and heading levels (#through######) - Semver ranges in JSON
and/orin Lua and Python
Refactoring + Docstrings
refactoring.nvim gives you extract function, extract variable, extract block, and inline variable — all via <leader>r with fzf-lua as the picker. neogen generates docstring annotations with <leader>cn, using the vim.snippet engine so you can tab through placeholders.
09. Keymap Cheat Sheet
Leader is <Space>. Holding leader pops up which-key (Helix preset, bottom-right vertical stack) with every binding labelled and iconned.
The headline groups:
| Prefix | Group |
|---|---|
<leader>a | AI / Claude |
<leader>b | Buffer |
<leader>c | Code (LSP) |
<leader>e | Explorer (root) |
<leader>f | File / Find |
<leader>g | Git |
<leader>h | Harpoon Quick Menu |
<leader>l | Lazy |
<leader>m | Mason |
<leader>n | Notes / Org |
<leader>o | Overseer (Tasks) |
<leader>p | Yank History |
<leader>q | Session |
<leader>r | Refactor |
<leader>s | Search |
<leader>t | Terminal / REPLs |
<leader>u | UI toggles |
<leader>w | Window |
<leader>x | Diagnostics / Trouble |
<leader>1–<leader>9 | Harpoon jump 1–9 |
AI / Claude
| Keys | What it does |
|---|---|
<leader>ac | Toggle Claude panel |
<leader>af | Focus Claude panel |
<leader>ar | Resume Claude session |
<leader>aC | Continue Claude |
<leader>am | Select model |
<leader>ab | Add current buffer to context |
<leader>as (visual) | Send selection to Claude |
<leader>aa | Accept diff |
<leader>ad | Deny diff |
Navigation + Editing
| Keys | What it does |
|---|---|
<C-\> | Toggle floating terminal |
<C-h/j/k/l> | Window navigation |
<S-h> / <S-l> | Previous / next buffer |
<A-j> / <A-k> | Move line(s) down / up |
s / S | Flash jump / treesitter jump |
<C-Space> / <BS> | Grow / shrink treesitter selection |
]f / [f | Next / prev function |
]c / [c | Next / prev class |
]a / [a | Next / prev parameter |
]d / [d | Next / prev diagnostic |
]e / [e | Next / prev error |
]w / [w | Next / prev warning |
]h / [h | Next / prev git hunk |
]t / [t | Next / prev TODO comment |
]x / [x | Next / prev git conflict |
]q / [q | Next / prev quickfix (smart: uses trouble when open) |
Code + LSP
| Keys | What it does |
|---|---|
gd | Go to definition |
gD | Go to declaration |
gr | References |
gI | Go to implementation |
gy | Go to type definition |
K | Hover docs |
gK / <C-k> (insert) | Signature help |
<leader>ca | Code action |
<leader>cr | Rename symbol (live preview) |
<leader>cR | Rename file |
<leader>cd | Line diagnostic |
<leader>cl | LSP info |
<leader>co | Organize imports |
<leader>cc | Run codelens |
<leader>cf | Format buffer |
<leader>cF | Format injected languages |
<leader>cn | Generate docstring annotation |
<leader>cs | Toggle symbol outline sidebar |
<leader>ch | Switch C/C++ source/header |
<leader>cv | Pick a Python virtualenv |
<leader>cp | Markdown preview (browser) |
Editing Extras
| Keys | What it does |
|---|---|
gco / gcO | Add comment line below / above |
gsa / gsd / gsr | Surround add / delete / replace |
<C-a> / <C-x> | Smart increment / decrement (dial) |
<leader>p | Yank history picker |
[y / ]y | Cycle yank ring after paste |
<leader>H | Harpoon: add file |
<leader>h | Harpoon: quick menu |
Search + Replace
| Keys | What it does |
|---|---|
<leader>ff | Find files |
<leader>fg | Live grep |
<leader>fb | Buffers |
<leader>fh | Help tags |
<leader>fr | Recent files |
<leader>fc | Config files |
<leader>sR | Search & replace (grug-far) |
<leader>sr | Resume last search |
<leader>st | TODO comments (fzf-lua) |
Git
| Keys | What it does |
|---|---|
<leader>gg | LazyGit |
<leader>gB | Browse on GitHub |
<leader>gb | Toggle line blame |
<leader>gd / <leader>gD | Diffview open / close |
<leader>gf | Diffview file history |
<leader>gl | Diffview repo log |
<leader>gi / <leader>gI | Octo: list / search issues |
<leader>gp / <leader>gP | Octo: list / search PRs |
<leader>gr | Octo: list repos |
<leader>gS | Octo: full-text search |
<leader>ghs / <leader>ghr | Stage / reset hunk |
<leader>ghS / <leader>ghR | Stage / reset buffer |
<leader>gxo / gxt / gxb / gxn | Conflict: ours / theirs / both / none |
Notes / Org
| Keys | What it does |
|---|---|
<leader>na | Org agenda |
<leader>nc | Org capture |
<leader>nf | Find org files |
<leader>ns | Search org files |
<leader>nr | Roam: find node |
<leader>ni | Roam: insert link |
<leader>nl | Roam: toggle buffer |
Terminal + REPLs
| Keys | What it does |
|---|---|
<leader>tf / th / tv / tT | Float / horizontal / vertical / tab terminal |
<leader>tp | Python REPL |
<leader>tn | Node REPL |
<leader>tl | Lua REPL |
<leader>tr | Ruby IRB |
<leader>tR | R Console |
<leader>tP | Perl REPL |
<leader>ts | Swift REPL |
UI Toggles
| Keys | What it does |
|---|---|
<leader>uf | Toggle format-on-save |
<leader>um | Toggle inline markdown rendering |
<leader>ut | Toggle sticky scope header |
<leader>ue / <leader>uE | Toggle edgy sidebars |
<leader>uC | Theme picker (live preview) |
<leader>uN / <leader>uP | Cycle next / previous theme |
Tasks (Overseer)
| Keys | What it does |
|---|---|
<leader>oo | Run task |
<leader>ow | Task list |
<leader>ot | Task action |
<leader>oq | Quick action |
<leader>oi | Task info |
10. Customization
1. Add a Plugin
Create a new file in nvim/lua/plugins/ returning a table of lazy.nvim specs. lazy auto-imports it.
| -- nvim/lua/plugins/my-plugin.lua | |
| return { | |
| { | |
| "username/cool-plugin.nvim", | |
| event = "VeryLazy", | |
| opts = { | |
| -- plugin config | |
| }, | |
| }, | |
| } |
If the plugin has keymaps, follow the pattern in terminal.lua: define keys = {} on the spec, then add a parallel which-key.nvim block in the same file with icons sourced from config/icons.lua.
2. Change the Palette
Open the theme picker with <leader>uC and browse all 75 palettes with live preview. Your choice persists automatically.
To customize the signature deep-ocean palette, edit lua/themes/nvchad/deep-ocean.lua. To adjust the 80+ plugin highlight overrides, edit colorscheme.lua — every override references tokyonight's c.* color slots, so your changes propagate to all 75 themes.
3. Add an LSP / Formatter / Linter
Add an entry to the servers table in lsp.lua (or formatter_to_mason / linter_to_mason in formatting.lua / linting.lua). The on-demand installer will pick it up the next time you open a matching filetype.
4. Add Org Capture Templates
The default templates (Todo, Note, Journal) live in the orgmode spec in org.lua. Add new templates following the orgmode.nvim docs — they'll appear in the capture menu at <leader>nc.
11. Options Worth Knowing
A few non-obvious defaults from options.lua:
- Leader:
<Space>. Local leader:\. - Tabs: 2 spaces everywhere, except Python/C/C++/Rust/Java (4 spaces) and Go (hard tabs). Autodetected per-file by
vim-sleuth. - Folds: Start fully open (level 99). Treesitter foldexpr is enabled per-buffer when a parser is available.
- Clipboard: System clipboard via
unnamedplus(disabled over SSH for OSC 52). - Scrolloff: 8 lines. Global statusline (
laststatus = 3). Smooth scrolling. - Conceallevel: 2 (enables markdown concealing for render-markdown).
- Persistent undo across sessions.
12. Autocmds
17 autocommand groups handle the rough edges:
- TreesitterLanguageAlias — registers the
systemverilogparser forverilogfiletype (they share a grammar). - ExplorerAutoClose — quits Neovim when only snacks explorer windows remain.
- HighlightYank — 200ms flash on yank.
- RestoreCursor — restores last cursor position on file open.
- ProseMode — enables wrap, spell, and linebreak for markdown/gitcommit/text/tex.
- JsonConceal — disables conceallevel in JSON files (so you can see quotes).
- TreesitterFolds — swaps to treesitter foldexpr when a parser is available.
- Indent4 — 4-space indent for Python/C/C++/Rust/Java.
- GoTabs — hard tabs for Go.
- HdlCommentstring —
// %sfor SystemVerilog/Verilog,-- %sfor VHDL. - BigFile — disables syntax, treesitter, spell, and undo for files > 1.5 MiB.
13. Uninstall
| ./uninstall.sh |
Removes the symlink at ~/.config/nvim and Neovim's data / state / cache directories. Your repo clone stays intact. Re-run install.sh to set everything back up.
14. Try It
Clone it, fork it, rip out the parts you don't like, and never manually configure Neovim from scratch again:
| git clone https://github.com/anirbanchakraborty-dev/ACH-NEOVIM.git | |
| cd ACH-NEOVIM | |
| ./install.sh |
If you've already followed Post-Mac-Setup for the rest of your machine, this is the natural next step. Same philosophy: one script, idempotent, hands-off.