1 puntos por GN⁺ 2026-05-13 | 2 comentarios | Compartir por WhatsApp
  • 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-function como consult-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-mode automáticamente, se desactiva agregando flymake a eglot-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 reglot-rename, C-c oeglot-code-action-organize-imports
    • C-c heldoc, C-c aeglot-code-actions, C-c qeglot-code-action-quickfix
    • C-M-<mouse-2>eglot-code-actions-at-mouse (un atajo con mouse para sortear las limitaciones de integración de flycheck-eglot)
  • eglot-format no se vincula intencionalmente; en Go ya se usa gofmt de go-mode
  • Si se configura eglot-extend-to-xref como t, 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 con file-remote-p si el archivo es remoto y luego llama a eglot-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 llamar eglot manualmente
  • 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_mypy y mypy; eso es un detalle de implementación interno de pylsp
  • Es obligatorio usar setq-default; con setq no 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 a dir-locals-set-directory-class y a eglot-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-configuration se 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

 
GN⁺ 2026-05-13
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

    • Si vas a mirar código potencialmente hostil, al final todo el trabajo debería hacerse dentro de un límite de seguridad real. Incluso git status puede 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
    • Otra razón para evitar el inicio automático es que algunos servidores de lenguaje tienen requisitos de recursos muy altos. En un proyecto Rust de tamaño medio, con solo abrir un archivo por un momento puede quedarse corriendo durante varios minutos un proceso rust-analyzer de 4 GB y aparecer un directorio target/debug/ de más de 1 GB
    • De todos modos, en cuanto ejecutaste cargo build ya 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 parece
    • Si quieres automatización, es mejor que pregunte antes de activarse, como lsp-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 con read-from-minibuffer “¿Confías en esta carpeta?” y, si usas algo como projectile para fijar el directorio base, obtienes la mayor parte de la ventaja de seguridad
      En 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 veces lsp-mode levantaba 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 razonable
  • Lo 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 de xref, CIDER y clojure-lsp, como pasa con Clojure, terminas prefiriendo el lado de CIDER, que sí conoce el estado real en tiempo de ejecución del código cargado
    El análisis estático de clojure-lsp puede desincronizarse, sobre todo en flujos de trabajo con REPL remota. En lsp-mode puedes seguir usando xref y a la vez invocar directamente comandos como ir a definición, pero en Eglot quitar solo un backend específico de xref es bastante engorroso. También faltan en Eglot otros comandos que sí están en lsp-mode, aunque en realidad son funcionalidades que podrían ofrecerse mediante puntos de integración de Emacs parecidos a xref

  • Probé lsp-mode una vez, pero me aparecieron demasiados popups y notificaciones confusas, así que lo borré enseguida. Eglot da una experiencia de LSP mucho más silenciosa
    Lo 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

    • En lsp-mode desactivé 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 momento
      Lo 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-mode son los clientes LSP para Emacs más conocidos, pero también hay alternativas como lspce y lsp-bridge
    Llevo 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

    • Para eso está this
  • Hace 4 días me cambié de lsp-mode a Eglot para Python y estoy satisfecho
    Aquí publiqué la versión mínima de mi configuración actual: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001

    • Hace casi un año me cambié de elpy a eglot + basedpyright, y yo también estoy bastante satisfecho
      Eso sí, tengo algunas molestias con el autocompletado. Por ejemplo, si presiono foo<tab><tab>, a veces basedpyright autoimporta 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 bien
  • Me 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 -nw y aparezca mi entorno de edición conocido

    • Para Python, una configuración mínima con fido-vertical-mode, which-key-mode, global-completion-preview-mode, yasnippet, eglot-ensure y basedpyright ya alcanza para empezar bien
      Si basedpyright está 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 config
    • Vale la pena probar doom emacs. Configurarlo es muy fácil y en su estado predeterminado ya funciona bien en la mayoría de los casos. Si no te gusta evil-mode, también puedes volver a los atajos de Emacs