Appearance
Neovim Cheatsheet
Overview
Neovim is a hyperextensible Vim-based text editor that aims to aggressively refactor Vim in order to simplify maintenance, enable advanced UIs, and maximize extensibility.
Installation
Package Managers
bash
# Ubuntu/Debian
sudo apt install neovim
# macOS
brew install neovim
# Arch Linux
sudo pacman -S neovim
# Windows (Chocolatey)
choco install neovim
# From source
git clone https://github.com/neovim/neovim.git
cd neovim && make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make install
Basic Differences from Vim
Key Improvements
vim
" Built-in terminal emulator
:terminal
:term
" Asynchronous job control
:help job-control
" Better default settings
" No need for 'nocompatible'
" Sensible defaults enabled
" Lua scripting support
:lua print("Hello from Lua!")
" Better plugin architecture
" Native LSP support
" TreeSitter integration
Configuration
Configuration Files
bash
# Neovim config location
~/.config/nvim/init.vim # Vimscript config
~/.config/nvim/init.lua # Lua config
# Check config location
:echo stdpath('config')
Basic init.vim
vim
" Enable syntax highlighting
syntax enable
" Line numbers
set number
set relativenumber
" Indentation
set tabstop=4
set shiftwidth=4
set expandtab
set autoindent
set smartindent
" Search
set ignorecase
set smartcase
set incsearch
set hlsearch
" UI improvements
set termguicolors
set signcolumn=yes
set updatetime=300
set timeoutlen=500
" Mouse support
set mouse=a
" Clipboard
set clipboard+=unnamedplus
" Split behavior
set splitbelow
set splitright
" Leader key
let mapleader = " "
Basic init.lua
lua
-- Basic settings
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true
vim.opt.hlsearch = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
vim.opt.updatetime = 300
vim.opt.timeoutlen = 500
vim.opt.mouse = "a"
vim.opt.clipboard = "unnamedplus"
vim.opt.splitbelow = true
vim.opt.splitright = true
-- Leader key
vim.g.mapleader = " "
-- Key mappings
vim.keymap.set('n', '<leader>w', ':w<CR>')
vim.keymap.set('n', '<leader>q', ':q<CR>')
vim.keymap.set('n', '<C-h>', '<C-w>h')
vim.keymap.set('n', '<C-j>', '<C-w>j')
vim.keymap.set('n', '<C-k>', '<C-w>k')
vim.keymap.set('n', '<C-l>', '<C-w>l')
Plugin Management
Using vim-plug
vim
" Install vim-plug
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
" Plugin configuration in init.vim
call plug#begin('~/.local/share/nvim/plugged')
" Essential plugins
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'L3MON4D3/LuaSnip'
Plug 'nvim-telescope/telescope.nvim'
Plug 'nvim-lua/plenary.nvim'
Plug 'kyazdani42/nvim-tree.lua'
Plug 'kyazdani42/nvim-web-devicons'
Plug 'nvim-lualine/lualine.nvim'
call plug#end()
" Install plugins: :PlugInstall
" Update plugins: :PlugUpdate
" Clean plugins: :PlugClean
Using packer.nvim (Lua)
lua
-- Install packer.nvim
local install_path = vim.fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
if vim.fn.empty(vim.fn.glob(install_path)) > 0 then
vim.fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
end
-- Plugin configuration
require('packer').startup(function(use)
use 'wbthomason/packer.nvim'
-- Essential plugins
use {'nvim-treesitter/nvim-treesitter', run = ':TSUpdate'}
use 'neovim/nvim-lspconfig'
use 'hrsh7th/nvim-cmp'
use 'hrsh7th/cmp-nvim-lsp'
use 'L3MON4D3/LuaSnip'
use {'nvim-telescope/telescope.nvim', requires = 'nvim-lua/plenary.nvim'}
use {'kyazdani42/nvim-tree.lua', requires = 'kyazdani42/nvim-web-devicons'}
use 'nvim-lualine/lualine.nvim'
end)
Language Server Protocol (LSP)
LSP Setup
lua
-- Basic LSP configuration
local lspconfig = require('lspconfig')
-- Python
lspconfig.pyright.setup{}
-- JavaScript/TypeScript
lspconfig.tsserver.setup{}
-- Rust
lspconfig.rust_analyzer.setup{}
-- Go
lspconfig.gopls.setup{}
-- C/C++
lspconfig.clangd.setup{}
-- Lua
lspconfig.lua_ls.setup{
settings = {
Lua = {
runtime = {version = 'LuaJIT'},
diagnostics = {globals = {'vim'}},
workspace = {library = vim.api.nvim_get_runtime_file("", true)},
telemetry = {enable = false},
},
},
}
LSP Key Mappings
lua
-- LSP key mappings
vim.keymap.set('n', 'gd', vim.lsp.buf.definition)
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration)
vim.keymap.set('n', 'gr', vim.lsp.buf.references)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation)
vim.keymap.set('n', 'K', vim.lsp.buf.hover)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help)
vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename)
vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action)
vim.keymap.set('n', '<leader>f', vim.lsp.buf.format)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float)
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist)
TreeSitter
TreeSitter Configuration
lua
require'nvim-treesitter.configs'.setup {
-- Install parsers synchronously (only applied to `ensure_installed`)
sync_install = false,
-- Automatically install missing parsers when entering buffer
auto_install = true,
-- List of parsers to install
ensure_installed = {
"c", "lua", "vim", "vimdoc", "query",
"python", "javascript", "typescript", "rust", "go"
},
highlight = {
enable = true,
additional_vim_regex_highlighting = false,
},
indent = {
enable = true
},
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
}
Autocompletion
nvim-cmp Setup
lua
local cmp = require'cmp'
local luasnip = require'luasnip'
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }),
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { 'i', 's' }),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
}, {
{ name = 'buffer' },
})
})
Terminal Integration
Built-in Terminal
vim
" Open terminal
:terminal
:term
" Terminal in split
:split | terminal
:vsplit | terminal
" Terminal key mappings
tnoremap <Esc> <C-\><C-n>
tnoremap <C-h> <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l
Terminal Lua Configuration
lua
-- Terminal configuration
vim.keymap.set('t', '<Esc>', '<C-\\><C-n>')
vim.keymap.set('t', '<C-h>', '<C-\\><C-n><C-w>h')
vim.keymap.set('t', '<C-j>', '<C-\\><C-n><C-w>j')
vim.keymap.set('t', '<C-k>', '<C-\\><C-n><C-w>k')
vim.keymap.set('t', '<C-l>', '<C-\\><C-n><C-w>l')
-- Open terminal in split
vim.keymap.set('n', '<leader>th', ':split | terminal<CR>')
vim.keymap.set('n', '<leader>tv', ':vsplit | terminal<CR>')
File Explorer
nvim-tree Setup
lua
require("nvim-tree").setup({
sort_by = "case_sensitive",
view = {
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = true,
},
})
-- Key mappings
vim.keymap.set('n', '<leader>e', ':NvimTreeToggle<CR>')
vim.keymap.set('n', '<leader>r', ':NvimTreeRefresh<CR>')
vim.keymap.set('n', '<leader>n', ':NvimTreeFindFile<CR>')
Fuzzy Finder
Telescope Setup
lua
require('telescope').setup{
defaults = {
mappings = {
i = {
["<C-n>"] = "move_selection_next",
["<C-p>"] = "move_selection_previous",
["<C-c>"] = "close",
["<Down>"] = "move_selection_next",
["<Up>"] = "move_selection_previous",
["<CR>"] = "select_default",
["<C-x>"] = "select_horizontal",
["<C-v>"] = "select_vertical",
["<C-t>"] = "select_tab",
},
},
},
}
-- Key mappings
vim.keymap.set('n', '<leader>ff', '<cmd>Telescope find_files<cr>')
vim.keymap.set('n', '<leader>fg', '<cmd>Telescope live_grep<cr>')
vim.keymap.set('n', '<leader>fb', '<cmd>Telescope buffers<cr>')
vim.keymap.set('n', '<leader>fh', '<cmd>Telescope help_tags<cr>')
Status Line
Lualine Setup
lua
require('lualine').setup {
options = {
icons_enabled = true,
theme = 'auto',
component_separators = { left = '', right = ''},
section_separators = { left = '', right = ''},
disabled_filetypes = {
statusline = {},
winbar = {},
},
ignore_focus = {},
always_divide_middle = true,
globalstatus = false,
refresh = {
statusline = 1000,
tabline = 1000,
winbar = 1000,
}
},
sections = {
lualine_a = {'mode'},
lualine_b = {'branch', 'diff', 'diagnostics'},
lualine_c = {'filename'},
lualine_x = {'encoding', 'fileformat', 'filetype'},
lualine_y = {'progress'},
lualine_z = {'location'}
},
}
Advanced Features
Lua Scripting
lua
-- Create custom commands
vim.api.nvim_create_user_command('Hello', function()
print('Hello from Neovim!')
end, {})
-- Create autocommands
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.lua",
callback = function()
vim.lsp.buf.format()
end,
})
-- Custom functions
local function toggle_number()
if vim.opt.number:get() then
vim.opt.number = false
vim.opt.relativenumber = false
else
vim.opt.number = true
vim.opt.relativenumber = true
end
end
vim.keymap.set('n', '<leader>tn', toggle_number)
Health Check
vim
" Check Neovim health
:checkhealth
" Check specific provider
:checkhealth provider
:checkhealth nvim-treesitter
:checkhealth telescope
Migration from Vim
Key Differences
vim
" Neovim uses different paths
:echo stdpath('config') " Config directory
:echo stdpath('data') " Data directory
:echo stdpath('cache') " Cache directory
" Better defaults
" No need for 'nocompatible'
" 'autoindent' is on by default
" 'autoread' is on by default
" 'background=dark' by default
" 'belloff=all' by default
" 'cscopeverbose' is on by default
" 'display=lastline' by default
" 'encoding=utf-8' by default
Compatibility
vim
" Most Vim plugins work with Neovim
" Vimscript is fully supported
" Can gradually migrate to Lua
" Check if running Neovim
if has('nvim')
" Neovim-specific configuration
endif
Debugging
Built-in Debugging
vim
" Debug mode
nvim -D file.txt
" Verbose mode
nvim -V9 file.txt
" Check startup time
nvim --startuptime startup.log file.txt
" Profile startup
:profile start profile.log
:profile func *
:profile file *
Performance Tips
Optimization
lua
-- Disable unused providers
vim.g.loaded_python_provider = 0
vim.g.loaded_ruby_provider = 0
vim.g.loaded_perl_provider = 0
vim.g.loaded_node_provider = 0
-- Lazy load plugins
-- Use event-based loading
-- Minimize startup plugins
-- Optimize search
vim.opt.regexpengine = 1
-- Reduce updatetime for better experience
vim.opt.updatetime = 250
Troubleshooting
Common Issues
vim
" Plugin not working
:checkhealth
:PlugStatus
" LSP not working
:LspInfo
:LspLog
" TreeSitter issues
:TSInstallInfo
:TSUpdate
" Clear cache
rm -rf ~/.local/share/nvim
rm -rf ~/.cache/nvim
Resources
- Official Documentation: neovim.io
- GitHub Repository: github.com/neovim/neovim
- Awesome Neovim: github.com/rockerBOO/awesome-neovim
- Community: reddit.com/r/neovim