Neovim Cheatsheet
Sinopsis
Neovim es un editor de texto basado en Vim hiperextensible que pretende refactorizar agresivamente Vim con el fin de simplificar el mantenimiento, permitir la interfaz de usuario avanzada y maximizar la extensibilidad.
Instalación
Administradores de paquetes
# 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
Diferencias básicas de Vim
Mejoras clave
" 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
Configuración
Archivos de configuración
# Neovim config location
~/.config/nvim/init.vim # Vimscript config
~/.config/nvim/init.lua # Lua config
# Check config location
:echo stdpath('config')
Init básico.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 = " "
Init básico.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')
Gestión de plugins
Utilizando vim-plug
" 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
Usando packer.nvim (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)
Protocolo del servidor de idiomas (LSP)
LSP Setup
-- 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 Mappings clave
-- 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
Configuración de TreeSitter
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
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' \\\\},
\\\\})
\\\\})
Integración terminal
Terminal incorporada
" 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 Configuración
-- 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
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
Telescopio Setup
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
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'\\\\}
\\\\},
\\\\}
Características avanzadas
Lua Scripting
-- 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)
Control de salud
" Check Neovim health
:checkhealth
" Check specific provider
:checkhealth provider
:checkhealth nvim-treesitter
:checkhealth telescope
Migración de Vim
Diferencias clave
" 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
Compatibilidad
" 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
Depuración incorporada
" 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 *
Consejos de rendimiento
Optimización
-- 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
Solución de problemas
Cuestiones comunes
" 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
Recursos
- ** Documentación oficial**: neovim.io
- Repositorio de GitHub: github.com/neovim/neovim
- Awesome Neovim: github.com/rockerBOO/awesome-neovim
- Comunidad: reddit.com/r/neovim