Saltar a contenido

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