nvim windows support + multicursors
This commit is contained in:
1 parent
b6968a10b3
commit
93c97e65e2
10 files changed
+778
-24
No files matched your search
+126
-2
@@ -1,9 +1,11 @@
|
||||
# Neovim Setup
|
||||
|
||||
A scripted Neovim setup built around C/C++ development (CMake + clangd + codelldb), with LSP support for Go, C#, TypeScript/JavaScript, HTML, and CSS alongside it. `setup_neovim.sh` handles installing dependencies and putting everything in place; the actual config lives in `config/` as plain files, not embedded in the script.
|
||||
A scripted Neovim setup built around C/C++ development (CMake + clangd + codelldb), with LSP support for Go, C#, TypeScript/JavaScript, HTML, and CSS alongside it. `setup_neovim.sh` (Linux) and `setup_neovim.ps1` (Windows) handle installing dependencies and putting everything in place; the actual config lives in `config/` as plain files, shared by both, not embedded in either script.
|
||||
|
||||
Supports **Fedora, Ubuntu, Debian, and Arch Linux** (and their common derivatives — Pop!_OS, Linux Mint, Manjaro, EndeavourOS, etc. — via `/etc/os-release`'s `ID_LIKE`) — the script detects which one you're on and uses the right package manager and package names automatically.
|
||||
|
||||
Also supports **Windows 10/11**, via `setup_neovim.ps1` and [winget](https://aka.ms/getwinget) — see [Installing → Windows](#windows) and [Windows notes](#windows-notes).
|
||||
|
||||
## Contents
|
||||
|
||||
- [Installing](#installing)
|
||||
@@ -11,6 +13,7 @@ Supports **Fedora, Ubuntu, Debian, and Arch Linux** (and their common derivative
|
||||
- [Config layout & adding plugins](#config-layout--adding-plugins)
|
||||
- [Terminal vs. desktop (Neovide)](#terminal-vs-desktop-neovide)
|
||||
- [Editor basics](#editor-basics)
|
||||
- [Multiple cursors](#multiple-cursors-multicursornvim)
|
||||
- [Look & feel](#look--feel)
|
||||
- [Buffers & tabs](#buffers--tabs-bufferline)
|
||||
- [Text search (Telescope)](#text-search-telescope)
|
||||
@@ -25,10 +28,13 @@ Supports **Fedora, Ubuntu, Debian, and Arch Linux** (and their common derivative
|
||||
- [Database (MariaDB)](#database-mariadb)
|
||||
- [Hex viewer](#hex-viewer)
|
||||
- [Formatting and linting](#formatting-and-linting)
|
||||
- [Windows notes](#windows-notes)
|
||||
- [Known quirks](#known-quirks)
|
||||
|
||||
## Installing
|
||||
|
||||
### Linux
|
||||
|
||||
```bash
|
||||
chmod +x setup_neovim.sh
|
||||
./setup_neovim.sh
|
||||
@@ -53,9 +59,65 @@ First launch takes a minute or two: `lazy.nvim` bootstraps itself and installs a
|
||||
- **Older distro releases** (Debian stable, older Ubuntu LTS): this config relies on Neovim 0.11+ APIs throughout. If your distro's packaged Neovim is older, the script prints a warning after install — see [Neovim's install docs](https://github.com/neovim/neovim/blob/master/INSTALL.md) for an AppImage/PPA/prebuilt build if so.
|
||||
- **Neovide** (if you choose it — see [Terminal vs. desktop (Neovide)](#terminal-vs-desktop-neovide)): Arch installs the packaged `neovide` binary directly; Fedora and Debian/Ubuntu have no native package for it, so the script builds it from source via `cargo` (installing Rust via `rustup` first if `cargo` isn't already on `PATH`), per [Neovide's own install docs](https://neovide.dev/installation.html#linux-source). This can take several minutes and, like the .NET SDK step, is best-effort — a failed build prints a warning rather than stopping the rest of the script.
|
||||
|
||||
### Windows
|
||||
|
||||
Needs Windows 10 (1809+) or Windows 11 with `winget` (the "App Installer" — preinstalled on current Windows; if it's missing, get it from the Microsoft Store). From PowerShell, in this folder:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\setup_neovim.ps1
|
||||
```
|
||||
|
||||
(`-ExecutionPolicy Bypass` applies to this one run only; it also gets around the "downloaded from the internet" block on a freshly unzipped script.) No administrator shell is needed — individual installers (LLVM, the .NET SDK, …) may still show their own UAC prompt.
|
||||
|
||||
As on Linux, keep `setup_neovim.ps1` and `config/` next to each other, and edit the files under `config/` rather than the script to customize. The script:
|
||||
|
||||
1. Installs everything through `winget` (Neovim and Git are required and abort the script if they fail; the rest are best-effort and just print a warning), asks which frontend(s) you want — see [Terminal vs. desktop (Neovide)](#terminal-vs-desktop-neovide) — and then installs npm-based language servers.
|
||||
2. Installs the JetBrainsMono and Cascadia Code Nerd Fonts for the current user (no admin needed).
|
||||
3. Removes the existing Neovim config **and data** folders, then copies `config/nvim` into `%LOCALAPPDATA%\nvim` (or `%XDG_CONFIG_HOME%\nvim` if you've set that — the same places Neovim itself looks).
|
||||
4. Copies `.clang-format`, `.clang-tidy` and `cpp-style-guide.md` into your user folder (`%USERPROFILE%`).
|
||||
|
||||
**Like the Linux script, this deletes the old config and data (`%LOCALAPPDATA%\nvim` and `%LOCALAPPDATA%\nvim-data`) with no backup by default** — but when run interactively it asks for confirmation first. Options:
|
||||
|
||||
| Option | Effect |
|
||||
|---|---|
|
||||
| `-Frontend terminal\|desktop\|both` | Skip the frontend question (the default when non-interactive is `terminal`) |
|
||||
| `-Backup` | Move the old config/data folders aside (`nvim.bak-<timestamp>`) instead of deleting them |
|
||||
| `-Force` | Don't ask for confirmation before deleting |
|
||||
| `-SkipMariaDB` | Don't offer to install the MariaDB client |
|
||||
|
||||
Open a **new** terminal afterwards so the PATH changes take effect. First launch takes a minute or two, as on Linux (`lazy.nvim` plugins, then Mason's language servers and `codelldb`; treesitter also compiles its parsers with `gcc`).
|
||||
|
||||
If you'd rather have the Linux experience, `setup_neovim.sh` also works unchanged inside a WSL Debian/Ubuntu distro.
|
||||
|
||||
#### What the Windows script installs
|
||||
|
||||
The same set of tools as on Linux, with Windows equivalents where the Linux package doesn't exist:
|
||||
|
||||
| Linux | Windows (winget id) |
|
||||
|---|---|
|
||||
| gcc, g++, make, gdb | WinLibs GCC / MinGW-w64 (`BrechtSanders.WinLibs.POSIX.UCRT`) — gcc, g++, gdb and a make — plus Ninja (`Ninja-build.Ninja`), the CMake generator to use on Windows |
|
||||
| cmake | `Kitware.CMake` |
|
||||
| clang-tools-extra (clang-format, clang-tidy) | `LLVM.LLVM` |
|
||||
| lldb | not installed separately — `codelldb` (via Mason) brings its own |
|
||||
| nodejs, npm / python3-pip / golang / dotnet-sdk-8.0 | `OpenJS.NodeJS.LTS` / `Python.Python.3.12` / `GoLang.Go` / `Microsoft.DotNet.SDK.8` |
|
||||
| ripgrep, fd-find | `BurntSushi.ripgrep.MSVC`, `sharkdp.fd` |
|
||||
| git, curl, wget, unzip | `Git.Git`; the rest ship with Windows |
|
||||
| fish | PowerShell 7 (`Microsoft.PowerShell`) — see [Terminal](#terminal) |
|
||||
| mariadb client | `MariaDB.Server`, run through its own installer wizard (opt-in prompt) — winget has no client-only package |
|
||||
| Neovide (optional) | `Neovide.Neovide` |
|
||||
|
||||
Where things end up:
|
||||
|
||||
| `config/` | Copied to |
|
||||
|---|---|
|
||||
| `nvim/` | `%LOCALAPPDATA%\nvim\...` (same layout as on Linux) |
|
||||
| `clang-format` | `%USERPROFILE%\.clang-format` |
|
||||
| `clang-tidy` | `%USERPROFILE%\.clang-tidy` |
|
||||
| `cpp-style-guide.md` | `%USERPROFILE%\cpp-style-guide.md` |
|
||||
|
||||
## What gets installed
|
||||
|
||||
Package names vary by distro (see the script for the exact list per package manager), but the same set gets installed everywhere:
|
||||
On Linux, package names vary by distro (see the script for the exact list per package manager), but the same set gets installed everywhere:
|
||||
|
||||
- **Compilers/tools**: gcc, g++, make, cmake, clang tooling, lldb, gdb, .NET SDK 8.0, Go, nodejs/npm, python3-pip
|
||||
- **CLI tools**: ripgrep, fd, git, curl, wget, unzip, fish (used only for Neovim's embedded terminal — see [Terminal](#terminal)), and the MariaDB *client* (`mariadb`; client only, no server — see [Database (MariaDB)](#database-mariadb))
|
||||
@@ -82,6 +144,7 @@ config/nvim/
|
||||
│ ├── lsp.lua nvim-lspconfig + Mason
|
||||
│ ├── completion.lua nvim-cmp + LuaSnip
|
||||
│ ├── database.lua vim-dadbod + UI + completion (MariaDB)
|
||||
│ ├── multicursor.lua multicursor.nvim (multiple cursors)
|
||||
│ ├── dap.lua nvim-dap + UI
|
||||
│ └── … telescope, nvim-tree, bufferline, lualine, and so on
|
||||
├── config/lsp/ helper modules that are *not* plugin specs
|
||||
@@ -156,6 +219,44 @@ Once installed, launch the desktop app with `neovide` from a terminal — if tha
|
||||
| `<leader>se` | Normal | Equalize split sizes |
|
||||
| `<leader>sx` | Normal | Close current split |
|
||||
|
||||
## Multiple cursors (`multicursor.nvim`)
|
||||
|
||||
[`multicursor.nvim`](https://github.com/jake-stewart/multicursor.nvim) (`lua/plugins/multicursor.lua`). The idea: add cursors, then use Vim normally — motions, operators, insert mode, macros and undo all act on every cursor at once. `<Esc>` collapses back to a single cursor.
|
||||
|
||||
The everyday actions sit on Ctrl keys (VS Code-style); the rest live under a `<leader>m` "Multicursor" group, so they show up in the which-key popup. These differ from the plugin's own README example on purpose — its `<leader>n/s/S/x` would collide with the `<leader>s…` Splits group, and bare `<Up>`/`<Down>` are ordinary movement here.
|
||||
|
||||
**Adding cursors**
|
||||
|
||||
| Key | Mode | Action |
|
||||
|---|---|---|
|
||||
| `<C-n>` / `<C-p>` | Normal/Visual | Add a cursor at the next / previous match of the word under the cursor (or of the visual selection) — like Ctrl+D in VS Code |
|
||||
| `<C-Down>` / `<C-Up>` | Normal/Visual | Add a cursor on the line below / above |
|
||||
| `<C-LeftMouse>` | Normal | Add or remove a cursor by clicking; `Ctrl`+drag adds a column of them |
|
||||
| `<C-q>` | Normal/Visual | Disable the cursors so only the main one moves; press it again to drop a cursor where the main one is, so move → `<C-q>` → move → `<C-q>` places cursors anywhere. `<Esc>` re-enables them. (This shadows `<C-q>` as the alias for `<C-v>`; `<C-v>` itself is untouched.) |
|
||||
| `ga{motion}` | Normal/Visual | Add a cursor on every line of the motion — `gaip` for a paragraph; in Visual mode, every selected line |
|
||||
| `<leader>ma` | Normal/Visual | Add cursors at **all** matches of the word/selection in the file |
|
||||
| `<leader>ms` / `<leader>mS` | Normal/Visual | Skip the next / previous match (jump there without adding a cursor) |
|
||||
| `<leader>mj` / `<leader>mk` | Normal/Visual | Skip the line below / above (move the main cursor without adding one) |
|
||||
| `<leader>mr` | Normal | Bring the cursors back if you cleared them by accident |
|
||||
| `I` / `A` | Visual | Insert at the start / append at the end of every selected line — like block-selection `I`/`A`, but for any selection |
|
||||
|
||||
**Managing cursors** (these only exist while there is more than one cursor)
|
||||
|
||||
| Key | Mode | Action |
|
||||
|---|---|---|
|
||||
| `<leader>mh` / `<leader>ml` | Normal/Visual | Make the previous / next cursor the main one |
|
||||
| `<leader>mx` | Normal/Visual | Delete the main cursor, keeping the rest |
|
||||
| `g<C-a>` / `g<C-x>` | Normal/Visual | Increment / decrement treating the cursors as one sequence (1, 2, 3, … down a column) |
|
||||
| `<Esc>` | Normal | Re-enable disabled cursors, otherwise collapse to one (also clears the search highlight, like the global `<Esc>`) |
|
||||
|
||||
Typical uses: `<C-n>` a few times on a variable name, then `ciw` to rename those occurrences; `Vjjj` + `A` to append to several lines; `<leader>ma` then `cw` to rename every occurrence; `gaip` then `I` to prefix a whole paragraph.
|
||||
|
||||
Notes:
|
||||
|
||||
- The cursors appear as reversed-color blocks (`MultiCursorCursor`); the main cursor is the one your terminal / Neovide draws.
|
||||
- Some terminals and window managers intercept `Ctrl`+click or `Ctrl`+arrow chords. `<C-n>` and `<C-q>` depend on neither.
|
||||
- The plugin lists autocompletion as supported, but it can only replay snippets expanded through Neovim's built-in `vim.snippet.expand`, and this config's snippets come from LuaSnip via nvim-cmp (as does the custom insert-mode `<CR>` comment continuation) — so if completion, snippets or Enter behave oddly with several cursors, press `<Esc>` to collapse back to one and do that part with a single cursor.
|
||||
|
||||
## Look & feel
|
||||
|
||||
- **Theme**: [`vscode.nvim`](https://github.com/Mofiqul/vscode.nvim) (dark variant, VS Code Dark+ palette), on a near-black `#090909` background (explorer, tabs, statusline and popups use near-black shades too, not VS Code's grays), with macros in Visual Studio's muted purple (`#BEB7FF`) and custom tinted backgrounds for error/warn/info/hint diagnostic virtual lines. lualine uses the plugin's own `vscode` theme.
|
||||
@@ -311,6 +412,8 @@ Default launch configs prompt for a path to the executable, or let you attach to
|
||||
|
||||
Neovim's embedded terminal launches **fish** instead of your login shell, purely for its built-in inline "ghost text" suggestions for paths and command history (no config needed, accept with `→`/`End`) — a terminal-side equivalent of the completion ghost text above, since a `:terminal` buffer is a raw PTY that `nvim-cmp` has no visibility into. Your actual system login shell is untouched.
|
||||
|
||||
On **Windows** there is no native fish, so the embedded terminal launches **PowerShell 7** (`pwsh`) instead — PSReadLine's grey inline prediction from your command history is on by default there, which is the same idea — falling back to Windows PowerShell if `pwsh` isn't installed.
|
||||
|
||||
## Git
|
||||
|
||||
`gitsigns` shows added/changed/removed lines in the sign column against the current git state.
|
||||
@@ -388,6 +491,27 @@ The mapping also makes sure the buffer is actually loaded in binary mode before
|
||||
|
||||
`<leader>lf` (LSP format) only consumes `.clang-format` — clangd's formatting is pure clang-format and has nothing to do with clang-tidy. `.clang-tidy` is picked up two separate ways: automatically by clangd for live diagnostics (clangd's clang-tidy integration is explicitly enabled via `--clang-tidy`, alongside `--background-index` so checks run against the whole project's semantic info rather than just what's open), and directly by `<leader>lt`, which shells out to the real `clang-tidy --fix` on the file instead of going through clangd. That's a deliberate difference, not an oversight: clangd filters code actions by LSP "kind", and clang-tidy fixes only ever surface from clangd as individual `quickfix` actions — one per diagnostic — never as a single batched "fix everything" action, because clangd doesn't implement the `source.fixAll` kind that would take ([clangd/clangd#1446](https://github.com/clangd/clangd/issues/1446)). Asking for that kind specifically is why this used to just return "No code actions available" no matter what the file contained. Running the actual `clang-tidy` binary sidesteps that entirely and does what the key was always meant to: fix everything the tool can in one pass. See the [LSP table](#lsp--code-intelligence) above for the compile-database caveat that governs how much either `<leader>la` or `<leader>lt` can actually catch.
|
||||
|
||||
## Windows notes
|
||||
|
||||
Everything under `config/nvim/` is shared between Linux and Windows. The handful of places that had Linux assumptions now branch on `vim.fn.has("win32")`, so nothing changes on Linux:
|
||||
|
||||
- **Embedded terminal** — `pwsh` instead of `fish` (`plugins/toggleterm.lua`).
|
||||
- **Clipboard** — the OSC 52 override in `init.lua` (meant for SSH) is skipped on Windows, where Neovim's native clipboard provider is used instead. OSC 52 can't work in Neovide at all, since Neovide isn't a terminal. Neovim's Windows build bundles both `win32yank` (clipboard) and `xxd` (the [hex viewer](#hex-viewer)).
|
||||
- **nvim-tree `gM`** (copy marked files with a regex rename) — Windows has no `cp`, so a Lua recursive copy is used there. One difference: if the target folder already exists, contents are merged into it instead of the source being nested inside it.
|
||||
- **DB UI save location** — `%LOCALAPPDATA%\db_ui\connections.json` instead of `~/.local/share/db_ui/`; still outside both folders the setup script wipes. Still plain text, password included.
|
||||
- **Dashboard "Edit Config"** — opens `init.lua` from wherever Neovim's config actually lives (`:echo stdpath("config")`).
|
||||
- **CMake debug template** — appends `.exe` to the target names (`lua/dap/configurations/cmake.lua`).
|
||||
|
||||
Things worth knowing:
|
||||
|
||||
- **Use the Ninja generator for CMake** — e.g. `cmake -S . -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON`. Multi-config generators (Visual Studio) put binaries under `build\Debug\...`, which the debug template's `build/...` paths don't expect. The template also mentions `scripts/build.sh`, a bash script — run it from Git Bash, or call `cmake` directly.
|
||||
- **MSVC isn't installed.** The setup uses GCC (WinLibs) because it's a single unattended install; if you want `cl.exe`, install the Visual Studio Build Tools yourself.
|
||||
- **Treesitter parsers need a C compiler on `PATH`.** If `:TSInstall` complains, check `gcc --version` in a fresh terminal. The script puts WinLibs' real `bin` folder on your user `PATH` for this reason.
|
||||
- **Fonts:** set your terminal's font face to `JetBrainsMono Nerd Font` (Windows Terminal: Settings → Profiles → Defaults → Appearance) and restart it. Neovide picks the font up from `init.lua` on its own.
|
||||
- **sqls config** lives in your user config folder — on Windows `%APPDATA%\sqls\config.yml` rather than `~/.config/sqls/config.yml` (sqls uses Go's per-OS user config directory; if the file isn't picked up, check the sqls docs). The Unix-socket DSN form from the [Language server (sqls)](#language-server-sqls) section doesn't apply; use TCP. For credentials outside the URL, use a MariaDB option file — see MariaDB's docs for where the Windows client looks.
|
||||
- **`.clang-format` / `.clang-tidy` fallbacks** are in `%USERPROFILE%`, and both tools only walk *upward* from the file being processed — so projects on another drive (`D:\...`) won't pick them up. Copy them to the project, or to that drive's root, if so.
|
||||
- **`MariaDB`**: the client's `bin` folder is added to your user `PATH` if the installer didn't do it. `mariadb --version` in a new terminal confirms it.
|
||||
|
||||
## Known quirks
|
||||
|
||||
- **`nvim-treesitter` is pinned to its `master` branch**, not the current upstream default (`main`). `main` is an incompatible rewrite that removed the `nvim-treesitter.configs` API this config (and most existing configs/plugins) are built on. `master` is kept frozen upstream specifically for this kind of backward compatibility.
|
||||
|
||||
Reference in new issue
Block a user