Migrarse de lsp-mode a Eglot en GNU Emacs
(utcc.utoronto.ca)- Resumen de una experiencia real de migración en la que se reemplazó por completo un entorno LSP basado en lsp-mode que ya funcionaba bien por Eglot, la solución LSP integrada en GNU Emacs
- Frente a lsp-mode, Eglot ofrece una interfaz minimalista y silenciosa, y se integra con paquetes externos como Corfu, Consult y Flycheck mediante la API estándar de Emacs Lisp
- La mayor parte del trabajo de transición no se fue en configurar Eglot en sí, sino en explorar, configurar y probar paquetes auxiliares
- Según el servidor LSP, como pylsp o gopls, la forma de configurar el workspace es distinta, y para la configuración por proyecto hace falta usar
.dir-locals.el - Al venir integrado en GNU Emacs, Eglot vale la pena considerarlo a largo plazo para quienes usan Emacs
Motivos del cambio e impresión general
- Sin una razón especialmente fuerte, el cambio siguió avanzando después de probar Eglot tras la migración a Corfu
- lsp-mode + lsp-ui ofrece una interfaz cargada (busy), con mucha información mostrada al mismo tiempo, y el cambio vino del deseo de una experiencia LSP más silenciosa
- Eglot es más minimalista que lsp-mode, pero para una experiencia completa hace falta reforzarlo con paquetes adicionales
- En general, el resultado fue satisfactorio, y en los modos de Go y Python incluso funcionaron mejor cosas como la autocompletación por prefijo común
- También se podía haber ajustado más la configuración de lsp-ui, pero cambiar a Eglot resolvió todos los problemas de una sola vez
Integración con paquetes auxiliares
- Corfu funciona para autocompletado con la configuración existente, sin ajustes adicionales
- Para obtener una vista previa estilo lsp-ui en referencias cruzadas, hay que conectar el paquete consult y configurar
xref-show-xrefs-functioncomoconsult-xref - Tras dudar entre Flycheck y Flymake, se eligió Flycheck
- Flymake se integra mejor con Eglot, pero en general se prefiere Flycheck
- Como Eglot activa
flymake-modeautomáticamente, se desactiva agregandoflymakeaeglot-stay-out-of - Como el modo global de flycheck-eglot no funcionaba de forma estable, se optó por configurar el hook manualmente
Configuración de atajos de teclado
- Como Eglot no proporciona atajos predeterminados, hay que configurarlos manualmente
- Ejemplos de los atajos usados actualmente:
C-c r→eglot-rename,C-c o→eglot-code-action-organize-importsC-c h→eldoc,C-c a→eglot-code-actions,C-c q→eglot-code-action-quickfixC-M-<mouse-2>→eglot-code-actions-at-mouse(un atajo con mouse para sortear las limitaciones de integración de flycheck-eglot)
eglot-formatno se vincula intencionalmente; en Go ya se usa gofmt de go-mode- Si se configura
eglot-extend-to-xrefcomot, después de saltar a un elemento externo se puede buscar otros usos dentro del proyecto con M-?
Inicio automático del servidor LSP
- Aunque la documentación oficial de Eglot recomienda inicio manual, se configuró para iniciarse automáticamente solo en archivos locales
- Se define la función
eglot-ensure-local-only, que comprueba confile-remote-psi el archivo es remoto y luego llama aeglot-ensure - Limitación de
eglot-ensure: cuando hay varios servidores LSP para un mismo lenguaje (por ejemplo, pylsp y ruff en Python), solo selecciona automáticamente el servidor predeterminado; para cambiarlo hay que cerrar el servidor actual y llamareglotmanualmente - Si se quiere ejecutar varios servidores LSP al mismo tiempo, se puede usar un multiplexor como rassumfrassum
Accesibilidad de Code Actions
- Aunque los servidores LSP ofrecen muchas code actions, en Eglot no es fácil acceder a ellas cómodamente (igual que en lsp-mode)
- Los servidores LSP solo devuelven code actions cuando se solicitan, y dependen de una ubicación específica
- Eglot no ofrece filtrado dentro de las largas listas de code actions enviadas por el servidor, así que la lista se vuelve engorrosa tanto en Go como en Python
Configuración del workspace en pylsp
- Para desactivar en pylsp (Python LSP Server) los linters basados en estilo en el diagnóstico continuo, hace falta usar eglot-workspace-configuration
- lsp-mode ofrece controles cómodos para desactivar herramientas de diagnóstico individuales (como mccabe), pero en Eglot hay que escribir directamente la workspace configuration en formato JSON
- Ejemplo: desactivar mccabe, pylint, mypy y pycodestyle con
:enabled :json-false - En las claves relacionadas con mypy se mezclan los nombres
pylsp_mypyymypy; eso es un detalle de implementación interno de pylsp - Es obligatorio usar
setq-default; consetqno funciona
Configuración por proyecto y .dir-locals.el
- Eglot no tiene una forma cómoda de configurar temporalmente parámetros del servidor LSP por proyecto
- Si hace falta una configuración específica, lo más fácil es escribirla con el formato correcto en el archivo
.dir-locals.el - En gopls (Go) y pylsp (Python), la estructura de configuración es completamente distinta, así que hay que aprender cada servidor LSP por separado
- Para cambiar la configuración en tiempo de ejecución, hay que escribir una función dedicada que defina una nueva clase con
dir-locals-set-class-variables, luego llame adir-locals-set-directory-classy aeglot-signal-didChangeConfiguration - Como Eglot ejecuta un solo servidor LSP por proyecto (árbol de directorios completo), no se puede aplicar configuración LSP por archivo o buffer; necesariamente debe hacerse por proyecto
- Si
eglot-workspace-configurationse configura por medios generales, se convierte en una variable local de buffer y en la práctica no sirve
Experiencia con Flymake vs Flycheck
- Flymake se integra mejor con Eglot y muestra directamente en las notas de diagnóstico sugerencias de corrección basadas en el servidor LSP (quickfix code actions) en el menú emergente del botón 2
- Flycheck solo marca errores, y tiene la limitación de que las code actions de LSP deben dispararse por separado
- Primero se intentó cambiar a Flymake, pero como Flycheck también tiene ventajas, se mantuvieron ambas configuraciones
- El autor de flycheck-eglot propuso una forma de rodear ese problema, así que se volvió a Flycheck
- Flycheck tiene una colección de checkers más grande que Flymake y permite cambiar entre ellos con más facilidad
- Se echa de menos la opción de mostrar diagnósticos al final de la línea en Flymake
- flycheck-inline solo muestra advertencias de la ubicación actual y no enseña todas las advertencias al desplazarse
- Sideline + sideline-flycheck tiene la misma limitación, pero la experiencia de UI es mejor
2 comentarios
https://web.archive.org/web/20260513001754/…
Opiniones en Lobste.rs
Dependiendo del lenguaje, el consejo de iniciar Eglot automáticamente puede ser terriblemente malo. Muchos servidores LSP no son seguros para usarse con código no confiable, y con solo abrir archivos de un proyecto de Rust o Elixir controlado por un atacante tu máquina podría verse comprometida
A menos que sea un lenguaje con un servidor LSP conocido por ser seguro, conviene evitar la activación automática de LSP. Referencia: https://rust-analyzer.github.io/book/security.html
git statuspuede ser una superficie de ataque: https://github.com/justinsteven/advisories/…La diferencia es que en ese caso el exploit tiene que estar en el propio repositorio, mientras que con LSP también puede venir por el lado de las dependencias. Aun así, si te acostumbras a tener LSP encendido por inercia, parece difícil evitar volverte insensible a las advertencias
rust-analyzerde 4 GB y aparecer un directoriotarget/debug/de más de 1 GBcargo buildya casi da lo mismo. Claro, hay una gran diferencia entre la carga automática de LSP y un comando que el usuario ejecuta explícitamente, pero en la práctica la diferencia quizá sea menor de lo que parecelsp-mode, y que agregue el proyecto a una lista de permitidos. Si ya tienes un hook que “ejecuta automáticamente”, con unas 10 líneas puedes hacer que primero pregunte conread-from-minibuffer“¿Confías en esta carpeta?” y, si usas algo comoprojectilepara fijar el directorio base, obtienes la mayor parte de la ventaja de seguridadEn mi configuración uso la lista de permitidos de
lsp-mode, pero la borro en cada sesión, así que cada vez que vuelvo a abrir Emacs tengo que aceptar otra vez por proyecto. Creo que originalmente lo hice por rendimiento, porque a veceslsp-modelevantaba varios procesos incluso antes de abrir cierto proyecto. El riesgo de seguridad es real, pero no es tan difícil armar un flujo de trabajo razonableLo más molesto de Eglot es que no expone la mayoría de sus comandos como funciones, sino que los define sobre interfaces de Emacs como
xref. Cuando tienes ambos backends dexref,CIDERyclojure-lsp, como pasa con Clojure, terminas prefiriendo el lado deCIDER, que sí conoce el estado real en tiempo de ejecución del código cargadoEl análisis estático de
clojure-lsppuede desincronizarse, sobre todo en flujos de trabajo con REPL remota. Enlsp-modepuedes seguir usandoxrefy a la vez invocar directamente comandos como ir a definición, pero en Eglot quitar solo un backend específico dexrefes bastante engorroso. También faltan en Eglot otros comandos que sí están enlsp-mode, aunque en realidad son funcionalidades que podrían ofrecerse mediante puntos de integración de Emacs parecidos axrefProbé
lsp-modeuna vez, pero me aparecieron demasiados popups y notificaciones confusas, así que lo borré enseguida. Eglot da una experiencia de LSP mucho más silenciosaLo dejas encendido y usas las funciones cuando ya estás listo. Es interesante cómo ~cks aborda el tema desde la dirección opuesta y va mencionando varios consejos y alternativas
lsp-modedesactivé muchas funciones y lo uso con una interfaz bastante silenciosa. Quise cambiarme a Eglot, pero no parecía tener la integración que yo quería, así que no seguí intentando en ese momentoLo que de verdad me gustaría encontrar es un servidor LSP capaz de manejar repositorios muy grandes. Eso me ha topado seguido con límites, y me hace pensar si debería construir algo que haga la mayor parte de la indexación del código fuente de una vez y luego la reutilice para varias tareas tipo LSP, aunque me preocupa estar intentando hervir otro océano
Eglot y
lsp-modeson los clientes LSP para Emacs más conocidos, pero también hay alternativas como lspce y lsp-bridgeLlevo años usando Eglot con satisfacción, pero tiene una limitación de diseño que podría volverse más problemática en el futuro. Asume un cliente por buffer; cuando se creó Eglot eso era razonable, pero ahora cada vez es más común querer correr varios servidores LSP en un mismo buffer. La recommendation actual es usar un programa aparte como multiplexor de LSP
Hace 4 días me cambié de
lsp-modea Eglot para Python y estoy satisfechoAquí publiqué la versión mínima de mi configuración actual: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001
Eso sí, tengo algunas molestias con el autocompletado. Por ejemplo, si presiono
foo<tab><tab>, a vecesbasedpyrightautoimporta algo raro aunque haya un símbolo que encaja con el scope actual, y todavía no encuentro una forma de completar solo hasta la cadena común más larga. Fuera de eso, está bastante bienMe dan envidia las personas que hacen que Emacs se comporte como un IDE moderno. Uso los atajos de Emacs, pero ni dedicándole 6 a 8 horas he logrado hacer que Emacs funcione como IDE
Antes traté de ajustarlo para FB Flow, que usaba en lugar de TypeScript en entornos de desarrollo de Linux y FreeBSD, y lo abandoné; el fin de semana pasado volví a rendirme intentando armar en Windows un entorno Python completo con tree-sitter. Hay demasiadas cosas por configurar y también demasiados DLL aparte que bajar, como los parsers de tree-sitter, así que se siente excesivo todo lo que hace falta para dejarlo como un IDE de verdad. Ya no quiero invertirle tiempo, aunque sí me gusta que en cualquier terminal pueda escribir
emacs -nwy aparezca mi entorno de edición conocidofido-vertical-mode,which-key-mode,global-completion-preview-mode,yasnippet,eglot-ensureybasedpyrightya alcanza para empezar bienSi
basedpyrightestá en el path, puedes tener autocompletado y resaltado de sintaxis correctos incluso sin gramática de tree-sitter. Es una versión reducida al mínimo de mi configuración completa, y la configuración completa está en my full configdoom emacs. Configurarlo es muy fácil y en su estado predeterminado ya funciona bien en la mayoría de los casos. Si no te gustaevil-mode, también puedes volver a los atajos de Emacs