Neovim configuration lives in ~/.config/nvim/init.lua (Lua) or init.vim (Vimscript). Modern Neovim defaults to Lua, which is more powerful and readable than Vimscript.
~/.config/nvim/
├── init.lua # main config file
├── lua/
│ └── user/
│ ├── settings.lua # options
│ └── keymaps.lua # keybindings
└── after/
└── ftplugin/
└── python.lua # file-type specific
Start simple with just init.lua.
Set options with vim.opt:
-- ~/.config/nvim/init.lua vim.opt.number = true -- show line numbers vim.opt.relativenumber = true -- relative numbers vim.opt.expandtab = true -- spaces, not tabs vim.opt.shiftwidth = 4 -- indent size vim.opt.tabstop = 4 -- tab display width vim.opt.ignorecase = true -- case-insensitive search vim.opt.smartcase = true -- case-sensitive if uppercase in search vim.opt.wrap = false -- no line wrap vim.opt.termguicolors = true -- true color support
Each option corresponds to a :set command (:set number is the ex equivalent of vim.opt.number = true).
-- Set colorscheme (requires plugin or built-in) vim.cmd.colorscheme "slate"
Popular colorschemes: slate, desert, torte (built-in). Plugins like tokyonight, gruvbox add more. Install via plugin manager (see Neovim Plugins).
Basic keymapping:
vim.keymap.set('n', '<Space>w', ':w<CR>') -- save with Space+w vim.keymap.set('n', '<C-s>', ':w<CR>') -- save with Ctrl+s vim.keymap.set('i', 'jk', '<Esc>') -- exit insert with jk
Modes: 'n' (normal), 'i' (insert), 'v' (visual), 'c' (command), 'o' (operator pending).
Options:
vim.keymap.set('n', '<leader>x', ':e<CR>', { noremap = true, silent = true })
noremap — prevent recursion (map to built-in, not other maps)silent — no message in status barbuffer — local to current buffer only
Leader is a custom prefix for personal keybindings (default \). Remap to space (common):
vim.g.mapleader = ' ' vim.g.maplocalleader = ','
Then <leader>e expands to <Space>e.
Lua comments use --:
-- This is a comment
VimScript uses ":
" This is a comment
After editing init.lua, reload with :source ~/.config/nvim/init.lua or restart Neovim.
For development, split config into files (settings.lua, keymaps.lua) and require them:
require('user.settings') require('user.keymaps')
This keeps init.lua clean and modular.