GNU Emacs에서 lsp-mode에서 Eglot으로 이동하기
요약
본 기사는 Emacs 환경에서 LSP(Language Server Protocol) 클라이언트로서 lsp-mode와 Eglot의 사용 경험을 비교하고, 특히 보안 및 자원 관리 측면에서의 주의점을 강조합니다. 자동 시작되는 LSP 서버는 공격 표면이 될 수 있고 과도한 자원을 소모할 수 있으므로, 사용자에게 명시적인 동의를 받거나 허용 목록 기반으로 제어하는 것이 권장됩니다. 또한, Eglot과 lsp-mode 간의 기능적 차이점(특히 Emacs 인터페이스 통합)을 분석하며, 사용자가 자신에게 맞는 최적화된 워크플로우를 구축하는 과정의 어려움을 다루고 있습니다.
핵심 포인트
- LSP 서버 자동 활성화는 보안 위험 및 과도한 자원 소모 문제를 야기할 수 있으므로 주의해야 합니다.
- 자동화를 원한다면 lsp-mode처럼 사용자에게 명시적으로 동의를 구하고 허용 목록을 사용하는 방식이 더 안전합니다.
- Eglot과 lsp-mode는 각각 장단점이 있으며, 특히 Emacs 인터페이스 통합 기능 측면에서 차이가 존재합니다.
- Emacs를 현대적인 IDE 수준으로 완벽하게 만드는 것은 매우 많은 시간과 노력을 요구하는 복잡한 과정입니다.
- Python 개발 환경의 경우, 최소한의 설정(예: basedpyright)만으로도 충분히 높은 생산성을 확보할 수 있습니다.
언어에 따라서는 Eglot을 자동 시작하는 조언이 치명적으로 나쁠 수 있음. 많은 언어의 LSP 서버는 신뢰할 수 없는 코드에서 안전하게 쓸 수 없고, 공격자가 제어하는 Rust나 Elixir 프로젝트의 파일을 여는 것만으로도 머신이 침해될 수 있음
안전하다고 알려진 LSP 서버가 있는 언어가 아니라면 LSP 자동 활성화는 피해야 함. 근거: https://rust-analyzer.github.io/book/security.html
적대적일 수 있는 코드를 본다면 결국 전체 작업을 실제 보안 경계 안에서 해야 함. git status조차 공격 표면이 될 수 있음: https://github.com/justinsteven/advisories/…
차이는 위 사례는 저장소 자체에 익스플로잇이 있어야 하지만, LSP는 의존성 쪽에서도 문제가 생길 수 있다는 점임. 그래도 습관적으로 LSP를 켜는 데 익숙해지면 경고에 둔감해지는 걸 막기 어려워 보임
자동 시작을 피해야 하는 또 다른 이유는 일부 언어 서버의 자원 요구량이 크기 때문임. 중간 규모 Rust 프로젝트에서 파일을 잠깐 열기만 해도 4GB짜리 rust-analyzer 프로세스가 몇 분 동안 돌고, 1GB 넘는 target/debug/ 디렉터리가 생길 수 있음
어차피 cargo build를 실행한 순간 이미 끝난 셈이긴 함. 물론 LSP 자동 로드와 사용자가 명시적으로 실행한 명령은 큰 차이가 있지만, 실제 사용에서는 생각보다 차이가 작을 수도 있음
자동화를 원한다면 lsp-mode처럼 활성화 전에 묻고, 프로젝트를 허용 목록에 추가하는 방식이 낫다. 이미 “자동으로 실행”하는 훅이 있다면 read-from-minibuffer로 먼저 “이 폴더를 신뢰하나요?”를 묻게 만드는 건 10줄 정도면 가능하고, projectile 같은 것으로 기준 디렉터리를 잡으면 보안 이점을 대부분 얻을 수 있음
내 설정은 lsp-mode의 허용 목록을 쓰되 세션마다 지워서, Emacs를 다시 켤 때마다 프로젝트별로 다시 동의해야 함. 원래는 성능 때문에 이렇게 했던 것 같고, lsp-mode가 특정 프로젝트를 열기도 전에 여러 프로세스를 띄우는 경우가 있었음. 보안 위험은 실제지만, 괜찮은 워크플로를 만드는 게 아주 어렵지는 않음
Eglot에서 가장 거슬리는 점은 대부분의 명령을 함수로 노출하지 않고, xref 같은 Emacs 인터페이스 위에 정의한다는 것임. Clojure처럼 CIDER와 clojure-lsp 양쪽 xref 백엔드가 있을 때는, 로드된 코드의 실제 런타임 상태를 아는 CIDER 쪽을 선호하게 됨 clojure-lsp의 정적 분석은 특히 원격 REPL 워크플로에서 동기화가 어긋날 수 있음. lsp-mode에서는 정의로 이동 같은 기능을 명령으로 직접 호출하면서 xref도 계속 쓸 수 있지만, Eglot에서는 특정 xref 백엔드만 빼는 일이 꽤 번거롭다. lsp-mode에 있는 다른 명령들도 Eglot에는 빠져 있는데, 사실 xref와 비슷한 Emacs 통합 지점을 통해 제공 가능한 기능들임
lsp-mode를 한 번 써봤는데, 헷갈리는 팝업과 알림이 너무 많이 떠서 바로 지웠음. Eglot은 훨씬 조용한 LSP 경험을 줌
켜두고 있다가 준비됐을 때 기능을 쓰면 됨. ~cks가 반대 방향에서 접근하면서 여러 팁과 대안을 언급하는 방식이 흥미로움
lsp-mode에서 많은 기능을 꺼서 꽤 조용한 인터페이스로 쓰고 있음. Eglot으로 갈아타려 했지만 원하는 통합 기능이 없어 보여서 그때는 더 시도하지 않았음
정말 찾고 싶은 건 아주 큰 저장소를 감당할 수 있는 LSP 서버임. 이게 자주 한계로 다가왔고, 소스 색인을 한 번에 대부분 처리한 뒤 여러 LSP식 작업에 재사용하는 걸 만들어야 하나 싶지만, 또 다른 바다를 끓이려는 건 아닌지 걱정됨
Emacs용 LSP 클라이언트로 Eglot과 lsp-mode가 가장 유명하지만, lspce와 lsp-bridge 같은 대안도 있음
Eglot을 몇 년 동안 만족스럽게 써왔지만, 앞으로 더 문제가 될 수 있는 설계상 한계가 있음. 버퍼당 클라이언트 하나를 가정하는데, Eglot이 만들어질 당시에는 타당했지만 이제는 한 버퍼에서 여러 LSP 서버를 돌리고 싶은 경우가 점점 흔해지고 있음. 현재 recommendation은 별도 프로그램을 LSP 멀티플렉서처럼 쓰는 것임
거의 1년 전에 elpy에서 eglot + basedpyright로 전환했고, 나도 꽤 만족하고 있음
다만 완성 관련 불편은 있음. 예를 들어 foo<tab><tab>을 누르면 현재 스코프에 맞는 심볼이 있는데도 basedpyright가 이상한 것을 자동 임포트할 때가 있고, 가장 긴 공통 문자열까지만 완성하는 방법은 아직 못 찾았음. 그 외에는 꽤 좋음
Emacs를 현대적인 IDE처럼 쓰게 만드는 사람들이 부러움. Emacs 키 바인딩은 쓰지만, 6~8시간을 들여도 Emacs를 IDE처럼 작동하게 만들 수가 없었음
예전에 Linux와 FreeBSD 개발 환경에서 TypeScript 대신 쓰던 FB Flow로 맞춰보려다 포기했고, 지난 주말에는 Windows에서 tree-sitter를 곁들인 풀기능 Python 환경을 만들려다 또 포기했음. 설정할 게 너무 많고, tree-sitter 파서 같은 DLL도 따로 너무 많이 받아야 해서, 제대로 된 IDE처럼 만들기까지 필요한 것이 과함. 이제는 시간을 투자하고 싶지 않지만, 가끔 아무 터미널에서 emacs -nw를 치면 익숙한 편집 환경이 뜨는 건 좋음
Python이라면 fido-vertical-mode, which-key-mode, global-completion-preview-mode, yasnippet, eglot-ensure, basedpyright 정도의 최소 설정으로 충분히 시작할 수 있음 basedpyright가 경로에 잡혀 있으면 tree-sitter 문법 없이도 제대로 된 완성과 구문 강조가 됨. 전체 설정에서 최소한으로 줄인 버전이고, 전체 설정은 my full config에 있음
doom emacs를 써볼 만함. 설정이 매우 쉽고 기본 상태에서도 대부분 잘 작동함. evil-mode가 마음에 들지 않으면 Emacs 키 바인딩으로 되돌릴 수도 있음
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기