1 Punkte von GN⁺ 2026-05-13 | 2 Kommentare | Auf WhatsApp teilen
  • Zusammenfassung einer tatsächlichen Migrationserfahrung, bei der eine zuvor gut funktionierende LSP-Umgebung auf Basis von lsp-mode vollständig durch Eglot, die in GNU Emacs integrierte LSP-Lösung, ersetzt wurde
  • Im Vergleich zu lsp-mode bietet Eglot eine minimalistische und ruhige Oberfläche und ist so aufgebaut, dass es sich über externe Pakete wie Corfu, Consult und Flycheck sowie die standardmäßige Emacs-Lisp-API integrieren lässt
  • Der Großteil der Umstellung entfiel nicht auf die Konfiguration von Eglot selbst, sondern auf das Suchen, Einrichten und Ausprobieren begleitender Pakete
  • Je nach LSP-Server wie pylsp oder gopls unterscheidet sich die Art der Workspace-Konfiguration, und für projektbezogene Einstellungen muss .dir-locals.el verwendet werden
  • Da Eglot in GNU Emacs integriert ist, lohnt es sich langfristig für Emacs-Nutzer, einen Wechsel in Betracht zu ziehen

Motivation für den Wechsel und Gesamteindruck

  • Ohne besonders zwingenden Grund wurde Eglot nach dem Wechsel zu Corfu zunächst testweise genutzt und dann beibehalten
  • lsp-mode + lsp-ui ist eine geschäftige (busy) Oberfläche, in der viele Informationen gleichzeitig angezeigt werden; der Wechsel erfolgte für ein ruhigeres LSP-Erlebnis
  • Eglot ist minimalistischer als lsp-mode, bietet aber erst mit zusätzlichen Paketen einen vollständigen Funktionsumfang
  • Insgesamt ist das Ergebnis zufriedenstellend, und in den Go- und Python-Modi funktionieren Features wie „Autovervollständigung über common prefix“ besser
  • Man hätte auch die Konfiguration von lsp-ui weiter anpassen können, aber der Wechsel zu Eglot löste alle Probleme auf einmal

Integration begleitender Pakete

  • Corfu funktioniert für die Autovervollständigung ohne zusätzliche Anpassungen mit der bisherigen Konfiguration weiter
  • Um in Cross-References eine Vorschau im Stil von lsp-ui zu erhalten, muss das Paket consult angebunden und xref-show-xrefs-function auf consult-xref gesetzt werden
  • Nach Abwägung zwischen Flycheck und Flymake fiel die Wahl auf Flycheck
    • Flymake ist besser in Eglot integriert, insgesamt wird jedoch Flycheck bevorzugt
    • Da Eglot automatisch flymake-mode aktiviert, wird es durch Hinzufügen von flymake zu eglot-stay-out-of deaktiviert
    • Weil der globale Modus von flycheck-eglot nicht stabil funktionierte, wurden die Hooks direkt gesetzt

Keybindings konfigurieren

  • Da Eglot keine Standard-Keybindings mitbringt, müssen sie manuell eingerichtet werden
  • Beispiele für aktuell verwendete Bindings:
    • 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 (eine Mausbelegung, um die Integrationsgrenzen von flycheck-eglot zu umgehen)
  • eglot-format wird absichtlich nicht gebunden — in Go wird bereits gofmt aus go-mode verwendet
  • Wird eglot-extend-to-xref auf t gesetzt, kann nach einem Sprung zu einem externen Eintrag mit M-? nach weiteren Verwendungen im Projekt gesucht werden

Automatischer Start von LSP-Servern

  • Die offizielle Eglot-Dokumentation empfiehlt einen manuellen Start, hier wurde jedoch konfiguriert, dass nur bei lokalen Dateien automatisch gestartet wird
  • Dafür wird die Funktion eglot-ensure-local-only definiert, die mit file-remote-p auf Remote-Dateien prüft und dann eglot-ensure aufruft
  • Einschränkung von eglot-ensure: Wenn es für eine Sprache mehrere LSP-Server gibt (z. B. bei Python pylsp und ruff), wird automatisch nur der Standardserver gewählt; für einen Wechsel muss der aktuelle Server beendet und eglot manuell aufgerufen werden
  • Um mehrere LSP-Server gleichzeitig zu betreiben, kann ein Multiplexer-Programm wie rassumfrassum verwendet werden

Zugänglichkeit von Code Actions

  • Es gibt viele Code Actions, die LSP-Server bereitstellen, aber in Eglot sind sie nicht bequem zugänglich (bei lsp-mode ähnlich)
  • LSP-Server liefern Code Actions nur auf Anfrage und abhängig von einer konkreten Position
  • Eglot bietet keine Filterfunktion für die langen Listen von Code Actions, die vom Server gesendet werden, wodurch die Listen sowohl in Go als auch in Python unübersichtlich werden

pylsp-Workspace-Konfiguration

  • Um im pylsp (Python LSP Server) stilbasierte Linter in der laufenden Diagnose zu deaktivieren, muss eglot-workspace-configuration verwendet werden
  • lsp-mode bietet komfortable Schalter zum Deaktivieren einzelner Diagnosewerkzeuge wie mccabe, in Eglot muss jedoch die Workspace-Konfiguration im JSON-Format direkt geschrieben werden
  • Beispiel: mccabe, pylint, mypy und pycodestyle werden mit :enabled :json-false deaktiviert
  • Im Zusammenhang mit mypy werden die Schlüssel pylsp_mypy und mypy unter zwei verschiedenen Namen gemischt verwendet, was ein Implementierungsdetail innerhalb von pylsp ist
  • Es muss unbedingt setq-default verwendet werden; mit setq funktioniert es nicht

Projektspezifische Einstellungen und .dir-locals.el

  • Eglot bietet keine bequeme Methode, um projektspezifische LSP-Server-Parameter nur vorübergehend zu setzen
  • Wenn bestimmte Einstellungen benötigt werden, ist es am einfachsten, sie im richtigen Format in .dir-locals.el zu schreiben
  • Bei gopls (Go) und pylsp (Python) ist die Struktur der Einstellungen völlig unterschiedlich, sodass jeder LSP-Server einzeln verstanden werden muss
  • Um Einstellungen zur Laufzeit zu ändern, muss eine eigene Funktion geschrieben werden, die mit dir-locals-set-class-variables eine neue Klasse definiert und anschließend dir-locals-set-directory-class sowie eglot-signal-didChangeConfiguration aufruft
  • Eglot startet einen LSP-Server für das gesamte Projekt (den Verzeichnisbaum), daher sind datei- oder bufferbezogene LSP-Einstellungen nicht möglich und müssen immer auf Projektebene angewendet werden
  • Wird eglot-workspace-configuration auf allgemeinem Weg gesetzt, wird daraus eine buffer-lokale Variable und sie ist praktisch unbrauchbar

Erfahrungen mit Flymake vs. Flycheck

  • Flymake ist besser in Eglot integriert und zeigt in Diagnosehinweisen direkt vom LSP-Server kommende Korrekturvorschläge (Quickfix Code Actions) im Popup-Menü von Taste 2 an
  • Flycheck markiert nur Fehler und hat die Einschränkung, dass LSP-Code-Actions separat ausgelöst werden müssen
  • Anfangs wurde auf Flymake umgestellt, später wurden jedoch wegen der Stärken von Flycheck beide Konfigurationen beibehalten
  • Der Entwickler von flycheck-eglot stellte einen Workaround für dieses Problem vor, wodurch die Rückkehr zu Flycheck möglich wurde
  • Flycheck bietet im Vergleich zu Flymake eine größere Sammlung an Checkern und einen einfacheren Wechsel zwischen ihnen
  • Bei Flymake wird die Option „Diagnosen am Zeilenende anzeigen“ vermisst
    • flycheck-inline zeigt nur Warnungen an der aktuellen Position und nicht alle Warnungen beim Scrollen
    • Sideline + sideline-flycheck hat dieselbe Einschränkung, bietet aber ein besseres UI-Erlebnis

2 Kommentare

 
GN⁺ 2026-05-13
Lobste.rs-Kommentare
  • Je nach Sprache kann der Ratschlag, Eglot automatisch zu starten, fatal schlecht sein. Die LSP-Server vieler Sprachen lassen sich nicht sicher mit nicht vertrauenswürdigem Code verwenden, und schon das Öffnen von Dateien in einem von Angreifern kontrollierten Rust- oder Elixir-Projekt kann den eigenen Rechner kompromittieren
    Wenn es sich nicht um eine Sprache mit einem als sicher bekannten LSP-Server handelt, sollte man LSP nicht automatisch aktivieren. Quelle: https://rust-analyzer.github.io/book/security.html

    • Wenn man potenziell feindseligen Code betrachtet, sollte man letztlich die gesamte Arbeit innerhalb einer echten Sicherheitsgrenze erledigen. Selbst git status kann eine Angriffsfläche sein: https://github.com/justinsteven/advisories/…
      Der Unterschied ist, dass im obigen Fall das Exploit im Repository selbst vorhanden sein muss, während bei LSP auch die Abhängigkeitsseite Probleme verursachen kann. Wenn man sich aber daran gewöhnt, LSP gewohnheitsmäßig einzuschalten, dürfte es schwer sein zu verhindern, gegenüber Warnungen abstumpft
    • Ein weiterer Grund, automatischen Start zu vermeiden, sind die hohen Ressourcenanforderungen mancher Sprachserver. Schon wenn man in einem mittelgroßen Rust-Projekt nur kurz eine Datei öffnet, kann ein rust-analyzer-Prozess mit 4 GB mehrere Minuten laufen, und es kann ein target/debug/-Verzeichnis von über 1 GB entstehen
    • Sobald man ohnehin cargo build ausgeführt hat, ist es im Grunde schon vorbei. Natürlich gibt es einen großen Unterschied zwischen automatischem Laden von LSP und einem Befehl, den der Benutzer explizit ausführt, aber in der Praxis könnte der Unterschied kleiner sein als gedacht
    • Wenn man Automatisierung möchte, ist es besser, wie bei lsp-mode vor der Aktivierung zu fragen und das Projekt in eine Allowlist aufzunehmen. Wenn es bereits einen Hook gibt, der etwas „automatisch ausführt“, kann man mit read-from-minibuffer in etwa 10 Zeilen zuerst „Vertrauen Sie diesem Ordner?“ abfragen, und wenn man mit etwas wie projectile ein Basisverzeichnis festlegt, bekommt man den Großteil des Sicherheitsgewinns
      In meiner Konfiguration nutze ich die Allowlist von lsp-mode, lösche sie aber pro Sitzung, sodass ich bei jedem Neustart von Emacs projektspezifisch erneut zustimmen muss. Ursprünglich habe ich das wohl aus Performancegründen so gemacht, und es kam vor, dass lsp-mode mehrere Prozesse startete, noch bevor ein bestimmtes Projekt überhaupt geöffnet war. Das Sicherheitsrisiko ist real, aber einen brauchbaren Workflow zu bauen ist nicht besonders schwer
  • Was an Eglot am meisten stört, ist, dass die meisten Befehle nicht als Funktionen offengelegt werden, sondern über Emacs-Schnittstellen wie xref definiert sind. Wenn es wie bei Clojure sowohl ein xref-Backend von CIDER als auch von clojure-lsp gibt, bevorzuge ich die Seite von CIDER, weil sie den tatsächlichen Laufzeitzustand des geladenen Codes kennt
    Die statische Analyse von clojure-lsp kann besonders in Remote-REPL-Workflows aus dem Tritt geraten. In lsp-mode kann man Funktionen wie „Gehe zu Definition“ direkt als Befehl aufrufen und xref trotzdem weiter nutzen, aber in Eglot ist es ziemlich umständlich, nur ein bestimmtes xref-Backend auszuschließen. Andere Befehle aus lsp-mode fehlen in Eglot ebenfalls, obwohl es eigentlich Funktionen sind, die sich über ähnliche Emacs-Integrationspunkte wie xref bereitstellen ließen

  • Ich habe lsp-mode einmal ausprobiert, aber die verwirrenden Pop-ups und Benachrichtigungen waren so zahlreich, dass ich es sofort wieder gelöscht habe. Eglot bietet eine deutlich ruhigere LSP-Erfahrung
    Man lässt es einfach aktiviert und nutzt die Funktionen, wenn man bereit ist. Interessant ist, wie ~cks aus der entgegengesetzten Richtung an die Sache herangeht und verschiedene Tipps und Alternativen erwähnt

    • Ich verwende lsp-mode, habe aber viele Funktionen abgeschaltet und damit eine ziemlich ruhige Oberfläche. Ich wollte zu Eglot wechseln, habe es dann aber nicht weiter verfolgt, weil die gewünschte Integration zu fehlen schien
      Was ich wirklich suche, ist ein LSP-Server, der sehr große Repositories bewältigen kann. Das war oft die eigentliche Grenze, und ich frage mich, ob ich etwas bauen sollte, das die Quellcode-Indizierung einmalig weitgehend erledigt und dann für verschiedene LSP-artige Aufgaben wiederverwendet, aber ich habe Sorge, damit nur ein weiteres Meer zum Kochen bringen zu wollen
  • Als LSP-Clients für Emacs sind Eglot und lsp-mode die bekanntesten, aber es gibt auch Alternativen wie lspce und lsp-bridge
    Ich nutze Eglot seit einigen Jahren zufrieden, aber es gibt eine architekturbedingte Einschränkung, die künftig problematischer werden könnte. Es geht von einem Client pro Buffer aus; als Eglot entstand, war das plausibel, aber inzwischen wird es immer üblicher, mehrere LSP-Server in einem Buffer laufen lassen zu wollen. Die aktuelle Empfehlung ist, ein separates Programm als LSP-Multiplexer zu verwenden

    • Dafür gibt es this
  • Ich bin vor 4 Tagen für Python von lsp-mode zu Eglot gewechselt und zufrieden
    Hier habe ich die Minimalversion meiner aktuellen Konfiguration veröffentlicht: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001

    • Vor fast einem Jahr bin ich von elpy zu eglot + basedpyright gewechselt, und ich bin ebenfalls ziemlich zufrieden
      Bei der Vervollständigung gibt es allerdings Unannehmlichkeiten. Wenn ich zum Beispiel foo<tab><tab> drücke, importiert basedpyright manchmal etwas Seltsames automatisch, obwohl es im aktuellen Scope ein passendes Symbol gibt, und ich habe noch keinen Weg gefunden, nur bis zur längsten gemeinsamen Zeichenfolge zu vervollständigen. Davon abgesehen ist es ziemlich gut
  • Ich beneide Leute, die Emacs wie eine moderne IDE nutzen. Ich verwende zwar Emacs-Keybindings, aber selbst nach 6 bis 8 Stunden bekomme ich Emacs nicht dazu, sich wie eine IDE zu verhalten
    Früher wollte ich es für Linux- und FreeBSD-Entwicklungsumgebungen auf FB Flow abstimmen, das ich anstelle von TypeScript genutzt habe, und habe aufgegeben; letztes Wochenende habe ich dann erneut aufgegeben, als ich unter Windows eine voll ausgestattete Python-Umgebung mit tree-sitter aufbauen wollte. Es gibt einfach zu viel zu konfigurieren, und man muss zusätzlich zu viele DLLs wie tree-sitter-Parser herunterladen, sodass der Aufwand bis zu einer richtigen IDE unverhältnismäßig wirkt. Inzwischen möchte ich dafür keine Zeit mehr investieren, aber es ist trotzdem schön, wenn in irgendeinem Terminal nach emacs -nw die vertraute Bearbeitungsumgebung erscheint

    • Für Python kann man schon mit einer Minimal-Konfiguration wie fido-vertical-mode, which-key-mode, global-completion-preview-mode, yasnippet, eglot-ensure und basedpyright gut loslegen
      Wenn basedpyright im Pfad liegt, bekommt man auch ohne tree-sitter-Grammatik ordentliche Vervollständigung und Syntaxhervorhebung. Das ist eine auf das Minimum reduzierte Version meiner Gesamtkonfiguration; die vollständige Konfiguration steht in my full config
    • doom emacs ist einen Blick wert. Die Konfiguration ist sehr einfach, und schon im Standardzustand funktioniert das meiste gut. Wenn einem evil-mode nicht gefällt, kann man auch wieder zu Emacs-Keybindings zurückkehren