
725 - ¿Es este el FUTURO del autocompletado en Neovim?
Transforma Neovim con plugins clave: blink.cmp (autocompletado), LSP, neominimap y tu propia wiki. ¡Maximiza tu productividad!
Hace algunos meses que dejé de utilizar Obisidian como gestor de notas y he vuelto a Neovim, de donde, probablemente, nunca debí salir, como suelen decir. La cuestión es que me siento infinitamente más cómodo trabajando con Neovim. Esto unido a que como te voy contando, estoy muy metido en el tema de programación, han hecho que esté casi mas tiempo en Neovim, que en la terminal, y eso ya es mucho decir. Con el incremento de uso de Neovim, me he puesto un poco mas al día, si cabe, con los plugin que vengo utilizando, he probado algunos nuevos, he desinstalado y he reemplazado. Como te conté en un reciente episodio, esto de la configuración de Neovim, como la de Niri, etc, es un proceso, que sabes cuando empieza, pero no cuando termina. Sin embargo, en esta ocasión, he cambiado uno de los plugin fundamentales, el del autocompletado. Algo que en ningún caso se me pasaba por la cabeza.

Es este el FUTURO del autocompletado en Neovim?
Un poquito de trasfondo
Si eres de los que sigues el podcast, atareao con Linux, o el canal de YouTube, ya estarás hasta harto de oírme decir que Neovim es una de mis herramientas favoritas. La razón para decir esto es sencilla, la capacidad de personalizarlo al extremo. Neovim te permite que tu entorno de trabajo se adapta a ti en lugar de al revés. Lo mismo que me sucede con Linux o con Niri, el gestor de ventanas que estoy utilizando actualmente.
La cuestión es que cuanto mas tiempo pasas en Neovim, mas tiempo inviertes en adecentarlo. En ir modificando poco a poco Neovim, puliendo pequeños detalles, o cambiando la configuración para adaptarlo mejor a su flujo de trabajo. Como te decía, es un proceso que empieza pero no sabes cuando termina.
Así, en estas últimas semanas he ido reemplazando algunos de los plugin que he estado utilizando hasta el momento. Algunos de esos plugins que inicialmente pensaba que serían completamente irremplazables, como por ejemplo el del autocompletado, han sido sustituidos por otros que me ofrecen una mejor experiencia de usuario.
El autocompletado
El primero de los plugin del que te quiero hablar es blink. Este plugin es el que ha venido a reemplazar al clásico nvim-cmp
, el que es considerado el estándar de facto para el autocompletado.
Sin lugar a dudas, el autocompletado es fundamental, ya sea que te dediques a programar, a escribir, o prácticamente a cualquier cosa que quieras hacer con Neovim, o con cualquier editor, hoy en día.
Te preguntarás porque reemplazo nvim-cmp
, pues simplemente por otros plugins. En los últimos tiempos ando probando, sobre todo, complementos de IA, y lo que he visto es que muchos han empezado a reemplazar al que yo usaba por este.
Sin embargo, nvim-cmp
, lo llevo utilizando bastante tiempo, y lo cierto es que funcionaba bien, salvo el problema de la integración. Y esto de que me estuviera funcionando ha sido básicamente el mayor obstáculo para decidirme por probar blink
, y al final ha sido un acierto, porque he conseguido un mejor integración que la que tenía con nvim-cmp
.
En algún sitio he leído que la configuración de blink
es mas sencilla que la de nvim-cmp
, y puede ser que sea algo mas sencilla, pero vamos, que no es una bicoca. En cualquier caso, una vez que lo tienes funcionando, la experiencia de usuario es mucho mejor, o por lo menos es lo que a mi me parece.
Tengo que decirte, que finalmente no me he quedado con ninguna de los complementos de IA que he probado, pero si que he conseguido una mejor experiencia de autocompletado, así que, definitivamente, se queda conmigo.
Mi configuración de blink
la puedes ver en mis dotfiles. Pero, te la dejo aquí también para tu comodidad,
return {
'saghen/blink.cmp',
-- optional: provides snippets for the snippet source
dependencies = {
"rafamadriz/friendly-snippets",
"mikavilpas/blink-ripgrep.nvim",
"fang2hou/blink-copilot",
"onsails/lspkind.nvim",
"saghen/blink.compat",
},
-- use a release tag to download pre-built binaries
version = '1.*',
-- AND/OR build from source, requires nightly: https://rust-lang.github.io/rustup/concepts/channels.html#working-with-nightly-rust
-- build = 'cargo build --release',
-- If you use nix, you can build from source using latest nightly rust with:
-- build = 'nix run .#build-plugin',
---@module 'blink.cmp'
opts = {
cmdline = { enabled = true },
fuzzy = {
implementation = "prefer_rust_with_warning",
sorts = {
"exact",
"score",
"sort_text"
}
},
keymap = {
['<tab>'] = { 'select_and_accept', 'fallback' },
['<CR>'] = { 'select_and_accept', 'fallback' }
},
sources = {
default = { "minuet", "copilot", "lsp", "path", "snippets", "buffer", "ripgrep" },
providers = {
minuet = {
name = 'minuet',
module = 'minuet.blink',
async = true,
-- Should match minuet.config.request_timeout * 1000,
-- since minuet.config.request_timeout is in seconds
timeout_ms = 3000,
score_offset = 50, -- Gives minuet higher priority among suggestions
},
copilot = {
name = "copilot",
module = "blink-copilot",
score_offset = 100,
async = true,
transform_items = function(_, items)
for _, item in ipairs(items) do
item.kind_icon = ''
item.kind_name = 'Copilot'
end
return items
end
},
ripgrep = {
module = "blink-ripgrep",
name = "Ripgrep",
-- see the full configuration below for all available options
---@module "blink-ripgrep"
opts = {},
},
buffer = {
opts = {
-- get all buffers, even ones like neo-tree
-- get_bufnrs = vim.api.nvim_list_bufs
-- or (recommended) filter to only "normal" buffers
get_bufnrs = function()
return vim.tbl_filter(function(bufnr)
return vim.bo[bufnr].buftype == ''
end, vim.api.nvim_list_bufs())
end
}
}
},
},
appearance = {
-- Blink does not expose its default kind icons so you must copy them all (or set your custom ones) and add Copilot
kind_icons = {
Copilot = "",
}
},
signature = { enabled = true },
completion = {
documentation = {
auto_show = true,
auto_show_delay_ms = 500,
window = { border = "single" },
},
ghost_text = {
enabled = true,
},
trigger = {
--show_on_keyword = true,
prefetch_on_insert = false
},
list = {
selection = { preselect = true, auto_insert = true }
},
menu = {
border = "single",
draw = {
padding = { 1, 1 }, -- padding only on right side
treesitter = { "lsp" },
columns = { { "kind_icon" }, { "label", gap = 1 } },
components = {
kind_icon = {
text = function(ctx)
local icon = ctx.kind_icon
if vim.tbl_contains({ "Path" }, ctx.source_name) then
local dev_icon, _ = require("nvim-web-devicons").get_icon(ctx.label)
if dev_icon then
icon = dev_icon
end
elseif ctx.source_name == "copilot" then
icon = "😺"
elseif ctx.source_name == "Ripgrep" then
icon = "🔍"
elseif ctx.source_name == "minuet" then
icon = "💃🏻"
else
icon = require("lspkind").symbolic(ctx.kind, {
mode = "symbol",
})
end
return icon .. ctx.icon_gap
end,
-- Optionally, use the highlight groups from nvim-web-devicons
-- You can also add the same function for `kind.highlight` if you want to
-- keep the highlight groups in sync with the icons.
highlight = function(ctx)
local hl = ctx.kind_hl
if vim.tbl_contains({ "Path" }, ctx.source_name) then
local dev_icon, dev_hl = require("nvim-web-devicons").get_icon(ctx.label)
if dev_icon then
hl = dev_hl
end
end
return hl
end,
},
label = {
text = function(ctx)
return require("colorful-menu").blink_components_text(ctx)
end,
highlight = function(ctx)
return require("colorful-menu").blink_components_highlight(ctx)
end,
},
}
}
}
}
},
opts_extend = { "sources.default" }
}
Dicho esto, no tengo nada claro, pero que nada claro, que este vaya a ser la solución de autocompletado definitiva, ni mucho menos. Es mas, cada día que pasa, lo que tengo claro es que el autocompletado terminará por ser algo integrado en el propio Neovim.
LSP
Desde hace ya algunas versiones que Neovim es compatible con el Protocolo de servidor de Lenguage (LSP), lo que significa que Neovim funciona como un cliente para los servidores LSP e incluye un framework en Lua llamado vim.lsp
para crear herramientas mejoras.
El LSP facilite funciones como ir a la definición, encontrar referencias, autocompletado, resaltar símbolos, formateo de código, y mucho más, todo ello de una manera estandarizada y consistente a través de diferentes lenguajes de programación.
Hasta la fecha, he estado utilizando distintos complementos para conseguir toda la funcionalidad necesaria. Pero, he visto que no es necesario nada de esto, de forma que he hecho una auténtica limpieza, y me he quedado únicamente con los archivos de configuración necesarios para los lenguajes que actualmente estoy utilizando, y que visto lo visto voy a tener que ir modificando, poco a poco (como de costumbre).
Así, ahora la estructura de los archivos de configuración de LSP, es un primer archivo, lsp.lua
, que se encuentra dentro del directorio lua
, y en ~/.config/nvim/lsp
se encuentran todos los archivos de configuración correspondientes a cada uno de los LSP.
El método Zettelkasten
Bueno, realmente ya no es tanto el método Zettelkasten, porque era mas bien la herramienta que estaba utilizando hasta hace unos meses y que la he reemplazado por lervag/wiki.vim
. Esta es una herramienta fundamental, porque como te contado en alguna que otra ocasión, utilizo Neovim para gestionar mis notas, y wiki.vim
es la herramienta que me permite hacerlo de una manera sencilla y eficaz.
Mas o menos esto es lo mismo que lo que tienes con Obsidian pero de una manera mucho mas simplificada.
Justo estaba escuchando precisamente el último episodio de Sobre la marcha, titulado Vuelvo a Obsidan, y no es por las Bases, en el que el mencionaba su regreso desde LogSeq a Obsidian, y me resultó muy curiosa la coincidencia.
El Mini mapa
Algo que llevaba pendiente hacer en Neovim desde hace tiempo, era el tener un mini mapa, algo que me permitiera tener una visión general del archivo que estoy editando. Creo que en algunas ocasiones he incorporado alguno, pero te puedo asegurar que ninguno como el que tengo ahora mismo, Isrothy/neominimap.nvim
.
Es muy sencillo, tremendamente fácil de configurar y que te da gusto eso que comento, un minimapa.
Más información,