My personal development environment for WSL/Linux. Covers Vim and Bash configuration, language-specific tooling, and a debugging setup powered by Vimspector.
| File | Description |
|---|---|
vimrc |
Vim config |
bashrc |
Bash config |
shortcuts.txt |
Quick reference for all shortcuts and commands |
setupscripts/envsetup |
Setup script for new machines |
setupscripts/lang_go.sh |
Go language setup |
setupscripts/lang_python.sh |
Python language setup |
setupscripts/lang_sh.sh |
Shell language setup |
setupscripts/lang_c.sh |
C language setup |
setupscripts/lang_cpp.sh |
C++ language setup |
setupscripts/lang_markdown.sh |
Markdown language setup |
| Section | Description |
|---|---|
| First-Time Setup | Everything needed to get the environment running on a new machine |
| Language Setup | Per-language install steps, tooling, and shortcuts |
| Debugging | How the Vimspector debugger works and how to use it |
| Daily Reference | Shortcuts, aliases, and UI reference for everyday use |
| Maintenance | How to push and pull config changes across machines |
The steps below are the full manual reference. If you prefer an automated setup, see envsetup which handles all of this interactively.
This repo can be cloned anywhere. The example below uses VIMFILES_PATH. Substitute with your actual path
git clone https://github.com/vit-ui/vimfiles.git VIMFILES_PATHThis setup requires a recent Vim build. If your system ships an older version, upgrade it:
sudo add-apt-repository ppa:jonathonf/vim && sudo apt update && sudo apt install vimInstall Node.js via nvm (Node Version Manager — installs Node without sudo and works on all platforms):
NVM_VER=$(curl -sL https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VER}/install.sh" | bash
source ~/.nvm/nvm.sh
nvm install --lts
nvm alias default lts/*Vim and Bash look for .vimrc and .bashrc in your home directory. Link them from this repo so your config
stays version-controlled:
ln -sf VIMFILES_PATH/vimrc ~/.vimrc
ln -sf VIMFILES_PATH/bashrc ~/.bashrc
source ~/.bashrcThese are symbolic links — the actual files stay in this repo. Any edit to
~/.vimrcis really an edit toVIMFILES_PATH/vimrc, which you can then commit and push. Runsource ~/.bashrcafter linking to apply bash changes to the current terminal session without restarting it.
vim-plug is the plugin manager. Install it:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vimThen open Vim and run:
:PlugInstallOn the first open, Vim automatically creates and configures
~/.gitignore_globalto ignoretagsfiles and.vimspector.json(the per-project debugger config file).
Universal Ctags — generates tag files for code symbol navigation, required by the Gutentags plugin:
sudo apt install universal-ctagsshellcheck — static analysis tool for shell scripts, used by coc-sh for diagnostics in .sh and .bashrc
files:
sudo apt install shellcheckglow — terminal Markdown renderer, used by :Preview and \mp:
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install glowmdless — terminal Markdown renderer used by envsetup info and the setupdocs alias (renders headings and
links properly):
sudo apt install ruby-full
sudo gem install mdlessIf you ran envsetup init, this is done automatically. If you are doing the setup manually:
sudo ln -sf VIMFILES_PATH/setupscripts/envsetup /usr/local/bin/envsetupA fast file content search tool that replaces grep for code search. Used with rg in the terminal:
sudo apt install ripgrepCommand-line interface for GitHub operations (creating pull requests, cloning repos, etc.). Not required for the environment to work.
Via webi (gets latest version):
curl -sS https://webi.sh/gh | shVia apt (auto-updates with apt upgrade):
sudo apt install ghAuthenticate after installing:
gh auth loginenvsetup is a setup script that automates the First-Time Setup steps above. It is interactive, idempotent
(safe to re-run), and works on apt, dnf, pacman, and brew systems.
On first run, call it directly from the repo:
VIMFILES_PATH/setupscripts/envsetup initAfter that, envsetup is available from anywhere on the system.
envsetup init # First-time setup — interactive
envsetup lang go # Set up Go (also: python, markdown)
envsetup info # Open this README with mdless
envsetup help # Show usageenvsetup init walks you through the same steps as First-Time Setup above, asking which languages and
optional tools to install. Each step checks if it is already done and skips it if so.
envsetup lang <n> sets up a single language at any time after init — useful when you want to add a language
later without re-running the full setup.
- Per-project debugger setup — run
:InstallDebugger <adapter>in Vim from your project root when needed. See Debugging.
All languages format automatically on save via CoC. No manual step is needed when adding a new language — install its CoC extension and formatter and formatting will work on save automatically.
Go
- Go binary
- Delve (the Go debugger binary — must be installed manually, see step 3)
The script below fetches the latest stable release from Go's API, detects your CPU architecture, and installs
to /usr/local/go:
GO_VER=$(curl -s "https://go.dev/dl/?mode=json" \
| grep -o '"version":"go[^"]*"' | head -1 | cut -d'"' -f4)
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -Lo "/tmp/${GO_VER}.linux-${ARCH}.tar.gz" \
"https://go.dev/dl/${GO_VER}.linux-${ARCH}.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "/tmp/${GO_VER}.linux-${ARCH}.tar.gz"
rm "/tmp/${GO_VER}.linux-${ARCH}.tar.gz"Alternatively, download the .tar.gz manually from go.dev/dl and run:
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go_XX.X.tar.gzVerify:
go versionThe Go binary directories are already in PATH via .bashrc.
Inside Vim:
:GoUpdateBinariesThis installs gopls (the Go language server) and other vim-go tooling using go install internally.
Delve is the Go debugger binary. Vimspector's delve adapter is a config layer that tells Vimspector how to
talk to Delve via DAP (Debug Adapter Protocol — a standard interface between editors and debuggers) — it does
not download the binary itself. Install it manually:
go install github.com/go-delve/delve/cmd/dlv@latestNavigate to your project root and open Vim:
cd ~/my-project
vim .Then run:
:InstallDebugger delveWhen launching a debug session with \gc, Vimspector prompts for ${program}. Enter the path to your entry
point, e.g. . or ./cmd/myapp.
See Debugging for how this works.
| Command/Shortcut | Description |
|---|---|
\r |
Run current file |
\t |
Run tests |
:GoAddTags |
Add JSON tags to struct fields |
Python
- Python 3 and pip
- pipx (tool manager for Python CLI programs)
- black (formatter)
- debugpy (downloaded automatically by
:InstallDebugger debugpy, see step 3)
They may already be present. Check:
python3 --version
pip --versionIf missing:
sudo apt install python3 python3-pippipx installs Python CLI tools each in their own isolated environment, while still exposing the binary
globally on your PATH. This avoids polluting the system Python without needing flags like
--break-system-packages:
sudo apt install pipx
pipx ensurepathInstall black (the formatter called on save for Python files):
pipx install blackVerify:
black --versionNavigate to your project root and open Vim:
cd ~/my-project
vim .Then run:
:InstallDebugger debugpyWhen launching a debug session with \gc, Vimspector prompts for ${program}. Enter the path to your entry
point, e.g. main.py or ./src/main.py.
Unlike Delve for Go, debugpy is a pure Python package — Vimspector downloads it directly from GitHub into its gadgets directory. No separate binary install is needed.
See Debugging for how this works.
| Command/Shortcut | Description |
|---|---|
\r |
Run current file with Python 3 |
Shell
- shellcheck (linter — installed in First-Time Setup step 5, used by coc-sh
for diagnostics in
.shand.bashrcfiles)
coc-sh handles Markdown automatically after :PlugInstall and is listed in
g:coc_global_extensions in vimrc — it installs automatically on next Vim open.
Note: Vim detects bash/sh filetype from the shebang line (
#!/usr/bin/env bash), so files without a.shextension (likeenvsetup) get full syntax highlighting and LSP support automatically.
Bash debugging via Vimspector uses vscode-bash-debug. Navigate to your
project root and run:
:InstallDebugger vscode-bash-debugThe generated .vimspector.json needs extra fields that the generator does
not add. After running it, open .vimspector.json and add these fields inside
the configuration block:
"pathBash": "bash",
"pathBashdb": "~/.vim/plugged/vimspector/gadgets/linux/vscode-bash-debug/bashdb_dir/bashdb",
"pathCat": "cat",
"pathMkfifo": "mkfifo",
"pathPkill": "pkill"For simple scripts, set -x at the top of the file is often enough — it
prints every command before it runs.
| Command/Shortcut | Description |
|---|---|
\r |
Run current file with bash |
C
- clangd (language server)
- clang-format (formatter)
- gcc (compiler)
coc-clangd is listed in g:coc_global_extensions in vimrc and installs
automatically on next Vim open. It connects CoC to clangd for LSP features
(completion, go-to-definition, diagnostics, hover).
Navigate to your project root and run:
:InstallDebugger CodeLLDBWhen launching a debug session with \gc, Vimspector prompts for ${program}.
Enter the path to the compiled binary, e.g. ./myapp.
Note: you must compile with debug symbols first (gcc -g). \r compiles
without them for quick runs — use a Makefile or compile manually for
debugging.
| Command/Shortcut | Description |
|---|---|
\r |
Compile and run current file with gcc |
C++
- clangd (language server — same binary as C, handles both)
- clang-format (formatter — same binary as C)
- g++ (compiler)
coc-clangd handles both C and C++ — no separate server or extension needed.
Same as C — navigate to your project root and run:
:InstallDebugger CodeLLDBEnter the path to the compiled binary when prompted.
| Command/Shortcut | Description |
|---|---|
\r |
Compile and run current file with g++ |
Markdown
- glow (terminal Markdown renderer — installed in First-Time Setup step 5, used by
:Previewand\mpin Vim) - mdless (README viewer — installed in First-Time Setup step 5, used by
envsetup infoandsetupdocs)
Three CoC extensions handle Markdown automatically after :PlugInstall: coc-markdownlint (lints style
violations as you type and on save), coc-prettier (formats prose on save), and coc-marksman (a Markdown
language server that enables \d and \fr on internal document links between .md files).
| Command/Shortcut | Description |
|---|---|
\mp |
Open rendered preview in a terminal split |
:Preview |
Same as \mp |
Debugging is powered by Vimspector using DAP (Debug Adapter Protocol — a standard interface between editors and language-specific debuggers). Vimspector acts as the DAP client: it sends commands (set breakpoint, step over, etc.) and the language-specific debugger executes them.
There are two separate components per language:
- The debugger — the actual program doing the debugging. Whether Vimspector downloads this or you install it manually depends on what the debugger is. See each language block above for details.
- The Vimspector gadget — a config layer that tells Vimspector how to launch and communicate with that
debugger. This is what
:InstallDebuggerinstalls.
:InstallDebugger is a custom command defined in .vimrc. It does two things:
- Runs
:VimspectorInstall <adapter>, which downloads the gadget into~/.vim/plugged/vimspector/gadgets/ - Creates (or merges into) a
.vimspector.jsonin the current directory with a launch configuration for that adapter
It does not install the debugger binary itself in all cases — see each language block for what is and isn't handled automatically.
Must be run from the project root. Navigate there first and open Vim with
vim ., then run:InstallDebugger <adapter>.
Using Go as the reference example, the generated .vimspector.json looks like:
{
"configurations": {
"delve": {
"adapter": "delve",
"filetypes": ["go"],
"configuration": {
"request": "launch",
"program": "${program}",
"args": [],
"cwd": "${workspaceRoot}",
"env": {},
"mode": "debug"
}
}
}
}Run :Format on .vimspector.json to pretty-print it after generation.
When you launch a debug session with \gc, Vimspector prompts for ${program}. The entry point to enter
depends on the language — see the relevant language block in Language Setup.
| Shortcut | Action |
|---|---|
\gb |
Toggle breakpoint |
\gc |
Launch / Continue |
\gn |
Step Over |
\gi |
Step Into |
\go |
Step Out |
\gs |
Stop session |
\gr |
Restart |
\gq |
Hard reset Vimspector |
Default
leaderis\
The full shortcut reference is in shortcuts.txt. Access it with:
:Shortcutsor from the terminal:
shortcutsA few non-obvious ones worth knowing up front:
| Shortcut | What it does |
|---|---|
dd |
Remapped — clears line contents but leaves the empty line |
dl |
Deletes the line entirely (default dd behavior) |
qq |
Exits insert mode (same as <Esc>) |
\d / \b |
Jump into definition / jump back |
\cp / \cn |
Jump to previous / next diagnostic (error or warning) |
The terminal aliases and Git shortcuts are in shortcuts.txt. The custom functions worth knowing by name:
mkcd <dir>— creates a directory and immediately enters itup [n]— go up N directories (e.g.,up 3=cd ../../..)git()— wraps git to printgit statusafter every successful command exceptstatus,help, andpull. Bypass withcommand git <args>.vim()— no arguments opens the current directory in netrw. Multiple arguments open in vertical splits.
| Command | Description |
|---|---|
cdv |
cd to the vimfiles repo |
evim |
Open vimrc, bashrc, and shortcuts.txt in splits |
shortcuts |
Open shortcuts.txt in less for reading |
setupdocs |
Open this README with mdless |
gcp |
git commit && git push in one step |
Status line fields:
| Field | Meaning |
|---|---|
| Filename | Current file path |
[+] |
Unsaved changes |
[RO] |
Read-only file |
% |
File progress |
L:C |
Line and column |
Cursor shape (works in WSL and common Linux terminals):
- Block — Normal mode
- Beam — Insert mode
- Underline — Replace mode
Window navigation — use \h \j \k \l to move between splits. Works inside Vimspector panels and
:terminal buffers as well.
Use when syncing your environment from the repo (e.g., on a new machine after initial setup):
cd VIMFILES_PATH
git pull
source ~/.bashrcsource ~/.bashrc applies any bash changes to the current terminal session without restarting it.
This repo is maintained by the owner. If you want to contribute changes, open a pull request:
1 — Fork the repo
Via GitHub CLI:
gh repo fork vit-ui/vimfiles --clone --remote
cd vimfiles--clone clones your fork locally. --remote adds the original repo as an upstream remote so you can pull
future updates from it.
Via browser: go to github.com/vit-ui/vimfiles and click Fork in the top right.
2 — If you forked via browser, clone your fork manually
git clone https://github.com/YOUR-USERNAME/vimfiles.git VIMFILES_PATH3 — Make your changes, commit, and push to your fork
cd VIMFILES_PATH
git add .
git commit -m "describe your change"
git push4 — Open a pull request
Via GitHub CLI:
gh pr create --title "your title" --body "describe your change"Via browser: go to your fork on GitHub and click Contribute → Open pull request.
If you are the owner pushing directly: switch the remote to SSH (
git remote set-url origin git@github.com:vit-ui/vimfiles.git), push, then switch back to HTTPS if needed.