요약
MIT에서 태어난 편집기 Emacs가 50년을 맞았고, 그 공유 문화가 자유 소프트웨어 운동을 낳았습니다.
MIT 동문 심슨 가핑클이 MIT 테크놀로지 리뷰에 쓴 역사 글입니다. 천공 테이프로 프로그램을 고치던 시절부터 Emacs와 GNU 프로젝트가 생기기까지의 흐름을 따라갑니다.
왜 중요한가
- 자유 소프트웨어 운동의 뿌리가 편집기 하나를 고쳐 가며 나눠 쓰던 공동체에 있었다는 점을 보여 줍니다.
- 무료로 나누던 프로그램이 상용 제품으로 팔린 일이 GNU 프로젝트를 낳았다는 인과를 짚습니다.
핵심 내용
- 1976년 MIT AI 연구소의 리처드 스톨먼이 키마다 매크로가 실행되게 바꾸면서 Emacs가 시작됐습니다.
- 바탕은 1962년 PDP-1용으로 나온 편집기 TECO였고, 이것이 매크로를 짜는 언어로 자라 있었습니다.
- 스톨먼은 테이프와 반송 우표를 보내면 Emacs를 복사해 주고, 고친 부분을 돌려 달라고 했습니다.
- 버나드 그린버그와 제임스 고슬링이 만든 판이 상용으로 팔리자 스톨먼은 GNU 프로젝트를 시작했습니다.
- GNU Emacs는 GNU의 첫 주요 프로그램이었고, Mac OS X에는 2001년부터 2019년까지 기본으로 들어 있었습니다.
HN 반응
- 30년 넘게 쓴 이용자들은 AI에게 말만 하면 확장 기능을 바로 만들어 실행 중인 Emacs에 넣을 수 있어 요즘이 전성기라고 했습니다.
- 반면 Emacs Lisp와 내부 구조를 깊이 아는 핵심 개발자들이 중년에 접어들었는데, AI가 후계자를 키우지는 못할 것이라는 걱정도 나왔습니다.
저는 Emacs를 30년 넘게 써 왔습니다. 다른 에디터는 왔다가 사라졌지만 Emacs는 남았습니다. 제 설정 일부는 30년도 더 된 것입니다.
Emacs 역사에도 좋은 시절과 나쁜 시절이 있었습니다. 하지만 요즘은 정말 좋습니다. Emacs는 활발하게 유지보수되고 개발되고 있으며, 인상적인 외부 패키지도 많습니다. Magit과 ghostel은 제가 매일 일하는 데 쓰는 대표적인 패키지입니다.
최근에는 AI가 제가 Emacs를 쓰는 방식을 완전히 바꿔 놓았는데, 아주 좋은 쪽으로 바뀌었습니다. 이제 저는 AI를 어떤 소원이든 들어주는 요정처럼 대합니다. 에디터가 어떻게 동작했으면 좋겠는지 설명하면, 짠! 정말 그렇게 동작합니다.
예를 들면 창과 탭 관리, difftastic 연동, 표가 아름답게 렌더링되는 마크다운 미리보기, PDF로 보는 마크다운 미리보기 등 많습니다.
그런데 무엇보다 중요한 것은 스톨먼의 원래 생각으로 돌아갑니다. 제 에디터와 제 환경은 제가 통제합니다. 어떻게 보이고 어떻게 동작할지는 제가 정합니다. 어떤 기업도 저 대신 결정하지 않습니다. 어떤 기업도 새 AI 어시스턴트를 억지로 끼워 넣지 않습니다. 광고나 추적을 들여오는 사람도 없습니다. 오랜 세월에 걸쳐 제가 고마움을 알게 된 부분입니다.
한편으로는 AI가 Emacs 개발에 힘을 실어 줍니다. 다른 한편으로, 30년 동안 Emacs를 써 온 사용자로서 저는 Emacs Lisp와 Emacs 내부를 깊이 이해하는 사람이, 그냥 Emacs를 쓰면서 자기 설정을 가볍게 손보는 정도의 사람들에 비하면 정말 적다고 늘 느껴 왔습니다. 그래서 AI가 그 소수 엘리트층의 성장을 북돋우지 못할까 걱정됩니다. Emacs의 장기적인 미래에는 그 층이 꽤 중요해 보이거든요.
좋은 지적입니다. 다만 저는 지난 5년 동안 독자적인 아키텍처를 만들어 내는 대신 Emacs 내부에 직접 연결되는, 아주 인기 있는 패키지가 많이 나왔다고 생각합니다.
예를 들어 corfu 0와 company 1를 비교해 보세요. Company도 capf와 함께 동작하지만, company 전용 백엔드를 직접 작성할 수도 있습니다. Corfu도 capf와 함께 동작하는데, 모든 백엔드가 corfu 전용 백엔드가 아니라 capf 함수입니다.
또 다른 좋은 예는 eglot 2와 lsp-mode 3입니다. Eglot은 이제 Emacs에 기본으로 포함되어 있습니다.
vertico 4(그리고 함께 설치하라고 권하는 다른 패키지들)와 helm/ivy의 관계도 있습니다.
다만 Emacs에 더 깊이 붙는 패키지가 꼭 더 낫다는 뜻은 아닙니다. 제 시각에서는, 공짜로 얻는 것이 훨씬 많아지고 파고들게 되는 문서도 패키지 전용이 아니라 Emacs 전용이 된다는 쪽에 가깝습니다. 결국 취향 문제입니다.
Vertico/Counsel/Orderless도 아주 좋지만, Helm과 Ivy는 기능이 완전히 갖춰져 있습니다(Helm이 얼마나 많은 걸 제공하는지 저는 늘 잊어버립니다).
저는 지금 corfu, eglot, vertico를 씁니다. Helm과 company로 돌아갈까 생각도 해 봤습니다. 특히 오랫동안 company의 백엔드에 아주 익숙했으니까요.
저는 Helm, lsp-mode, yasnippet 같은 것들을 오랫동안 썼습니다. 그러다 Eglot/Corfu/Vertico/Tempel로 갈아탔습니다. 새 흐름이 훨씬 마음에 듭니다.
실제로는 몇 년 만에 가장 큰 개발 붐이 일고 있어요. r/emacs에는 새 패키지 발표가 매일, 정말 매일 올라와요. 대부분은 아니더라도 상당수는 AI가 대충 만든 쓰레기가 아니라 아주 쓸 만해요. 일부 패키지 제작자는 바이브 코딩을 했는데도 설계 판단이 좋고, 테스트도 제대로 갖추고, 문서도 손으로 직접 쓰는 등 그 이상을 해내요. Canvas 쪽 작업은 LLM이 없었다면 아마 불가능했을 거예요.
말 그대로 /r/emacs 구독을 끊었어요. 실제로 쓰레기였거든요.
Canvas 패치는 써 보지 않았지만, 제가 알기로 minad는 그걸 짜는 데 LLM을 쓰지 않았어요.
아, 제가 틀렸네요. 헷갈렸어요. Divya가 Emacs Reader용으로 실험 삼아 먼저 만든 줄 알았거든요. 알고 보니 원래 프로토타입을 만든 사람은 정말 minad였고, Divya가 그걸 Reader에 쓰고 싶어 했고, 이후 여러 사람이 힘을 모아 Android와 Mac에서 동작하게 만들었고, 마침내 master 브랜치에 들어간 거였네요. 그리고 맞아요, LLM은 없었어요. 적어도 쓴 적이 있다고 공개적으로 말한 사람은 아무도 없어요.
이건 좋은 일입니다. 커스텀 환경은 최소한으로 하거나 업스트림에 있는 것을 써야 합니다. 누구든 옆에 앉아서 변경 사항을 같이 해킹해 줄 수 있어야 하니까요. 환경이 특이하고 커스텀될수록 그게 어려워지고, 이 손해는 커스텀 설정으로 얻을 수 있는 어떤 이득도 상쇄하고 남습니다. (elisp를 배우고 변경 작업을 하는 데 드는 비용도 꼭 계산에 넣으세요!)
누군가는 올바른 설정을 만들어야 합니다. 하지만 우리 대부분은 더 할 일이 있습니다.
저는 모든 사용자(혹은 대다수 사용자)가 내부 구조에 시간을 너무 많이 쏟아서 생산성 이득을 못 보게 하자고 주장하는 게 아닙니다. 제 걱정은 이 제품이 의존하는 엘리트층을 유지하고, 세대교체를 확실히 하고, 건강하게 키우는 일입니다. Emacs 생태계 핵심 개발자 상당수가 중년이라는 건 비밀이 아니고, 그러니 이 프로젝트는 심장마비 몇 번이면 지금까지 잘 지탱해 온 경험과 역량을 잃을 수 있는 처지입니다.
Emacs의 대부분은 lisp입니다. 시스템의 능력에 비하면 실제 C 부분은 꽤 작습니다. Lisp가 그런 언어다 보니, 언어 전문성보다는 도메인 지식의 문제입니다.
위에 얹힌 lisp 구조에는 상당한 언어 전문성이 필요하다고 생각합니다. defvar, defconst, defcustom, alist, cl-loop 같은 Lisp다운 구문이 Emacs에서 아주 폭넓게 쓰이는데, 이걸 다루려면 Lisp 특유의 이해가 필요합니다. 물론 도메인은 이런 구문 자체에 대한 공통의 이해 위에 쌓입니다.
전 세계에 C 전문성이 계속 남아 있다 해도, emacs-lisp 전문성을 잃는 것은 상당한 손실이라고 봅니다.
패키지가 풍부하고 emacs-lisp 문서도 꽤 방대합니다. 무슨 난해한 언어도 아니고요. 제가 말하려던 건 패키지 코드가 꽤 단순하고 읽기 쉬울 수 있다는 점입니다.
결국 그냥 Lisp 방언일 뿐이고, 배우기도 Javascript보다 크게 복잡하지 않습니다. 유일하게 특이한 점은 동적 스코핑을 많이 쓴다는 건데, 제가 알기로 요즘은 렉시컬 스코핑도 쓸 수 있고 권장됩니다.
emacs 31 이후로 제 커스텀 Lisp 파일에서 이런 경고가 나오기 시작했습니다:
Warning (files): Missing ‘lexical-binding’ cookie in "~/.emacs.d/custom.el". You can add one with ‘M-x elisp-enable-lexical-binding RET’. See ‘(elisp)Selecting Lisp Dialect’ and ‘(elisp)Converting to Lexical Binding’ for more information. (경고(files): "~/.emacs.d/custom.el"에 ‘lexical-binding’ 쿠키가 없습니다. ‘M-x elisp-enable-lexical-binding RET’로 추가할 수 있습니다. 자세한 내용은 ‘(elisp)Selecting Lisp Dialect’와 ‘(elisp)Converting to Lexical Binding’을 참고하세요.)
아직도 어떻게 해야 할지 알아내는 중입니다! 매뉴얼은 꽤 장황한데, 끝까지 읽을 인내심이 아직 없었습니다.
파일을 열고 다음을 실행하면:
파일 맨 위에 쿠키(lexical-binding)가 추가됩니다. 직접 하려면 이렇게 넣으세요:
또는 이렇게요:
custom.el 파일 맨 위에요. 이제 명시하라고 하는 건 결국 lexical이 기본값이 될 것이기 때문입니다. 앞의 것을 넣으면 lexical이 기본값이 된 뒤에도 이 파일은 지금처럼 동적 바인딩을 계속 씁니다. 뒤의 것을 쓰면 문제가 있을 경우, 기본값이 바뀌어 놀라기 전에 지금 미리 발견할 수 있습니다.
해야 할 일을 정확히 알려 줬잖아요.
Emacs 안에서 claude한테 확장 기능을 즉석에서 구현해 달라고 하고, 그걸 실행 중인 프로세스에 주입한 다음 결과를 관찰하게 하고, 빠르게 반복해서 동작하는 해법까지 만들게 할 수 있다니, 믿기지 않아요.
Claude, 궁극의 REPL이에요.
저도 30년 넘은 emacs 클럽 회원입니다(몇 년 전 자바 때문에 jetbrains로 잠깐 외도했지만요). claude가 emacs 확장 기능을 구현하고 디버깅하는 데 이렇게 뛰어나다니 놀랍습니다. 컨테이너 안에 emacs를 설치해 두어서, 헤드리스로 emacs를 써서 뭐든 디버깅할 수 있게 해 놨습니다.
"에디터가 X를 했으면 좋겠다"고 말하면 제가 완전히 통제하는 에디터에서 거의 실시간으로 그대로 이뤄진다니 대단합니다. 예전에 elisp를 써 본 적은 있지만 제가 가장 약한 언어 중 하나라서, claude를 활용할 수 있다는 게 정말 좋습니다.
궁금합니다. elisp는 그런 일(실행 중인 프로세스를 수정하는 일)에 특히 강한가요? 저는 그런 시스템을 써 본 적이 없어서 궁금합니다.
어떤 Lisp든 실행 중인 프로세스를 수정하는 데 강합니다. REPL만 붙여 주면 됩니다. Lisp는 동형성(homoiconic)을 지니고 있어서 Read-Eval-Print-Loop의 모든 단계가 다르게 작동합니다. Lisp 사용자들은 Lisp REPL을 "진짜 REPL"이라고 부르기도 합니다. 동형성이 아닌 REPL은 그에 비하면 "대화형 셸"에 가깝기 때문입니다.
예를 들어 Clojurescript 사용자들은 nbb에 REPL을 연결해서, 에디터에서 곧바로 버튼을 대화식으로 "클릭"하고 DOM을 탐색하면서 웹 스크레이퍼를 만들 수 있습니다.
Emacs의 경우 [그냥] 에디터가 아니라, 기술적으로는 텍스트 에디터가 내장된 Lisp REPL 루프입니다. 그래서 한 번도 재시작하지 않고 사실상 모든 부분을 즉석에서 바꿀 수 있습니다.
놀라운 건 이 덕분에 거의 모든 것을 "프로그래밍 가능"하게 만들 수 있다는 점입니다. Emacs의 키보드 매크로조차 그저 Lisp 명령어의 나열입니다. 매크로를 만든 다음 그 밑의 코드를 보고, 수정하고, 실행할 수 있습니다.
Elisp는 동형성 언어이고 REPL 개발 문화도 강하지만, elisp가 정말 좋은 이유는 에디터를 반복 개선해 온 수십 년의 사용 역사가 있다는 점입니다. Common Lisp로 이를 시도하는 꽤 멋진 프로젝트로 Lem이 있지만, emacs와 elisp를 하나로 결합된 시스템으로 만드는 데 들어간 어마어마한 인년(person-years)이 쓰고 반복 개선하기에 즐거운 환경을 만들어 줍니다. 그에 비해 Lem은 elisp에서는 기본으로 갖춰져 있는 "라이브 프로그래밍 환경" 관련 UX를 하나씩 쌓아 가는 중입니다(저는 개인적으로 언어/환경으로는 Common Lisp를 선호하지만요).
LLM 이전에는 회사에서 의욕이 좀 떨어질 때 가끔 오후 시간을 써서 emacs에 새 기능을 추가하거나 환경의 사소한 불편을 고치곤 했습니다. 지금은 대부분 LLM이 대신 작업하게 하되, 설정에서 따로 불러오게 해서 LLM이 쓴 코드와 제 코드를 분리해 둡니다.
런타임에 광범위하게 다시 로드할 수 있는 환경과 언어는 여럿 있습니다. elisp가 좋은 건 주로 잘 다듬어져 있기 때문이지, 꼭 "최고"라서는 아닙니다. Erlang이 더 낫다고 주장할 만할 겁니다. 그리고 대부분의 스크립트 언어가 그런 일을 할 수 있다고 해서, 아무거나 가져다 놓으면 바로 된다는 뜻은 아닙니다. 그런 상호작용성이 일급 기능이고 끊임없이 쓰이고 테스트되는 환경이어야 도움이 되는데, 다듬어진 완성도는 거기서 나옵니다.
런타임으로서의 Erlang은 분명 그렇습니다. 하지만 Emacs는 이런 속성을 가진 애플리케이션입니다. Erlang용 Emacs 같은 에디터는 없고(작은 클론들은 있겠지만) 이 기능을 활용하는 다른 사용자용 애플리케이션도 없습니다.
Smalltalk는 개발 환경이자 애플리케이션 플랫폼입니다. 개발 도구가 Emacs만큼 확장 가능하고 사용자가 커스텀할 수 있습니다. 그리고 Erlang처럼 소프트웨어를 패키징해 올릴 수 있는 런타임이기도 합니다. GUI든 서버 소프트웨어든 가능합니다. Emacs로도 아마 같은 일을 할 수 있겠지만, GUI를 익숙하게 느낄 사용자가 많을지는 잘 모르겠습니다.
claude와 상호작용하는 데 어떤 패키지를 쓰시나요?
질문받은 당사자는 아니지만요.
저는 agent-shell을 쓰는데, 거기서 만들어지고 있는 생태계가 정말 마음에 듭니다:
https://github.com/xenodium/agent-shell
그리고 claude가 emacs와 다시 상호작용하게 하는 방법은 이렇습니다:
MCP 패키지를 쓰는 사람들도 있습니다. 그쪽이 통제권을 조금 더 준다는 데는 동의합니다. 하지만 저는 위험하게 삽니다. emacs를 데몬 모드로 돌리고 claude에게 필요할 때 emacsclient로 elisp를 실행하라고 시킵니다. 놀랄 만큼 잘 됩니다. Claude는 제 에디터를 완전히 볼 수 있고, 우리는 함께 거의 뭐든 할 수 있습니다.
사실 저는 emacs를 점점 그냥 살아 있는 lisp 머신으로 생각하게 됩니다. 저와 에이전트들이 함께 상호작용하는 표면이죠. 문서 저장소, 데이터베이스, 제어판 같은 역할을 합니다.
저도 agent-shell을 강력히 추천합니다. Claude와 하는 모든 작업에 이걸 씁니다.
저는 claude-code.el과 monet.el을 쓰는데, 이후 claude에게 여러 방식으로 확장하게 했습니다. monet의 /ide 지원을 통해 executeCode를 노출하는 것도 그중 하나입니다.
claude는 REPL이 아니에요. claude가 "반복"할 수 있게 해 준 건 emacs고요. 게다가 claude는 "반복"을 하는 것도 아니에요. 그렇게 하라고 시키는 건 당신이잖아요.
저도 그렇습니다! /[usr]/bin/에 있는 기본 유닉스 도구를 빼면, emacs만큼 오래 살아남은 소프트웨어는 거의 없습니다. 저는 1992년에 vi에서 emacs로 완전히 갈아탔고 그 뒤로 매일 열심히 써 왔습니다. 정말 좋습니다.
(그 시절 프로그램 중에 지금도 쓰는 건 USENET을 읽는 trn 정도뿐입니다)
50살인데도 "미래의 에디터"라며 팔려는 어떤 쓰레기들보다 더 현대적으로 느껴져요. Emacs는 과거, 현재, 그리고 먼 미래의 진짜 에디터예요.
모달 편집이 사용자를 빼앗아 갈 거라고 했죠. Evil 모드는 vim 하기를 더 낫게 만들었어요. LSP가 Emacs를 죽일 거라고 했죠. 오히려 더 좋게만 만들었어요. Electron 기반 쓰레기들이 내장 터미널, 확장 기능, 세련된 UI로 터미널 네이티브 에디터를 구닥다리로 보이게 만들 거라고 했죠. Emacs에는 vterm, eat, ghostel이 생겼어요. GitKraken 같은 GUI가 git CLI를 불필요하게 만들 거라고 했죠. Magit은 GUI든 아니든 존재하는 어떤 git 클라이언트보다 낫다는 평가를 널리 받아요. Tree-sitter는 정확한 파싱을 위해 "진짜" 언어 서버 아키텍처가 필요하게 만들 거라고 했죠. Emacs 29가 이를 네이티브로 흡수했고, 여러 메이저 모드에서 font-lock, 들여쓰기, 구조적 탐색이 눈에 띄게 좋아졌어요. Obsidian과 Notion이 계속 극복하려 하지만 Org-mode는 계속 더 좋아지기만 해요. AI가 Emacs를 구식으로 만들 거라고 했죠. 오히려 강화하기만 했어요.
반세기 동안 인류는 Emacs 킬러를 찾아 헤맸어요. 그동안 내내 Emacs가 킬러 앱이었는데도요.