A Lua-only Neovim configuration focused on fast navigation, solid language tooling, AI-assisted workflows, and practical test/debug support.
- Lua-first structure with shared config in
lua/config/, plugin specs inlua/plugins/, and filetype overrides inafter/. - Strong code-navigation workflow built around
fzf-lua,nvim-tree,aerial.nvim, Tree-sitter, and a custom always-visible tabline that keeps the current tab visible when crowded. - Comment helpers stay usable in non-Tree-sitter buffers by falling back to the buffer-local
commentstring, so mappings likecostill work in files such as.env. - Completion and AI tooling with
blink.cmp,copilot.lua,blink-cmp-copilot, andCopilotChat.nvim; chat defaults to GPT-6 Luna with maximum reasoning effort. - Language tooling powered by
nvim-lspconfig,mason.nvim,conform.nvim, andnvim-treesitter. - Testing and debugging workflows via
neotest,nvim-dap, andnvim-dap-ui. - Git and review workflow with
vim-fugitive,vim-rhubarb,gv.vim, quickfix helpers, repo-aware shell helpers, and shell-parity shortcuts like<leader>gaforgit add -Awith a completion notification. <leader>agsaves buffers, stages all changes silently, asks CopilotChat for a Conventional Commit message, and passes it to~/git/Linux/git/gap -mto commit, rebase, and push without a second AI call. It shows one final success or failure notification; failed runs keep their full output open in the terminal split, while successful splits close automatically. CopilotChat closes when the gap process finishes. The sharedgit/gapscript strips Copilot co-author trailers from commit messages.<leader>gtprefills the custom:GDifftoolcommand, which behaves like plaingit diff(same optional revision argument, e.g.:GDifftool HEADto include staged changes) but opens each changed file as a diff tab and additionally opens Git-added and untracked files in their own tabs, avoiding fugitive's "exists on disk, but not in<sha>" error for files with no prior version to diff against.- The save-and-quit helper behind
<C-q>only writes buffers that are actually writable, so readonly diff and review windows still close cleanly. - Local automation with
lefthookand a Plenary-based headless test suite.
- Plugin management:
lazy.nvim - Navigation and UI:
fzf-lua,nvim-tree.lua,aerial.nvim,treesitter-context.nvim,lualine.nvim,snacks.nvim(notifications and popup input),nvim-origami - Completion and editing:
blink.cmp,copilot.lua,blink-cmp-copilot,nvim-autopairs,nvim-surround,substitute.nvim - Markdown workflow:
selimacerbas/markdown-preview.nvim,img-paste.vim - Markdown preview uses per-instance servers, so
:MarkdownPreviewalways opens a fresh preview instead of silently attaching to an older Neovim session. - Markdown conceal hides emphasis, inline-code, and link markup and adds table-aware inline padding so pipe-table columns stay aligned.
- Markdown prose is spell-checked while fenced and indented code blocks are excluded through Tree-sitter.
- Markdown folds use a custom Tree-sitter section query to retain trailing blank lines, with
nvim-origamiand azxrefresh on markdownInsertLeaveandTextChangedevents. - The
blink.cmpcompletion menu is suppressed for markdown, so suggestions from every source stay hidden while writing prose (manual completion triggers still work). - Language tooling:
nvim-lspconfig,mason.nvim,conform.nvim,nvim-treesitter - Testing and debugging:
neotest,neotest-dotnet,neotest-python,nvim-dap,nvim-dap-ui - Git and diffing:
vim-fugitive,vim-rhubarb,gv.vim
This config is set up for everyday work across:
- Lua
- Python
- TypeScript / JavaScript / Vue
- C#
- Go
- SQL
- Markdown
- INI / DOSINI
- YAML / JSON / TOML / Bash
Generic .conf filenames are detected as conf; INI-style files should include # vim: set ft=dosini: to select the dosini filetype and its ini Tree-sitter parser. DOSINI comments use #.
Roslyn powers the C# workflow. Mason refreshes the configured registries and installs
the available roslyn-nightly package (falling back to roslyn) when it is
missing. The install is deferred until an interactive UI is ready, and headless
startup checks do not start network installs. The optional Razor/CSHTML Roslyn
extension stays disabled by default, so regular .cs editing works without
requiring the extra Razor DLLs from the VS Code C# toolchain.
Python uses Ruff for linting/import cleanup and basedpyright for type checking. Each
project owns its pyrightconfig.json, including its type-checking mode and scope. When
a project root contains a .venv, basedpyright automatically uses that environment's
interpreter and local language server, so different Python project roots can use
different virtual environments in the same Neovim session.
init.luabootstraps the config and loadslazy.nvim.lua/config/contains shared editor behavior, commands, autocmds, and focused helper modules for buffers, terminals, windows, and keymap facades.lua/config/commands.luaalso preserves legacy function-style entrypoints when plugin workflows still call them directly.lua/plugins/contains one Lazy spec per plugin or plugin group.after/ftplugin/andafter/ftdetect/contain filetype-local behavior.tests/contains the Plenary test harness and a focused set of repo-level behavior tests.
- Neovim
0.11.xstable or newer gitluafor hook syntax checksstyluafor Lua formatting and style checksctagsfor the Gutentags tag workflowmakefor buildingCopilotChat.nvim- Optional:
mmdr(cargo install mermaid-rs-renderer) for Rust-backed Mermaid rendering inmarkdown-preview.nvim; the configured renderer uses browser-side Mermaid.js tree-sitterCLI for compiling Tree-sitter parsersunzipfor extracting Mason packages- .NET SDK for the C# Roslyn language server
- Language servers / formatters installed through Mason or system packages, depending on the tool
For local test runs, the suite expects plenary.nvim at:
$HOME/.local/share/nvim/lazy/plenary.nvimOverride with PLENARY_PATH if needed.
The test harness sets nvim_config_test and uses a temporary file-backed
clipboard provider, so the headless suite does not require a desktop clipboard
session or the production clipsy helper.
The suite is intentionally biased toward startup, module-loading, commands, and stateful editor behaviors instead of exhaustive snapshots of every option or keymap. The plugin-spec tests mock Mason's registry, so the automatic Roslyn installation path is validated without downloading packages.
Place the repository at ~/.config/nvim. For example:
git clone <repo-url> ~/.config/nvim
# or
ln -s /path/to/this/repo ~/.config/nvimThen start Neovim to let lazy.nvim bootstrap itself and install plugins.
Mason installs the C# Roslyn package automatically after the interactive UI starts.
Useful follow-up commands:
:Lazy sync
:Mason
:TSUpdateSyncTo restore plugin versions exactly from lazy-lock.json:
nvim --headless -u init.lua "+Lazy! restore" +qaFormat the Lua tree:
stylua init.lua lua after testsCheck formatting without rewriting files:
stylua --check init.lua lua after testsRun the focused Plenary suite:
PLENARY_PATH="$HOME/.local/share/nvim/lazy/plenary.nvim" \
nvim --headless -u tests/minimal_init.lua \
-c "PlenaryBustedDirectory tests/nvim-config { minimal_init = 'tests/minimal_init.lua' }" \
-c "qa"Run a single test file:
PLENARY_PATH="$HOME/.local/share/nvim/lazy/plenary.nvim" \
nvim --headless -u tests/minimal_init.lua \
-c "PlenaryBustedFile tests/nvim-config/config_modules_spec.lua" \
-c "qa"Run a headless startup smoke test:
nvim --headless -u init.lua -c "qa"- Install hooks with
lefthook install - Run all local automation with
lefthook run pre-commit --all-files
The pre-commit hook runs:
- staged Lua formatting
- staged Markdown, JSON, and YAML formatting with Prettier
- on Lua changes:
stylua --check, Lua syntax checks, the focused Plenary suite, and a headless startup smoke test