1 पॉइंट द्वारा GN⁺ 2026-05-13 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • GNU Emacs की बिल्ट-इन LSP solution Eglot से पहले से अच्छी तरह काम कर रहे lsp-mode आधारित LSP environment को पूरी तरह बदलने के वास्तविक migration अनुभव का सार
  • Eglot, lsp-mode की तुलना में minimal और शांत interface देता है, और Corfu·Consult·Flycheck जैसे external packages तथा standard Emacs Lisp API के साथ integration करने वाली संरचना रखता है
  • बदलाव के अधिकांश काम Eglot की अपनी settings में नहीं, बल्कि सहायक packages की खोज·सेटअप·trial and error में लगे
  • pylsp, gopls जैसे LSP servers में workspace settings के तरीके अलग-अलग हैं, और project unit settings के लिए .dir-locals.el का उपयोग ज़रूरी है
  • GNU Emacs में बिल्ट-इन होने के कारण, लंबे समय में Emacs users के लिए इस बदलाव पर विचार करना उपयोगी हो सकता है

बदलाव की प्रेरणा और समग्र अनुभव

  • किसी खास मजबूत वजह के बिना, Corfu पर स्विच करने के बाद Eglot को ट्रायल के तौर पर इस्तेमाल करते-करते आगे बढ़े
  • lsp-mode + lsp-ui एक busy interface है जिसमें कई तरह की जानकारी एक साथ दिखती है, और अधिक शांत LSP अनुभव के लिए बदलाव किया गया
  • Eglot, lsp-mode से अधिक minimal है, लेकिन पूरा अनुभव पाने के लिए अतिरिक्त packages से फीचर बढ़ाने पड़ते हैं
  • नतीजा संतोषजनक रहा, और Go तथा Python modes में 'common prefix से autocomplete' जैसी सुविधाएँ बेहतर काम करती हैं
  • lsp-ui की settings को और ट्यून किया जा सकता था, लेकिन Eglot पर जाने से सभी समस्याएँ एक साथ हल हो गईं

सहायक package integration

  • Corfu बिना किसी अलग setting के, पहले वाली configuration के साथ ही autocomplete में काम करता है
  • cross-reference में lsp-ui शैली का preview पाने के लिए consult package को जोड़ना और xref-show-xrefs-function को consult-xref पर सेट करना ज़रूरी है
  • Flycheck और Flymake के बीच सोच-विचार के बाद Flycheck चुना गया
    • Flymake, Eglot के साथ बेहतर integrated है, लेकिन कुल मिलाकर Flycheck अधिक पसंद है
    • Eglot अपने-आप flymake-mode चालू कर देता है, इसलिए eglot-stay-out-of में flymake जोड़कर इसे बंद किया गया
    • flycheck-eglot का global mode स्थिर रूप से काम नहीं कर रहा था, इसलिए hook सीधे सेट करने का तरीका अपनाया गया

Key binding सेटअप

  • Eglot default key bindings नहीं देता, इसलिए इन्हें खुद सेट करना पड़ता है
  • अभी इस्तेमाल हो रहे 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 (flycheck-eglot की integration limitations से बचने के लिए mouse binding)
  • eglot-format को जानबूझकर bind नहीं किया गया — Go में पहले से go-mode का gofmt इस्तेमाल हो रहा है
  • eglot-extend-to-xref को t पर सेट करने से, external item पर jump करने के बाद M-? से project के अंदर दूसरी usages खोजी जा सकती हैं

LSP server का auto-start

  • Eglot के official docs manual start की सलाह देते हैं, लेकिन केवल local files के लिए auto-start सेट किया गया
  • eglot-ensure-local-only function define करके file-remote-p से remote file होने की जाँच की जाती है, फिर eglot-ensure call किया जाता है
  • eglot-ensure की सीमा: एक भाषा में कई LSP servers (जैसे Python में pylsp और ruff) होने पर default server ही अपने-आप चुना जाता है; बदलने के लिए मौजूदा server बंद कर eglot manually चलाना पड़ता है
  • कई LSP servers एक साथ चलाने के लिए rassumfrassum जैसे multiplexer program का उपयोग किया जा सकता है

Code Actions की accessibility

  • LSP server द्वारा दिए जाने वाले code actions बहुत होते हैं, लेकिन Eglot में उन्हें आसानी से access करना मुश्किल है (lsp-mode में भी यही स्थिति है)
  • LSP server केवल request आने पर ही code actions देता है, और वे किसी खास location पर निर्भर होते हैं
  • Eglot, server से आने वाली लंबी code action list में filtering नहीं देता, जिससे Go और Python दोनों में सूची उलझी हुई लगती है

pylsp Workspace settings

  • pylsp (Python LSP server) में style-based linter को लगातार diagnostics से बंद करने के लिए eglot-workspace-configuration का उपयोग ज़रूरी है
  • lsp-mode अलग-अलग diagnostic tools (mccabe आदि) को बंद करने के लिए सुविधाजनक control देता है, लेकिन Eglot में JSON format की workspace configuration खुद लिखनी पड़ती है
  • उदाहरण: mccabe, pylint, mypy, pycodestyle आदि को :enabled :json-false से disable करना
  • mypy से जुड़े keys pylsp_mypy और mypy दो अलग नामों से मिश्रित रूप में मिलते हैं; यह pylsp के अंदरूनी implementation detail की वजह से है
  • setq-default का इस्तेमाल अनिवार्य है, और setq से यह काम नहीं करता

Project-specific settings और .dir-locals.el

  • project के हिसाब से LSP server parameters को अस्थायी रूप से सेट करने का कोई आसान तरीका Eglot में नहीं है
  • अगर किसी खास setting की ज़रूरत हो, तो .dir-locals.el फ़ाइल में सही format में लिखना सबसे आसान तरीका है
  • gopls (Go) और pylsp (Python) में settings की संरचना पूरी तरह अलग है, इसलिए हर LSP server को अलग से सीखना पड़ता है
  • runtime पर settings बदलने के लिए dir-locals-set-class-variables से नया class define करना, फिर dir-locals-set-directory-class और eglot-signal-didChangeConfiguration call करने वाला dedicated function लिखना पड़ता है
  • Eglot पूरे project (directory tree) पर एक LSP server चलाता है, इसलिए file या buffer level LSP settings संभव नहीं हैं; इन्हें project level पर ही लागू करना होता है
  • eglot-workspace-configuration को सामान्य तरीके से सेट करने पर यह buffer-local variable बन जाता है और practically बेकार हो जाता है

Flymake vs Flycheck अनुभव

  • Flymake Eglot के साथ अधिक बेहतर integrated है, इसलिए diagnostic note में सीधे LSP server आधारित fix suggestions (quickfix code action) button 2 popup menu में दिखती हैं
  • Flycheck केवल error marking करता है, और LSP code actions को अलग से trigger करना पड़ता है
  • शुरुआत में Flymake पर स्विच किया गया, लेकिन Flycheck के कुछ बेहतर पहलुओं के कारण दोनों की settings संभालकर रखी गईं
  • flycheck-eglot के लेखक ने इस issue के लिए एक workaround सुझाया, जिसके बाद फिर Flycheck पर वापसी हुई
  • Flycheck में Flymake की तुलना में checkers का collection बड़ा है और उनके बीच switch करना आसान है
  • Flymake में 'line end पर diagnostics दिखाने' वाला विकल्प कमज़ोर लगता है
    • flycheck-inline केवल current location की warnings दिखाता है, scroll करते समय सभी warnings नहीं दिखतीं
    • Sideline + sideline-flycheck में भी वही सीमा है, लेकिन UI अनुभव बेहतर है

2 टिप्पणियां

 
GN⁺ 2026-05-13
Lobste.rs की रायें
  • कुछ भाषाओं में Eglot को ऑटो-स्टार्ट करने की सलाह बेहद ख़तरनाक हो सकती है। कई भाषाओं के LSP सर्वर untrusted code के साथ सुरक्षित रूप से इस्तेमाल नहीं किए जा सकते, और attacker के नियंत्रण वाले Rust या Elixir प्रोजेक्ट की फ़ाइल सिर्फ़ खोलने भर से भी मशीन compromise हो सकती है
    अगर भाषा के लिए कोई ऐसा LSP सर्वर नहीं है जिसे सुरक्षित माना जाता हो, तो LSP auto-activation से बचना चाहिए। संदर्भ: https://rust-analyzer.github.io/book/security.html

    • अगर आप संभावित रूप से hostile code देख रहे हैं, तो आख़िरकार पूरा काम वास्तविक security boundary के भीतर ही करना चाहिए। git status भी attack surface बन सकता है: https://github.com/justinsteven/advisories/…
      फ़र्क बस इतना है कि ऊपर वाले मामले में exploit repository के भीतर होना चाहिए, जबकि LSP में dependency side से भी समस्या आ सकती है। फिर भी अगर आदतन LSP चालू रखने की आदत पड़ जाए, तो warnings के प्रति सुस्त न होना मुश्किल लगता है
    • ऑटो-स्टार्ट से बचने की एक और वजह कुछ language servers की resource requirements हैं। मध्यम आकार के Rust प्रोजेक्ट में सिर्फ़ थोड़ी देर के लिए फ़ाइल खोलने पर भी 4GB का rust-analyzer process कई मिनट तक चल सकता है, और 1GB से बड़ा target/debug/ directory बन सकता है
    • वैसे cargo build चलाते ही मामला काफ़ी हद तक वैसा ही हो जाता है। बेशक LSP auto-load और user द्वारा साफ़ तौर पर चलाया गया command में बड़ा अंतर है, लेकिन व्यवहार में यह अंतर सोचे से कम भी हो सकता है
    • अगर automation चाहिए, तो lsp-mode की तरह activation से पहले पूछना और project को allowlist में जोड़ना बेहतर है। अगर पहले से कोई “अपने आप चलने” वाला hook है, तो read-from-minibuffer से पहले “क्या आप इस folder पर भरोसा करते हैं?” पूछने लायक बनाना लगभग 10 lines में हो सकता है, और projectile जैसी चीज़ से base directory तय कर लें तो सुरक्षा के ज़्यादातर फ़ायदे मिल जाते हैं
      मेरी setup lsp-mode की allowlist का इस्तेमाल करती है, लेकिन हर session में उसे साफ़ कर देती है, ताकि Emacs दोबारा खोलने पर हर project के लिए फिर से सहमति देनी पड़े। लगता है मैंने मूल रूप से यह performance की वजह से किया था, क्योंकि lsp-mode कभी-कभी किसी खास project को खोलने से पहले ही कई processes शुरू कर देता था। सुरक्षा जोखिम वास्तविक है, लेकिन ठीक-ठाक workflow बनाना बहुत मुश्किल भी नहीं है
  • Eglot में सबसे परेशान करने वाली बात यह है कि यह ज़्यादातर commands को functions के रूप में expose नहीं करता, बल्कि उन्हें xref जैसे Emacs interfaces के ऊपर define करता है। Clojure जैसी स्थिति में, जहाँ CIDER और clojure-lsp दोनों के xref backend मौजूद हों, वहाँ आम तौर पर CIDER को प्राथमिकता मिलती है क्योंकि वही loaded code की असली runtime state जानता है
    clojure-lsp का static analysis ख़ासकर remote REPL workflow में sync से बाहर हो सकता है। lsp-mode में go to definition जैसी features को command के रूप में सीधे call करते हुए भी xref इस्तेमाल किया जा सकता है, लेकिन Eglot में किसी खास xref backend को हटाना काफ़ी झंझट भरा है। lsp-mode के दूसरे commands भी Eglot में नहीं हैं, जबकि वे असल में xref जैसे Emacs integration points के ज़रिए दिए जा सकते हैं

  • मैंने lsp-mode एक बार इस्तेमाल किया था, लेकिन उसमें इतने उलझाऊ popups और notifications आते थे कि मैंने तुरंत हटा दिया। Eglot एक कहीं ज़्यादा शांत LSP अनुभव देता है
    इसे चालू रहने दें और जब तैयार हों तब features इस्तेमाल करें। ~cks का उलटी दिशा से आना और रास्ते में अलग-अलग tips व alternatives बताना दिलचस्प लगा

    • मैं lsp-mode में कई features बंद करके उसे काफ़ी शांत interface की तरह इस्तेमाल कर रहा हूँ। Eglot पर जाने की कोशिश की थी, लेकिन उसमें वह integration नहीं दिखा जो मैं चाहता था, इसलिए तब आगे कोशिश नहीं की
      मैं सच में ऐसा LSP server चाहता हूँ जो बहुत बड़े repositories संभाल सके। यही चीज़ बार-बार सीमा बनकर सामने आई है, और कभी-कभी लगता है कि शायद ऐसा कुछ बनाना पड़े जो source indexing ज़्यादातर एक बार में कर ले और फिर उसे कई LSP-स्टाइल कामों में reuse करे, लेकिन डर है कि कहीं यह फिर एक और बहुत बड़ा काम न बन जाए
  • Emacs के लिए LSP clients में Eglot और lsp-mode सबसे मशहूर हैं, लेकिन lspce और lsp-bridge जैसे alternatives भी हैं
    मैं कई सालों से Eglot संतोष के साथ इस्तेमाल कर रहा हूँ, लेकिन इसमें एक design limitation है जो आगे और बड़ी समस्या बन सकती है। यह प्रति buffer एक client मानकर चलता है; जब Eglot बनाया गया था तब यह उचित था, लेकिन अब एक ही buffer में कई LSP servers चलाने की ज़रूरत बढ़ती जा रही है। मौजूदा recommendation है कि किसी अलग program को LSP multiplexer की तरह इस्तेमाल किया जाए

    • उसके लिए this मौजूद है
  • 4 दिन पहले मैंने Python के लिए lsp-mode से Eglot पर स्विच किया और संतुष्ट हूँ
    अपनी मौजूदा configuration का एक minimal version यहाँ सार्वजनिक किया है: https://discuss.afpy.org/t/configuration-emacs-minimale-en-2026/3001

    • लगभग एक साल पहले मैंने elpy से eglot + basedpyright पर स्विच किया था, और मैं भी काफ़ी संतुष्ट हूँ
      हाँ, completion को लेकर कुछ असुविधा है। उदाहरण के लिए foo<tab><tab> दबाने पर, जबकि current scope में सही symbol मौजूद हो, basedpyright कभी-कभी कोई अजीब auto-import कर देता है, और अभी तक मुझे ऐसा तरीका नहीं मिला जो सिर्फ़ सबसे लंबी common string तक completion करे। इसके अलावा यह काफ़ी अच्छा है
  • मुझे उन लोगों से जलन होती है जो Emacs को modern IDE की तरह इस्तेमाल कर लेते हैं। मैं Emacs key bindings इस्तेमाल करता हूँ, लेकिन 6–8 घंटे लगाने पर भी Emacs को IDE की तरह काम नहीं करा पाया
    पहले Linux और FreeBSD development environment में TypeScript की जगह इस्तेमाल होने वाले FB Flow के हिसाब से सेट करने की कोशिश की थी और छोड़ दिया, और पिछले वीकेंड Windows पर tree-sitter के साथ एक full-featured Python environment बनाने की कोशिश की, वह भी छोड़नी पड़ी। सेट करने के लिए बहुत कुछ है, और tree-sitter parsers जैसी DLLs भी अलग से बहुत डाउनलोड करनी पड़ती हैं, इसलिए इसे एक ढंग का IDE बनाने के लिए ज़रूरत से ज़्यादा चीज़ें चाहिए। अब मैं इसमें समय नहीं लगाना चाहता, लेकिन कभी-कभी किसी भी terminal में emacs -nw चलाते ही परिचित editing environment मिल जाना अच्छा लगता है

    • अगर Python है, तो fido-vertical-mode, which-key-mode, global-completion-preview-mode, yasnippet, eglot-ensure, basedpyright जैसी minimal configuration से शुरुआत करना काफ़ी है
      अगर basedpyright path में उपलब्ध है, तो tree-sitter syntax के बिना भी ठीक-ठाक completion और syntax highlighting मिल जाती है। यह मेरी पूरी setup का न्यूनतम किया हुआ version है, और पूरी setup my full config में है
    • doom emacs आज़माने लायक है। इसे configure करना बहुत आसान है और default state में भी ज़्यादातर चीज़ें ठीक चलती हैं। अगर evil-mode पसंद न आए तो Emacs key bindings पर वापस भी जा सकते हैं