Vim / Neovim (vimtex)

Para escribir LaTeX en Vim o Neovim, el estándar de facto es el complemento vimtex de Karl Yngve Lervåg. Ofrece compilación, navegación entre la tabla de contenido y etiquetas, movimientos y objetos de texto que operan en entornos y comandos, finalización y saltos bidireccionales con su visor PDF, todo sin salir del editor. Esta página explica la instalación y configuración de vimtex, la finalización y la búsqueda inversa mediante SyncTeX.

¿Qué es vimtex?

Ni Vim ni Neovim escriben TeX; la compilación real la realiza una distribución que usted instala: TeX Live (o MiKTeX/MacTeX). vimtex es el puente: un complemento de tipo de archivo y sintaxis para .tex. Cuando detecta el tipo de archivo tex, habilita automáticamente comandos de compilación, resaltado de sintaxis, una función de finalización (omnifunc), una vista de tabla de contenido, salto a definición para \ref/\cite y objetos de texto para entornos, delimitadores y comandos. Su núcleo funciona sin dependencias externas; La finalización y los fragmentos se combinan con los complementos de su elección.

Hay tres requisitos previos. Primero, los comandos TeX deben ser accesibles en su PATH: vimtex genera latexmk y sus amigos como procesos secundarios, por lo que si latexmk --version se ejecuta en una terminal, es casi seguro que esté bien. En segundo lugar, utilice Vim 9.1 o posterior, o Neovim 0.10 o posterior, según lo requiere vimtex actual. En tercer lugar, Vim debe tener detección de tipo de archivo y sintaxis habilitadas. Su vimrc/init.vim necesita estas dos líneas (la mayoría de las configuraciones ya las tienen):

terminal
filetype plugin indent on
syntax enable

Configuración

Normalmente instala vimtex con un administrador de complementos: vim-plug para Vim, lazy.nvim para Neovim, son las opciones comunes. Una advertencia crítica: no cargue vimtex de forma diferida. Como el proyecto lo documenta explícitamente, cargarlo después de que se detecta el tipo de archivo interrumpe la búsqueda inversa que se describe a continuación. La regla general es lazy = false en lazy.nvim, una carga explícita en packer y ninguna especificación diferida basada en for en vim-plug.

A continuación se muestra una configuración mínima de Vim (vim-plug). Declare el complemento, habilite el tipo de archivo/sintaxis y elija un visor PDF con g:vimtex_view_method, y comenzará a funcionar. Dado que maplocalleader (el líder local) es el punto de entrada para los comandos de vimtex, es tranquilizador configurarlo explícitamente (el valor predeterminado es barra invertida \).

terminal
call plug#begin()
Plug 'lervag/vimtex'
call plug#end()

filetype plugin indent on
syntax enable

let maplocalleader = ' '          " use Space as <localleader>
let g:vimtex_view_method = 'zathura'   " 'skim' on macOS, 'sumatrapdf' on Windows
let g:vimtex_compiler_method = 'latexmk'

En Neovim (lazy.nvim) escribes lo mismo en Lua. Configurar las variables dentro de init hace que entren en vigor antes de que se cargue el cuerpo del complemento. No olvides lazy = false:

terminal
return {
  "lervag/vimtex",
  lazy = false,   -- do NOT lazy-load: it breaks inverse search
  init = function()
    vim.g.vimtex_view_method = "zathura"   -- "skim" / "sumatrapdf"
    vim.g.vimtex_compiler_method = "latexmk"
  end,
}

Abra un archivo .tex y los comandos desactivados en <localleader>l estarán disponibles. Los cuatro que vale la pena memorizar primero son:

acciónMapeo predeterminadoque hace
compile\llIniciar/detener compilación continua mediante latexmk; se reconstruye automáticamente en cada guardado
view\lvAbra PDF y búsqueda directa (fuente → PDF) hasta el cursor
clean\lcLimpiar archivos auxiliares (.aux, .log,…)
stop\lkDetenga la compilación en ejecución (\lK detiene todo)

En la práctica: presione \ll una vez y latexmk permanecerá residente, actualizando PDF en cada guardado posterior. Utilice \lv para mostrar el lugar actual en PDF y \le para colocar errores en la lista de soluciones rápidas y saltar a la línea infractora. En cuanto a escribirlos: si el líder local sigue siendo \, presiona \ll; si lo cambiaste a Espacio, presionas <Space>ll, y así sucesivamente.

El compilador predeterminado es latexmk y vimtex pasa opciones como -verbose -file-line-error -synctex=1 -interaction=nonstopmode por usted. En particular, -synctex=1 está activado de forma predeterminada, por lo que los datos de sincronización necesarios para la búsqueda directa e inversa a continuación se emiten sin ninguna configuración adicional. Para usar Tectonic en su lugar, configure g:vimtex_compiler_method = "tectonic"; latexrun y arara también están disponibles.

Para japonés, el enfoque más limpio es dejar que .latexmkrc elija el motor. El backend latexmk de vimtex lee $pdf_mode de .latexmkrc para decidir la ruta de procesamiento (1 = pdfLaTeX directamente, 3 = construye un DVI y luego convierte con dvipdfmx, 4 = LuaLaTeX). Tenga en cuenta que las banderas del motor como -pdf/-lualatex no deben agregarse al options de vimtex; especifíquelos en .latexmkrc o mediante g:vimtex_compiler_latexmk_engines. Aquí hay una configuración upLaTeX + dvipdfmx: la combinación clásica para artículos japoneses sobre ciencias:

latex
$latex = 'uplatex -synctex=1 -interaction=nonstopmode -file-line-error %O %S';
$bibtex = 'upbibtex %O %B';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';
$makeindex = 'upmendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';
$pdf_mode = 3;
$max_repeat = 5;

Los puntos clave: asigne uplatex a $latex y dvipdfmx a $dvipdf, luego configure $pdf_mode = 3 para elegir la ruta “construir un DVI, luego convertir a PDF con dvipdfmx”. Pasar -synctex=1 a $latex también transporta los datos de SyncTeX al PDF incluso a través de DVI. Si escribe japonés con LuaLaTeX, no necesita .latexmkrc en absoluto; simplemente haga que g:vimtex_compiler_latexmk_engines seleccione lualatex o escriba $pdf_mode = 4 (suponiendo que luatexja/ltjsclasses).

Finalización

vimtex ofrece candidatos sensibles al contexto a través de la función de finalización estándar de Vim (omnifunc). En un búfer tex, configura omnifunc=vimtex#complete#omnifunc automáticamente, por lo que mientras g:vimtex_complete_enabled (1 predeterminado) esté activado, estará listo para usar. Lo principal que completa:

  • \cite{...}: lee archivos .bib y \bibitems para completar las claves de citas.
  • \ref{...} / \eqref{...}: reúne los \labels del documento para completar las referencias.
  • Comandos y entornos: nombres de entorno \commands y \begin{...} según los paquetes que cargue.
  • Nombres de archivos: rutas para figuras, \input/\include, \includepdf y similares.
  • Glosario y nombres de paquetes: entradas glossaries y nombres de paquetes basados en los archivos .sty/.cls disponibles.

En Vim simple, presione Ctrl-X Ctrl-O (el disparador omnicompletado) en modo de inserción y aparecerán los candidatos. Escriba \cite{ y luego Ctrl-X Ctrl-O, por ejemplo, y se enumerarán las claves de sus citas. Sin embargo, presionar eso cada vez es tedioso, por lo que en la práctica la gente conecta el omnifunc a un motor de finalización que muestra sugerencias automáticamente a medida que escribe.

Para una configuración moderna de Neovim, nvim-cmp es la opción habitual. Agregue su fuente omni y los candidatos del flujo omnifuncional de vimtex directamente:

terminal
local cmp = require("cmp")
cmp.setup({
  sources = cmp.config.sources({
    { name = "omni" },   -- pulls vimtex completion via omnifunc
  }),
})

Si prefiere coc.nvim (que funciona tanto en Vim como en Neovim), instale la extensión coc-omni e incluya el tipo de archivo tex entre sus fuentes omnidireccionales. En configuraciones anteriores de deoplete, emparéjelo con deoplete-vimtex. En todos los casos, la división del trabajo es la misma: vimtex produce los candidatos y el motor de finalización decide cuándo y cómo presentarlos.

SyncTeX registra la correspondencia entre las líneas de origen y las posiciones en PDF. Permite la búsqueda directa (saltar desde su posición de edición al PDF) y la búsqueda inversa (ir desde un lugar en el PDF a la línea de origen). vimtex maneja la búsqueda directa por usted, por lo que simplemente presione \lv. La búsqueda inversa es la parte complicada: necesita que el visor PDF vuelva a llamar a Vim. La pieza clave es el comando :VimtexInverseSearch que proporciona vimtex.

Aquí está el mecanismo. Usando SyncTeX, el espectador determina a qué línea fuente y archivo corresponde un clic, luego ejecuta un comando de shell para invocar al editor con ese número de línea y archivo como argumentos. Dentro de ese comando llamas a VimtexInverseSearch <line> <file>, y vimtex#view#inverse_search localiza tu Vim/Neovim en ejecución y abre el lugar. vimtex maneja múltiples instancias y nombres de servidores por usted, por lo que generalmente no necesita pasar un --servername usted mismo. Los nombres de los marcadores de posición difieren según el visor: la línea y el archivo son %{line}/%{input} en zathura, %line/%file en Skim y %l/%f en SumatraPDF.

Linux — zathura. La combinación más probada en batalla con vimtex. Con g:vimtex_view_method = "zathura" obtienes búsqueda directa a través de \lv y, en la mayoría de los casos, búsqueda inversa esencialmente sin configuración: vimtex inicia zathura con -x y le entrega el comando del editor que llama a VimtexInverseSearch por ti (en sistemas sin xdotool, usa zathura_simple). En zathura, Ctrl-click se mueve a la línea fuente coincidente.

Si desea configurarlo usted mismo o sincronizar también la columna, colóquelo directamente en zathurarc. los marcadores de posición de zathura son %{line} y %{input} (nota: no %l/%f); con una compilación que reconoce columnas, también puedes usar %{column}:

terminal
set synctex true
set synctex-editor-command "nvim --headless -c 'VimtexInverseSearch %{line} %{input}'"

macOS — Skim. Establezca g:vimtex_view_method = "skim". En el lado Skim, abra Preferencias → Sincronización, establezca el ajuste preestablecido en "Personalizado" y registre un comando y argumentos. %line y %file se reemplazan por Skim con el número de línea y el archivo:

terminal
Command:   nvim
Arguments: --headless -c "VimtexInverseSearch %line '%file'"

Ahora Cmd-Shift-click en Skim realiza una búsqueda inversa: Skim inicia Neovim en segundo plano y VimtexInverseSearch transmite el lugar a su instancia existente.

Windows — SumatraPDF. Establezca g:vimtex_view_method = "sumatrapdf". En SumatraPDF, en Settings → Opciones → “Establecer línea de comando de búsqueda inversa”, registre un comando como el siguiente (%l y %f son el número de línea y el archivo):

terminal
cmd /c start /min "" nvim --headless -c "VimtexInverseSearch %l '%f'"

En SumatraPDF, un doble clic activa la búsqueda inversa. Para gVim simple, reemplace la parte nvim --headless con vim -v --not-a-term -T dumb (gVim y Vim en Windows inician un servidor automáticamente).

Una última advertencia. Vim ejecutándose en una terminal (Linux/macOS) no inicia un servidor de forma predeterminada, por lo que los usuarios de Vim deben agregar lo siguiente a vimrc para que la devolución de llamada de búsqueda inversa pueda acceder a ellos (Neovim no necesita nada de esto):

terminal
if empty(v:servername) && exists('*remote_startserver')
  call remote_startserver('VIM')
endif

En cada OS y visor, el requisito previo es que el documento haya sido compilado con -synctex=1, pero como se señaló, eso ya forma parte de las opciones latexmk predeterminadas de vimtex, por lo que rara vez tienes que pensar en ello.

El bucle de edición de vimtex

vimtex no es una herramienta que debas dominar antes de escribir. Primero bloquee en cuatro movimientos: comience la compilación continua con \ll, guarde, salte a PDF con \lv e inspeccione solo los errores con \le. Cuando agregue ecuaciones o figuras, inserte \ref{...} hasta completar la etiqueta y decida cómo se detecta el archivo raíz antes de dividir capítulos. Si este bucle de edición de vimtex se resuelve primero, los motores de finalización y los fragmentos se pueden agregar más adelante sin alterar la línea principal de escritura.

Antes de pasar a un documento de varios archivos, haga que el archivo con \documentclass sea el centro del proyecto y confirme que la compilación desde un archivo secundario aún genere el mismo PDF. Si \ll de un capítulo produce un objetivo diferente, corrija la detección de raíz y .latexmkrc antes de agregar más fragmentos o capas de finalización.