In GNU Emacs von lsp-mode zu Eglot wechseln
(utcc.utoronto.ca)- 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.elverwendet 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-functionaufconsult-xrefgesetzt 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-modeaktiviert, wird es durch Hinzufügen vonflymakezueglot-stay-out-ofdeaktiviert - 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 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(eine Mausbelegung, um die Integrationsgrenzen von flycheck-eglot zu umgehen)
eglot-formatwird absichtlich nicht gebunden — in Go wird bereits gofmt aus go-mode verwendet- Wird
eglot-extend-to-xrefauftgesetzt, 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-onlydefiniert, die mitfile-remote-pauf Remote-Dateien prüft und danneglot-ensureaufruft - Einschränkung von
eglot-ensure: Wenn es für eine Sprache mehrere LSP-Server gibt (z. B. bei Pythonpylspundruff), wird automatisch nur der Standardserver gewählt; für einen Wechsel muss der aktuelle Server beendet undeglotmanuell 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-configurationverwendet 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-falsedeaktiviert - Im Zusammenhang mit mypy werden die Schlüssel
pylsp_mypyundmypyunter zwei verschiedenen Namen gemischt verwendet, was ein Implementierungsdetail innerhalb von pylsp ist - Es muss unbedingt
setq-defaultverwendet werden; mitsetqfunktioniert 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.elzu 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-variableseine neue Klasse definiert und anschließenddir-locals-set-directory-classsowieeglot-signal-didChangeConfigurationaufruft - 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-configurationauf 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
https://web.archive.org/web/20260513001754/…
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
git statuskann 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
rust-analyzer-Prozess mit 4 GB mehrere Minuten laufen, und es kann eintarget/debug/-Verzeichnis von über 1 GB entstehencargo buildausgefü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 gedachtlsp-modevor der Aktivierung zu fragen und das Projekt in eine Allowlist aufzunehmen. Wenn es bereits einen Hook gibt, der etwas „automatisch ausführt“, kann man mitread-from-minibufferin etwa 10 Zeilen zuerst „Vertrauen Sie diesem Ordner?“ abfragen, und wenn man mit etwas wieprojectileein Basisverzeichnis festlegt, bekommt man den Großteil des SicherheitsgewinnsIn 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, dasslsp-modemehrere Prozesse startete, noch bevor ein bestimmtes Projekt überhaupt geöffnet war. Das Sicherheitsrisiko ist real, aber einen brauchbaren Workflow zu bauen ist nicht besonders schwerWas an Eglot am meisten stört, ist, dass die meisten Befehle nicht als Funktionen offengelegt werden, sondern über Emacs-Schnittstellen wie
xrefdefiniert sind. Wenn es wie bei Clojure sowohl einxref-Backend vonCIDERals auch vonclojure-lspgibt, bevorzuge ich die Seite vonCIDER, weil sie den tatsächlichen Laufzeitzustand des geladenen Codes kenntDie statische Analyse von
clojure-lspkann besonders in Remote-REPL-Workflows aus dem Tritt geraten. Inlsp-modekann man Funktionen wie „Gehe zu Definition“ direkt als Befehl aufrufen undxreftrotzdem weiter nutzen, aber in Eglot ist es ziemlich umständlich, nur ein bestimmtesxref-Backend auszuschließen. Andere Befehle auslsp-modefehlen in Eglot ebenfalls, obwohl es eigentlich Funktionen sind, die sich über ähnliche Emacs-Integrationspunkte wiexrefbereitstellen ließenIch habe
lsp-modeeinmal 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-ErfahrungMan 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
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 schienWas 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-modedie bekanntesten, aber es gibt auch Alternativen wie lspce und lsp-bridgeIch 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
Ich bin vor 4 Tagen für Python von
lsp-modezu Eglot gewechselt und zufriedenHier habe ich die Minimalversion meiner aktuellen Konfiguration veröffentlicht: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001
Bei der Vervollständigung gibt es allerdings Unannehmlichkeiten. Wenn ich zum Beispiel
foo<tab><tab>drücke, importiertbasedpyrightmanchmal 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 gutIch 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 -nwdie vertraute Bearbeitungsumgebung erscheintfido-vertical-mode,which-key-mode,global-completion-preview-mode,yasnippet,eglot-ensureundbasedpyrightgut loslegenWenn
basedpyrightim 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 configdoom emacsist einen Blick wert. Die Konfiguration ist sehr einfach, und schon im Standardzustand funktioniert das meiste gut. Wenn einemevil-modenicht gefällt, kann man auch wieder zu Emacs-Keybindings zurückkehren