Berpindah dari lsp-mode ke Eglot di GNU Emacs
(utcc.utoronto.ca)- Ringkasan pengalaman migrasi nyata dengan mengganti sepenuhnya lingkungan LSP berbasis lsp-mode yang sebelumnya bekerja baik ke Eglot, solusi LSP bawaan GNU Emacs
- Dibandingkan lsp-mode, Eglot menawarkan antarmuka yang minimalis dan tidak ramai, dengan struktur integrasi ke paket eksternal seperti Corfu, Consult, Flycheck, dan API standar Emacs Lisp
- Sebagian besar pekerjaan migrasi ternyata bukan pada konfigurasi Eglot itu sendiri, melainkan pada mencari, mengatur, dan mencoba paket-paket pendukung
- Untuk server LSP seperti pylsp dan gopls, cara pengaturan workspace berbeda-beda, dan konfigurasi per proyek perlu memanfaatkan
.dir-locals.el - Karena Eglot sudah dibundel di GNU Emacs, dalam jangka panjang layak dipertimbangkan oleh pengguna Emacs
Motivasi perpindahan dan kesan umum
- Tanpa alasan yang benar-benar kuat, setelah berpindah ke Corfu penulis mencoba Eglot secara eksperimental lalu meneruskannya
- lsp-mode + lsp-ui menampilkan banyak informasi sekaligus sehingga menjadi antarmuka yang sibuk (busy), dan perpindahan dilakukan karena ingin pengalaman LSP yang lebih tenang
- Eglot lebih minimalis daripada lsp-mode, tetapi pengalaman yang lengkap baru terasa jika ditambah paket lain
- Secara keseluruhan hasilnya memuaskan, dan pada mode Go serta Python fitur seperti 'autocomplete dengan common prefix' bekerja lebih baik
- Pengaturan lsp-ui sebenarnya masih bisa disesuaikan lebih lanjut, tetapi berpindah ke Eglot menyelesaikan semua masalah sekaligus
Integrasi paket pendukung
- Corfu langsung bekerja untuk autocomplete dengan konfigurasi lama tanpa pengaturan tambahan
- Untuk mendapatkan pratinjau ala lsp-ui pada cross-reference, perlu menghubungkan paket consult dan mengatur
xref-show-xrefs-functionkeconsult-xref - Setelah mempertimbangkan antara Flycheck dan Flymake, penulis memilih Flycheck
- Flymake memang terintegrasi lebih baik dengan Eglot, tetapi secara umum penulis lebih menyukai Flycheck
- Karena Eglot otomatis mengaktifkan flymake-mode,
flymakeditambahkan keeglot-stay-out-ofagar nonaktif - Karena mode global flycheck-eglot tidak berjalan stabil, penulis memakai pendekatan dengan mengatur hook secara langsung
Pengaturan key binding
- Karena Eglot tidak menyediakan key binding bawaan, semuanya perlu diatur sendiri
- Contoh binding yang saat ini dipakai:
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(binding mouse untuk mengatasi keterbatasan integrasi flycheck-eglot)
eglot-formatsengaja tidak diberi binding — di Go, penulis sudah memakai gofmt dari go-mode- Jika
eglot-extend-to-xrefdiatur ket, setelah melompat ke item eksternal pengguna bisa mencari penggunaan lain di dalam proyek dengan M-?
Auto-start server LSP
- Dokumentasi resmi Eglot menyarankan start manual, tetapi penulis mengaturnya agar otomatis start hanya untuk file lokal
- Dengan mendefinisikan fungsi
eglot-ensure-local-only, status file remote diperiksa lewatfile-remote-plalueglot-ensuredipanggil - Ada keterbatasan pada
eglot-ensure: jika satu bahasa memiliki lebih dari satu server LSP (misalnya pylsp dan ruff untuk Python), hanya server default yang dipilih otomatis; untuk menggantinya harus mematikan server saat ini lalu memanggileglotsecara manual - Jika ingin menjalankan beberapa server LSP sekaligus, bisa memakai program multiplexer seperti rassumfrassum
Aksesibilitas Code Actions
- Walau server LSP menyediakan banyak code actions, di Eglot aksesnya kurang nyaman (hal serupa juga terjadi di lsp-mode)
- Server LSP hanya memberikan code action saat diminta, dan sifatnya bergantung pada posisi tertentu
- Karena Eglot tidak menyediakan fungsi pemfilteran untuk daftar code action panjang yang dikirim server, daftar tersebut menjadi ramai baik di Go maupun Python
Pengaturan workspace pylsp
- Untuk menonaktifkan linter berbasis style dari diagnosis terus-menerus di pylsp (Python LSP server), perlu memakai eglot-workspace-configuration
- lsp-mode menyediakan kontrol praktis untuk mematikan alat diagnosis tertentu seperti mccabe, tetapi di Eglot pengguna harus menulis workspace configuration format JSON secara langsung
- Contohnya, mccabe, pylint, mypy, pycodestyle, dan lainnya dinonaktifkan dengan
:enabled :json-false - Kunci terkait mypy dipakai dengan dua nama berbeda, yaitu
pylsp_mypydanmypy; ini merupakan detail implementasi internal pylsp - Wajib menggunakan
setq-default, dansetqtidak akan bekerja
Pengaturan per proyek dan .dir-locals.el
- Eglot tidak punya cara praktis untuk mengatur parameter server LSP khusus per proyek secara sementara
- Jika butuh konfigurasi tertentu, cara termudah adalah menuliskannya dengan format yang benar di file
.dir-locals.el - Pada gopls (Go) dan pylsp (Python), struktur konfigurasinya benar-benar berbeda, sehingga tiap server LSP perlu dipelajari sendiri
- Untuk mengubah konfigurasi saat runtime, perlu menulis fungsi khusus yang mendefinisikan kelas baru lewat
dir-locals-set-class-variables, lalu memanggildir-locals-set-directory-classdaneglot-signal-didChangeConfiguration - Karena Eglot menjalankan satu server LSP untuk seluruh proyek (tree direktori), konfigurasi LSP per file atau per buffer tidak dimungkinkan; semuanya harus diterapkan pada tingkat proyek
- Jika
eglot-workspace-configurationdiatur dengan cara umum, nilainya menjadi variabel buffer-local sehingga praktis tidak berguna
Pengalaman Flymake vs Flycheck
- Flymake lebih terintegrasi dengan Eglot, sehingga pada catatan diagnosis bisa langsung menampilkan usulan perbaikan berbasis server LSP (quickfix code action) di menu popup tombol 2
- Flycheck hanya memberi penandaan error, sehingga code action LSP harus dipicu secara terpisah
- Penulis sempat berpindah ke Flymake terlebih dahulu, tetapi karena ada sisi yang lebih baik di Flycheck, konfigurasi keduanya tetap dipertahankan
- Pembuat flycheck-eglot kemudian memberikan cara workaround untuk masalah tersebut, sehingga penulis kembali ke Flycheck
- Flycheck punya koleksi checker yang lebih besar daripada Flymake dan lebih mudah berpindah antar-checker
- Opsi 'menampilkan diagnosis di akhir baris' pada Flymake terasa kurang memuaskan
- flycheck-inline saat ini hanya menampilkan peringatan di posisi saat ini, dan tidak menunjukkan semua peringatan saat menggulir
- Sideline + sideline-flycheck punya keterbatasan yang sama, tetapi pengalaman UI-nya lebih baik
2 komentar
https://web.archive.org/web/20260513001754/…
Komentar Lobste.rs
Bergantung pada bahasanya, saran untuk memulai Eglot secara otomatis bisa jadi sangat buruk. Banyak server LSP untuk berbagai bahasa tidak aman digunakan pada kode yang tidak tepercaya, dan hanya dengan membuka file dari proyek Rust atau Elixir yang dikendalikan penyerang saja mesin bisa dikompromikan
Kecuali untuk bahasa yang punya server LSP yang diketahui aman, sebaiknya hindari mengaktifkan LSP otomatis. Referensi: https://rust-analyzer.github.io/book/security.html
git statuspun bisa menjadi permukaan serangan: https://github.com/justinsteven/advisories/…Bedanya, pada kasus di atas eksploit harus ada di repositorinya sendiri, sedangkan pada LSP masalah juga bisa muncul dari sisi dependensi. Tetap saja, kalau sudah terbiasa menyalakan LSP secara refleks, sepertinya sulit mencegah diri menjadi kebal terhadap peringatan
rust-analyzersebesar 4GB bisa berjalan selama beberapa menit, dan direktoritarget/debug/berukuran lebih dari 1GB bisa munculcargo build, semuanya pada dasarnya sudah terlanjur terjadi. Tentu ada perbedaan besar antara memuat LSP otomatis dan perintah yang dijalankan pengguna secara eksplisit, tetapi dalam praktik nyata perbedaannya mungkin lebih kecil dari yang dibayangkanlsp-mode: tanya dulu sebelum aktif lalu tambahkan proyek ke allowlist. Jika sudah ada hook yang “berjalan otomatis”, cukup sekitar 10 baris untuk membuatnya lebih dulu menanyakan “apakah Anda memercayai folder ini?” lewatread-from-minibuffer, dan jika direktori acuan ditentukan dengan sesuatu sepertiprojectile, sebagian besar manfaat keamanannya bisa didapatKonfigurasi saya memakai allowlist
lsp-modetetapi dibersihkan setiap sesi, jadi setiap kali Emacs dibuka lagi saya harus menyetujui ulang per proyek. Awalnya saya tampaknya melakukan ini karena alasan performa, dan kadanglsp-modemeluncurkan beberapa proses bahkan sebelum benar-benar membuka proyek tertentu. Risiko keamanannya nyata, tetapi membuat alur kerja yang masuk akal juga tidak terlalu sulitHal yang paling mengganggu dari Eglot adalah kebanyakan perintah tidak diekspos sebagai fungsi, melainkan didefinisikan di atas antarmuka Emacs seperti
xref. Saat ada backendxrefdariCIDERdanclojure-lspsekaligus, seperti pada Clojure, saya cenderung lebih memilih sisiCIDERyang mengetahui keadaan runtime sebenarnya dari kode yang sedang dimuatAnalisis statis
clojure-lspbisa kehilangan sinkronisasi, terutama pada alur kerja REPL jarak jauh. Dilsp-mode, fitur seperti pergi ke definisi bisa dipanggil langsung sebagai perintah sambil tetap memakaixref, tetapi di Eglot cukup merepotkan untuk menyingkirkan hanya backendxreftertentu. Perintah lain yang ada dilsp-modejuga tidak ada di Eglot, padahal sebenarnya merupakan fitur yang bisa disediakan lewat titik integrasi Emacs yang mirip denganxrefSaya pernah mencoba
lsp-mode, tetapi langsung menghapusnya karena terlalu banyak popup dan notifikasi yang membingungkan. Eglot memberi pengalaman LSP yang jauh lebih senyapTinggal dibiarkan aktif lalu gunakan fiturnya saat sudah siap. Menarik melihat bagaimana ~cks mengambil pendekatan dari arah sebaliknya sambil menyebutkan berbagai tip dan alternatif
lsp-modedengan banyak fitur dimatikan sehingga antarmukanya cukup tenang. Saya sempat mau pindah ke Eglot, tetapi saat itu tampaknya tidak punya fitur integrasi yang saya inginkan, jadi tidak saya lanjutkanYang benar-benar ingin saya temukan adalah server LSP yang bisa menangani repositori yang sangat besar. Ini sering menjadi batas yang terasa, dan saya sempat berpikir apakah perlu membuat sesuatu yang mengerjakan sebagian besar pengindeksan sumber sekali saja lalu memakainya ulang untuk berbagai pekerjaan bergaya LSP, tetapi saya juga khawatir jangan-jangan itu cuma usaha merebus lautan yang lain
Eglot dan
lsp-modeadalah klien LSP untuk Emacs yang paling terkenal, tetapi ada juga alternatif seperti lspce dan lsp-bridgeSaya sudah memakai Eglot dengan puas selama beberapa tahun, tetapi ada keterbatasan desain yang bisa makin jadi masalah ke depan. Eglot mengasumsikan satu klien per buffer; saat Eglot dibuat itu masuk akal, tetapi sekarang makin umum ada kasus ketika kita ingin menjalankan beberapa server LSP dalam satu buffer. [Rekomendasi] saat ini adalah memakai program terpisah sebagai multiplekser LSP
Empat hari lalu saya pindah dari
lsp-modeke Eglot untuk Python dan puas sejauh iniSaya membagikan versi minimum dari konfigurasi saya saat ini di sini: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001
Hanya saja ada sedikit gangguan soal completion. Misalnya saat menekan
foo<tab><tab>, kadangbasedpyrightmalah mengimpor otomatis sesuatu yang aneh padahal ada simbol yang cocok di scope saat ini, dan saya masih belum menemukan cara agar completion hanya sampai string umum terpanjang. Selain itu, sejauh ini cukup bagusSaya iri pada orang-orang yang berhasil membuat Emacs terasa seperti IDE modern. Saya memang memakai key binding Emacs, tetapi meski sudah menghabiskan 6–8 jam saya tidak pernah bisa membuat Emacs bekerja seperti IDE
Dulu saya mencoba menyesuaikannya dengan FB Flow, yang saya pakai sebagai pengganti TypeScript di lingkungan pengembangan Linux dan FreeBSD, lalu menyerah; akhir pekan lalu saya juga kembali menyerah saat mencoba membuat lingkungan Python full-featured di Windows lengkap dengan tree-sitter. Terlalu banyak yang harus dikonfigurasi, dan terlalu banyak DLL seperti parser tree-sitter yang juga harus diunduh terpisah, jadi yang dibutuhkan untuk menjadikannya seperti IDE sungguhan terasa berlebihan. Sekarang saya tidak ingin lagi menginvestasikan waktu sebanyak itu, tetapi sesekali menyenangkan juga ketika saya mengetik
emacs -nwdi terminal mana pun dan lingkungan penyuntingan yang familier langsung munculfido-vertical-mode,which-key-mode,global-completion-preview-mode,yasnippet,eglot-ensure, danbasedpyrightsudah cukup untuk mulaiJika
basedpyrightada di path, completion dan syntax highlighting yang layak tetap bisa didapat bahkan tanpa grammar tree-sitter. Itu versi yang dipangkas seminimal mungkin dari konfigurasi penuh saya, dan konfigurasi lengkapnya ada di my full configdoom emacslayak dicoba. Konfigurasinya sangat mudah dan dalam keadaan bawaan pun sebagian besar sudah berjalan baik. Kalau tidak sukaevil-mode, Anda juga bisa kembali ke key binding Emacs