I finally started learning vim, or neovim to be specific, and while to be honest I’m still struggling to learn all the ins and outs of this stupidly extensible editor, I think I’ve found a strong starting setup for my needs. This is largely based on ThePrimeagen’s 0 to LSP video tutorial, where he walks you through the most basic starting setup with lsp, after which you can take it as far as you need, really.

Caution

Please note however, that ThePrimeagen’s 0 to LSP video is outdated as of my writing this article, and you will likely need some extra googling + research to figure out the changes in his current nvim dotfiles. Notably, there is lazy.nvim integration now and I’m not personally aware of the extent of remaining compatibility with packer as of today, although I am still using it as my package manager for this setup.

How to set-up

Pre-requisites:

  • Neovim >= 0.9.0
  • Node.js >= 16.x (for LSP servers)
  • ripgrep (for telescope grep)
  • A C compiler (for treesitter)
  • packer.nvim
  • [Optional] A Nerd font (for icons)

LSP Servers

The following LSP servers will be automatically installed via Mason:

  • TypeScript (ts_ls)
  • Vue (volar)
  • ESLint
  • Rust Analyzer

Platform-Specific Installation

Windows

  1. Install Neovim and core CLIs:
winget install Neovim.Neovim
# or
choco install neovim
 
winget install Git.Git
winget install OpenJS.NodeJS.LTS
winget install Python.Python.3.12
winget install BurntSushi.ripgrep.MSVC
winget install sharkdp.fd
winget install junegunn.fzf
 
# C/C++ build tools (needed for Treesitter & native plugins)
# Either MSVC Build Tools OR MinGW-w64:
winget install Microsoft.VisualStudio.2022.BuildTools
# OR
# choco install mingw
  1. Create configuration directory:
mkdir ~\AppData\Local\nvim
  1. Clone repository:
git clone https://github.com/akashbagchi/dotfiles.git ~\AppData\Local\nvim
  1. Install Packer:
git clone https://github.com/wbthomason/packer.nvim "$env:LOCALAPPDATA\nvim-data\site\pack\packer\start\packer.nvim"
  1. First neovim launch + setup
# Open nvim
nvim .
 
# Inside nvim, do
:so %LOCALAPPDATA%\nvim\init.lua
:PackerSync
:TSUpdate
:Mason

macOS/Linux

  1. (Optional) Nuke old neovim state:
rm -rf ~/.local/share/nvim ~/.local/state/nvim ~/.cache/nvim
  1. Install Neovim & core CLIs:
# macOS
brew install neovim ripgrep fd fzf git node python@3.12
 
# Linux
sudo apt install neovim  # Debian/Ubuntu
sudo dnf install neovim  # Fedora

Also install a Nerd Font for icons (eg: JetBrainsMono Nerd Font), and set it as your terminal’s font.

  1. Create configuration directory:
mkdir -p ~/.config/nvim
  1. Clone repository:
git clone https://github.com/akashbagchi/dotfiles.git ~/.config/nvim
  1. Install Packer:
git clone --depth 1 https://github.com/wbthomason/packer.nvim\
 ~/.local/share/nvim/site/pack/packer/start/packer.nvim
  1. First neovim launch + sourcing order:
# Open neovim
nvim
 
# Inside neovim, do this in order
:so ~/.config/nvim/lua/theprimagen/packer.lua
:so ~/.config/nvim/init.lua
:PackerSync
:TSUpdate
:Mason
 
# Anytime you edit your config hereafter:
:so ~/.config/nvim/init.lua

Platform-Specific Configuration Changes

For Windows Users

  1. In lua/theprimeagen/remap.lua, uncomment Windows keybindings and comment out Mac ones:
-- Uncomment these lines for Windows
vim.keymap.set('n', '<C-/>', 'gcc', { remap = true })
vim.keymap.set('v', '<C-/>', 'gc', { remap = true })
 
-- Comment out these lines on Windows
-- vim.keymap.set('n', '<D-/>', 'gcc', { remap = true })
-- vim.keymap.set('v', '<D-/>', 'gc', { remap = true })
  1. In after/plugin/lsp.lua, adjust completion keybindings:
local cmp_mappings = lsp.defaults.cmp_mappings({
    -- Uncomment these for Windows
    ['<C-p>'] = cmp.mapping.select_prev_item(cmp_select),
    ['<C-n>'] = cmp.mapping.select_next_item(cmp_select),
    ['<C-y>'] = cmp.mapping.confirm({ select = true }),
    ["<C-Space>"] = cmp.mapping.complete(),
 
    -- Comment these out for Windows
    -- ['<D-p>'] = cmp.mapping.select_prev_item(cmp_select),
    -- ['<D-n>'] = cmp.mapping.select_next_item(cmp_select),
    -- ['<D-y>'] = cmp.mapping.confirm({ select = true }),
    -- ["<D-Space>"] = cmp.mapping.complete(),
})

For macOS Users

  1. The configuration is already set up for macOS key bindings (<D-/> for comments, etc.)
  2. Ensure your terminal emulator (iTerm2, Terminal.app, etc.) is set up to use your installed Nerd Font
  3. For Volar LSP to work correctly, update the TypeScript SDK path in lsp.lua:
lspconfig.volar.setup({
    init_options = {
        typescript = {
            tsdk = vim.fn.expand('~/node_modules/typescript/lib')
            -- or globally installed TypeScript:
            -- tsdk = '/usr/local/lib/node_modules/typescript/lib'
        }
    }
})

Additional Platform-Specific Notes

Windows

  • Some plugins (like telescope.nvim) might work better with PowerShell or Git Bash than CMD
  • If using WSL, consider installing Neovim inside WSL for a better Unix-like experience
  • The <C-f> mapping for tmux-sessionizer won’t work by default; you’ll need to adjust or remove it

macOS

  • The Command key mappings (<D->) work in GUI Neovim (Neovide, VimR) but might need adjustments in terminal Neovim
  • For optimal performance, consider using a modern terminal emulator like Alacritty or Kitty

Key Features

File Navigation

  • NvimTree: File explorer
  • Telescope: Fuzzy finder
  • Harpoon: Quick file navigation

Development

  • LSP integration with zero-lsp
  • Treesitter for syntax highlighting
  • Auto-completion
  • Git integration via Fugitive
  • Comment.nvim for code commenting
  • Refactoring tools
  • Trouble for error diagnostics

Focus & Productivity

  • Zen Mode
  • Undotree
  • Custom status line

Key Mappings

General

  • <Space> - Leader key
  • <leader>pf - Find files
  • <C-p> - Git files
  • <leader>ps - Grep search
  • <leader>e - Toggle NvimTree
  • <leader>fe - Focus NvimTree

LSP

  • gd/gD/gr/gi - Go to definition/declaration/references/implementation
  • K - Hover documentation
  • <leader>vws - Workspace symbol search
  • <leader>vd - Open diagnostic float
  • [d / ]d - Previous/Next diagnostic
  • <leader>vca - Code action
  • <leader>vrr - Show references
  • <leader>vrn - Rename

Git (Fugitive)

  • <leader>gs - Git status
  • <leader>p - Git push (in fugitive buffer)
  • <leader>P - Git pull —rebase (in fugitive buffer)

Editing

  • J/K in visual mode - Move lines up/down
  • <leader>y - Yank to system clipboard
  • <leader>d - Delete to void register
  • <D-/> (Mac) - Toggle line comment
  • <A-S-a> - Toggle block comment
  • <C-d>/<C-u> - Scroll down/up (centered)
  • <C-h/t/n/s> - Navigate to Harpoon marks 1-4
  • <C-e> - Toggle Harpoon quick menu
  • zz/zt/zb - Recenter, scroll to top, scroll to bottom of screen
  • H/M/L - Move to top/middle/bottom of visible screen
  • } / { - Move forward/backward by paragraph
  • ]] / [[ - Jump to next/prev function/class

Focus Mode

  • <leader>zz - Toggle Zen Mode (with numbers)
  • <leader>zZ - Toggle Zen Mode (minimal)

Important Notes

  1. LSP Setup:
    • TypeScript/JavaScript LSP is configured for relative imports
    • ESLint will auto-fix on save
    • Vue support requires TypeScript in your project
  2. File Types:
    • Special handling for .env files via Cloak plugin
    • Treesitter ensures syntax highlighting for major languages
  3. Platform Specific:
    • Some keybindings are Mac-specific (e.g., <D-/> for comments)
    • Undo directory is set to Windows path (%LOCALAPPDATA%)
  4. Performance:
    • Auto-install of TreeSitter parsers is enabled
    • Swap files are disabled, but persistent undo is enabled
    • UpdateTime is set to 50ms for responsive git signs

Customization

Most configurations are modular and can be found in:

  • lua/theprimeagen/set.lua - Basic Vim settings
  • lua/theprimeagen/remap.lua - Key mappings
  • after/plugin/ - Plugin-specific configurations

Troubleshooting

If you encounter issues:

  1. Run :checkhealth to verify requirements
  2. Ensure all prerequisites are installed
  3. Try :PackerSync to update plugins
  4. Check LSP status with :LspInfo

See Also: