Saltar al contenido

La terminal integrada

El modo Terminal de Neovim: :terminal, cómo salir con Ctrl-\ Ctrl-n, por qué un terminal es un buffer normal, los autocomandos de TermOpen, y cuándo conviene NO usarlo.

Neovim trae un emulador de terminal dentro. No es un plugin ni un truco: es un tipo de buffer más, con su propio modo. Entender que es un buffer explica todo lo que puedes hacer con él, y también por qué a veces conviene no usarlo.

  • Abrir una terminal y salir de ella sin cerrarla.
  • Por qué un terminal es un buffer y qué se puede hacer con eso.
  • Ajustarlo con TermOpen para que no parezca un fichero.
  • Un terminal flotante que va y viene con una tecla.
  • Cuándo la terminal integrada es la herramienta equivocada.

Abrir y, sobre todo, salir

VIM
:terminal          " abre un shell en el buffer actual:split | terminal  " en una ventana horizontal

Al abrirse, entras en el modo Terminal: lo que teclees va al programa, no a Neovim. Y aquí es donde todo el mundo se queda atrapado la primera vez, porque Esc no te saca: se lo traga el shell.

La combinación que hay que memorizar hoy

Ctrl-\ Ctrl-n sale del modo Terminal a modo Normal.

Es incómoda a propósito: cualquier tecla cómoda se la comería el programa que está corriendo. Si te resulta imposible, en la lección 1.1 aprendiste a mapear — pero sabiendo que le estás robando esa tecla a todo lo que ejecutes dentro.

Una vez en Normal, el buffer se comporta como cualquier otro: te mueves con hjkl, buscas con /, copias con y. Para volver a escribir en el programa, i o a, igual que en un fichero.

Un terminal es un buffer

Eso no es una metáfora: es literalmente un buffer con un proceso detrás, y de ahí sale todo lo demás.

  • Se busca. Lanzas una compilación, falla, y buscas el primer error con /error en vez de scrollear.
  • Se copia. La salida se copia con y y sus objetos de texto, sin ratón y sin el portapapeles del terminal.
  • Se navega. gg y G se mueven por todo el historial del proceso.
  • Sigue vivo escondido. Si cierras la ventana con :q, el buffer y su proceso siguen ahí: vuelves con :b y su número, o desde el picker de buffers. Un servidor de desarrollo lanzado así no se muere porque cierres la ventana.

La consecuencia que casi nadie aprovecha

La salida de un comando deja de ser texto que pasa y se pierde: es texto editable con las mismas herramientas que tu código.

Lanza los tests, y con la salida en pantalla usa /FAIL para saltar de fallo en fallo, yiw para copiar el nombre del test que quieres relanzar, y Ctrl-o para volver. Nada de seleccionar con el ratón.

Que no parezca un fichero

Un buffer de terminal hereda tus opciones, así que aparece con números de línea y columna de signos, que ahí no pintan nada. Se arregla con un autocomando:

lua/config/autocmds.lua (añadir)LUA
au("TermOpen", {  group = aug("terminal_limpio", { clear = true }),  callback = function()    vim.opt_local.number = false    vim.opt_local.relativenumber = false    vim.opt_local.signcolumn = "no"    vim.opt_local.spell = false    -- Al abrirse, empieza escribiendo: es lo que quieres el 100% de las veces    vim.cmd.startinsert()  end,})

opt_local y no vim.o: esto tiene que aplicarse solo a esta ventana, no a todo el editor. Es el primer sitio del curso donde esa distinción importa de verdad.

Un terminal que va y viene

Abrir y cerrar terminales a mano se hace pesado. Lo que quieres es una tecla que lo muestre y lo esconda, conservando el proceso. snacks, que ya instalaste en la lección anterior, lo trae:

Sin argumentos abre tu shell en un split inferior y la misma tecla lo esconde. Con un comando concreto, lo abre en una ventana flotante y lo cierra cuando el comando termina. Cada comando distinto mantiene su propio terminal, así que <leader>tg siempre te devuelve el mismo LazyGit donde lo dejaste.

Ejecutar sin abrir una terminal

No todo necesita un emulador. Neovim tiene tres formas de lanzar algo y son distintas:

Forma Qué hace
:!comando Lo ejecuta y te enseña la salida. Bloquea el editor hasta que acaba.
:terminal comando Lo ejecuta en un buffer de terminal, interactivo.
vim.system({...}) Lo ejecuta en segundo plano desde Lua y te devuelve la salida.

:! vale para cosas cortas. :terminal para lo que necesita teclado. Y vim.system es el que usan los plugins para no congelar el editor — lo verás a fondo en el nivel de procesos externos.

Y hay una cuarta, la más útil de todas y la que menos se usa:

VIM
:make

:make ejecuta tu compilador y mete los errores en la quickfix, ya parseados, con fichero y línea. En vez de leer una salida a ojo, saltas de error a error con :cnext. Lo dominaste en la lección 1.6; ahora que compilas de verdad, es cuando rinde.

Cuándo NO usar la terminal integrada

Merece la pena decirlo, porque el entusiasmo lleva a meterlo todo dentro del editor:

  • Procesos de larga duración —un servidor, un watcher, unos logs— viven mejor fuera. Si Neovim se cierra, se los lleva por delante.
  • Trabajo de shell de verdad —moverse por directorios, encadenar tuberías, git a mano— es más cómodo en una terminal de verdad, con su historial y su completado.
  • Varias cosas a la vez es justo el problema que resuelve un multiplexor, y ese es el trabajo de tmux o zellij.

La terminal integrada brilla en lo efímero: lanzar los tests, ver un git diff, correr un script y leer su salida sin cambiar de ventana. Para todo lo demás, Ctrl-z y fg siguen siendo perfectamente válidos.

Sales a Normal, buscas como en cualquier fichero, y copias con un objeto de texto. La salida es texto editable.

Cerrar la ventana no mata el buffer ni el proceso. Vuelves desde el picker de buffers.

La terminal como parte del editor

  1. Abre :terminal, sal a Normal con Ctrl-\ Ctrl-n y comprueba que puedes buscar en la salida con /.
  2. Añade el autocomando de TermOpen y comprueba que desaparecen los números de línea.
  3. Monta <leader>tt y úsalo tres veces seguidas: la misma sesión tiene que seguir ahí.
  4. Ejecuta algo largo, cierra la ventana con :q, y recupera el buffer desde <leader>fb.
  5. Prueba :make en un proyecto que compile y recorre los errores con :cnext. Esa es la diferencia entre leer una salida y navegarla.