Essay

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-NEOVIMMIT

01. Quick Start

Bash
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.sh provisions Homebrew, the latest stable Neovim, and the Claude Code CLI. Re-run it any time — every step is idempotent.
  • On-demand everything. No ensure_installed lists anywhere. Open a Python file and pyright + ruff install themselves. Open a Go file and gopls + gofumpt arrive. Treesitter parsers, formatters, and linters all follow the same pattern.
  • Native LSP client. Uses Neovim 0.12+'s vim.lsp.config / vim.lsp.enable flow with nvim-lspconfig providing per-server defaults. blink.cmp capabilities 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.nvim ships Claude as a snacks-themed split with native diff review and selection tracking.
  • Full org-mode. Agenda, capture templates, TODO cycling, and org-roam for a bidirectional knowledge graph — all under <leader>n.
  • HDL first-class support. Optional --with-hdl flag 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 *.f filelists.
  • Schema-aware JSON / YAML. SchemaStore.nvim is wired into both jsonls and yamlls — you get completion + validation for package.json, tsconfig.json, GitHub Actions, Kubernetes manifests, docker-compose, and 1200+ other schemas with no manual setup.
  • Per-project LSP overrides. neoconf.nvim auto-merges .neoconf.json and .vscode/settings.json from the project root into the LSP config, so cloning a JS/TS project that ships shared editor settings just works.
  • Harpoon quick marks. <leader>H to mark, <leader>1<leader>9 to jump. Persistent across sessions.
  • Task runner. overseer.nvim runs make/npm/cargo/go tasks with <leader>o.
  • Yank ring. yanky.nvim gives you a clipboard history with <leader>p and [y/]y cycling after paste.

03. Step 1 — Run the Installer

The installer does four things (plus an optional fifth):

  1. Installs Homebrew if it isn't already present (Apple Silicon aware).
  2. Installs or upgrades Neovim to the latest stable release (validated against the GitHub releases API — not just whatever Homebrew last cached).
  3. Installs the Claude Code CLI via the official native installer (~/.local/bin/claude, auto-updates in the background) and appends the PATH export to ~/.zshrc if it isn't already there.
  4. Symlinks nvim/ to ~/.config/nvim. If you already have a Neovim config, it gets moved to a timestamped backup first.
  5. (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.

Bash
# Standard install
./install.sh
# With HDL tools
./install.sh --with-hdl

When it finishes, you'll see something like:

Plain Text
[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:

Bash
nvim

The first launch does a few things in order:

  1. lazy.nvim bootstraps itself (clones from GitHub on first run).
  2. Every plugin in nvim/lua/plugins/ is downloaded.
  3. The snacks.dashboard startup screen appears — an ASCII-art "ACH NEOVIM" header with quick links to find files, grep text, recent files, config, and Lazy.
  4. 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.notifier toast 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:

Bash
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:

Plain Text
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-startuptime

Each 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)

LanguageLSPFormatterLinter
Lualua_lsstylua
Pythonpyright + ruffruff (organize+fmt)ruff (LSP)
TypeScript / JSts_ls + eslint (LSP)prettierd / prettier + eslinteslint (LSP)
HTML / CSShtml + emmet, csslsprettierd / prettier
JSON / YAMLjsonls / yamlls + SchemaStoreprettierd / prettieryamllint
Markdownmarksmanprettier + markdown-toc + mdlintmarkdownlint
Bash / Zshbashlsshfmtshellcheck
C / C++clangd + clangd_extensionsclang-format
Gogoplsgoimports + gofumptgolangci-lint
LaTeX / BibTeXtexlab + vimtexlatexindent / bibtex-tidy

Web

LanguageLSPFormatterNotes
Angularangularlsprettier
Astroastro-language-serverprettier
Sveltesvelte-language-serverprettier
Vuevue_ls (Volar)prettierstandalone Volar
Tailwind CSStailwindcss-language-serverattaches across html/css/js/ts/...
Prismaprismalsprettier
Emberember
Twigtwiggy_language_server

Systems / Compiled

LanguageLSPFormatterNotes
Rustrust_analyzer (clippy on save)rustfmt
Zigzlszig fmt
Haskellhaskell-language-serverormoluheavy install (~2 GB)
OCamlocaml-lspocamlformat
Elixirelixir-lsmix format
C# / VBomnisharpcsharpier
Kotlinkotlin-language-serverktlint
Scalametalsscalafmt
Javajdtlsgoogle-java-format
PHPintelephensephp-cs-fixer / pint
Swiftsourcekit (system)Apple Xcode toolchain
Dartdartls (system)Flutter/Dart SDK

HDL / Hardware

LanguageLSPFormatterLinterNotes
SystemVerilogverible + svlangserver (dual)verible (brew)verilatorverible for lint/outline, svlangserver for cross-file nav
Verilogverible + svlangserver (dual)verible (brew)verilatorsame dual-LSP setup
VHDLtreesitter highlighting + comment string

Infra / Data

LanguageLSPFormatterLinter
Ansibleansible-language-serveransible-lint
CMakecmake-language-servercmake-formatcmakelint
Helmhelm-ls
Terraformterraform-lsterraform fmttflint
TOMLtaplotaplo
SQLsqlssqlfluffsqlfluff
Soliditysolidity_ls_nomicfoundationforge fmtsolhint
Dockerfilehadolint
Nixnil_lsalejandra
Regoregal
Typsttinymist

...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-lspconfig is still pulled in, but only for its default per-server config files (paths, root markers, init options).
  • vim.lsp.config('*', { capabilities = blink_caps }) merges blink.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>cM adds missing imports, <leader>cD fixes 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>ch switches 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:

KeyAction
<leader>uCOpen theme picker with live preview
<leader>uNCycle to next theme
<leader>uPCycle 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.nvim handles format-on-save (sync, 1500ms timeout, LSP fallback). It uses a prettierd -> prettier fallback chain for web files, gated by a prettier --file-info parser 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's source.fixAll.eslint code action — eslint fixes lint issues, prettier has the final word on cosmetic formatting.
  • nvim-lint runs external linters (shellcheck, markdownlint, hadolint, yamllint, golangci-lint, ansible-lint, tflint, sqlfluff, solhint, cmakelint, verilator) via a debounced dispatcher (100ms) and feeds results into vim.diagnostic. An executable guard checks vim.fn.executable before 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:

Plain Text
[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 names
  • let/const in TypeScript
  • Hex colors in CSS
  • Markdown checkboxes ([ ] / [x]) and heading levels (# through ######)
  • Semver ranges in JSON
  • and/or in 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:

PrefixGroup
<leader>aAI / Claude
<leader>bBuffer
<leader>cCode (LSP)
<leader>eExplorer (root)
<leader>fFile / Find
<leader>gGit
<leader>hHarpoon Quick Menu
<leader>lLazy
<leader>mMason
<leader>nNotes / Org
<leader>oOverseer (Tasks)
<leader>pYank History
<leader>qSession
<leader>rRefactor
<leader>sSearch
<leader>tTerminal / REPLs
<leader>uUI toggles
<leader>wWindow
<leader>xDiagnostics / Trouble
<leader>1<leader>9Harpoon jump 1–9

AI / Claude

KeysWhat it does
<leader>acToggle Claude panel
<leader>afFocus Claude panel
<leader>arResume Claude session
<leader>aCContinue Claude
<leader>amSelect model
<leader>abAdd current buffer to context
<leader>as (visual)Send selection to Claude
<leader>aaAccept diff
<leader>adDeny diff
KeysWhat 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 / SFlash jump / treesitter jump
<C-Space> / <BS>Grow / shrink treesitter selection
]f / [fNext / prev function
]c / [cNext / prev class
]a / [aNext / prev parameter
]d / [dNext / prev diagnostic
]e / [eNext / prev error
]w / [wNext / prev warning
]h / [hNext / prev git hunk
]t / [tNext / prev TODO comment
]x / [xNext / prev git conflict
]q / [qNext / prev quickfix (smart: uses trouble when open)

Code + LSP

KeysWhat it does
gdGo to definition
gDGo to declaration
grReferences
gIGo to implementation
gyGo to type definition
KHover docs
gK / <C-k> (insert)Signature help
<leader>caCode action
<leader>crRename symbol (live preview)
<leader>cRRename file
<leader>cdLine diagnostic
<leader>clLSP info
<leader>coOrganize imports
<leader>ccRun codelens
<leader>cfFormat buffer
<leader>cFFormat injected languages
<leader>cnGenerate docstring annotation
<leader>csToggle symbol outline sidebar
<leader>chSwitch C/C++ source/header
<leader>cvPick a Python virtualenv
<leader>cpMarkdown preview (browser)

Editing Extras

KeysWhat it does
gco / gcOAdd comment line below / above
gsa / gsd / gsrSurround add / delete / replace
<C-a> / <C-x>Smart increment / decrement (dial)
<leader>pYank history picker
[y / ]yCycle yank ring after paste
<leader>HHarpoon: add file
<leader>hHarpoon: quick menu

Search + Replace

KeysWhat it does
<leader>ffFind files
<leader>fgLive grep
<leader>fbBuffers
<leader>fhHelp tags
<leader>frRecent files
<leader>fcConfig files
<leader>sRSearch & replace (grug-far)
<leader>srResume last search
<leader>stTODO comments (fzf-lua)

Git

KeysWhat it does
<leader>ggLazyGit
<leader>gBBrowse on GitHub
<leader>gbToggle line blame
<leader>gd / <leader>gDDiffview open / close
<leader>gfDiffview file history
<leader>glDiffview repo log
<leader>gi / <leader>gIOcto: list / search issues
<leader>gp / <leader>gPOcto: list / search PRs
<leader>grOcto: list repos
<leader>gSOcto: full-text search
<leader>ghs / <leader>ghrStage / reset hunk
<leader>ghS / <leader>ghRStage / reset buffer
<leader>gxo / gxt / gxb / gxnConflict: ours / theirs / both / none

Notes / Org

KeysWhat it does
<leader>naOrg agenda
<leader>ncOrg capture
<leader>nfFind org files
<leader>nsSearch org files
<leader>nrRoam: find node
<leader>niRoam: insert link
<leader>nlRoam: toggle buffer

Terminal + REPLs

KeysWhat it does
<leader>tf / th / tv / tTFloat / horizontal / vertical / tab terminal
<leader>tpPython REPL
<leader>tnNode REPL
<leader>tlLua REPL
<leader>trRuby IRB
<leader>tRR Console
<leader>tPPerl REPL
<leader>tsSwift REPL

UI Toggles

KeysWhat it does
<leader>ufToggle format-on-save
<leader>umToggle inline markdown rendering
<leader>utToggle sticky scope header
<leader>ue / <leader>uEToggle edgy sidebars
<leader>uCTheme picker (live preview)
<leader>uN / <leader>uPCycle next / previous theme

Tasks (Overseer)

KeysWhat it does
<leader>ooRun task
<leader>owTask list
<leader>otTask action
<leader>oqQuick action
<leader>oiTask 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.

Lua
-- 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 systemverilog parser for verilog filetype (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// %s for SystemVerilog/Verilog, -- %s for VHDL.
  • BigFile — disables syntax, treesitter, spell, and undo for files > 1.5 MiB.

13. Uninstall

Bash
./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:

Bash
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.

Book mode
neovimluatoolsproductivitytutorial
Was this helpful?