Emacs에서는 모든 것이 서비스처럼 보인다
(yummymelon.com)- Emacs는 운영체제 자체라기보다 커널 위의 애플리케이션과 유틸리티를 조율하며, 파일 시스템·네트워크·외부 프로그램을 활용해 다양한 서비스의 클라이언트가 됨
- 클라이언트에 필요한 UI·통신 계층·로컬 데이터 저장소를 미니버퍼, 버퍼, URL, TCP/UDP, JSON, SQLite 같은 내장 라이브러리로 구성할 수 있음
- 동적 언어인 Emacs Lisp(Elisp) 는 Elisp 함수와 셸 명령을 실행 중에 결합해, Emacs가 접근할 수 있는 기능을 유연하게 조율함
- 예제
wttr명령은 위치를 입력받아 wttr.in에 HTTP 요청을 보내고, JSON에서 지역·기온·날씨를 추출해 미니버퍼에 표시한 뒤 kill ring에도 저장함 - 전체
wttr.el은cloc기준 67줄이며, 네트워크 요청과 JSON 처리를 Python 같은 명령줄 도구에 맡기면 셸 명령 자체를 서비스로 삼는 더 짧은 Elisp 클라이언트도 만들 수 있음
운영체제 위에서 서비스를 조율하는 Emacs
- Emacs를 운영체제라고 부르는 표현은 정확하지 않지만, 운영체제 커널 위에서 애플리케이션과 유틸리티를 조율하는 능력 때문에 이런 비교가 생김
- 파일 시스템과 네트워크 같은 운영체제 서비스에 내장 기능으로 접근하고 다른 프로그램도 실행할 수 있어, Emacs 안에서 클라이언트 동작을 즉석에서 구성하기 쉬움
- 여러 클라이언트 모드로 많은 컴퓨팅 작업을 처리할 수 있으므로 사용자가 “Emacs 안에서만 생활한다”는 발상도 성립함
요청과 응답으로 보는 클라이언트-서버 모델
- 클라이언트-서버 모델은 자원을 제공하는 서비스와 이를 요청하는 클라이언트가 작업을 나누는 상호작용 패턴임
- 클라이언트가 요청을 보냄
- 서버가 요청을 처리한 뒤 응답을 반환함
- 요청과 응답으로 이뤄진 트랜잭션은 네트워크를 통하거나 한 시스템 안에서 로컬로 수행될 수 있음
- 네트워크 기반 모델은 REST 스타일 소프트웨어 아키텍처에서 폭넓게 발전함
Emacs 클라이언트를 이루는 세 영역
- 일반적인 클라이언트는 다음 세 영역을 담당함
- UI: 필요에 따라 사용자 입력과 출력을 처리함
- 클라이언트 경계(Client Edge): 서비스와 통신하며, 네트워크 클라이언트에서는 네트워크 하위 시스템이 이 역할을 맡음
- 로컬 데이터베이스: 서버와 교환하거나 동기화할 데이터를 표현하며, 구체적인 관리 방식은 구현 요구사항에 따라 달라짐
-
사용자 인터페이스 구성
- Emacs는 클라이언트 UI를 만들 수 있는 여러 내장 기능을 제공함
- Minibuffers
- Buffers
- Completion
- Tabulated List Mode
- Variable Pitch Table(vtable)
- Transient
-
서비스 통신과 데이터 변환
- 서비스에 연결되는 클라이언트 경계에는 다음 기능을 활용할 수 있음
- 직렬화와 역직렬화에는 내장 파서를 이용함
-
로컬 데이터 관리
- 서버 데이터의 로컬 표현에는 Elisp 컬렉션을 활용할 수 있음
- 영속적인 로컬 저장소가 필요하면 SQLite를 사용할 수 있음
- 실제 클라이언트의 복잡도는 요구사항에 따라 달라지며, 무거운 처리를 담당할 기존 명령줄 유틸리티가 있다면 셸 호출로 접근하는 서비스로 재구성할 수 있음
Elisp로 기능을 결합하는 방식
- 앞의 라이브러리는 모두 Emacs Lisp(Elisp)에서 접근할 수 있음
- Elisp는 실행 중 높은 수준의 즉흥적 구성을 허용하는 동적 프로그래밍 언어임
- Elisp 함수부터 셸 명령까지 Emacs가 사용할 수 있는 동작을 결합해 복잡한 흐름을 조율할 수 있음
wttr.in 날씨 클라이언트 구현
- wttr.in은 콘솔 중심의 일기예보 웹 서비스이며 JSON 출력을 지원함
- Emacs용
wttr명령은 다음 순서로 동작함- 사용자에게 위치를 입력받음
- wttr.in 요청 URL을 생성함
- HTTP 요청을 전송함
- JSON 응답을 처리함
- 결과를 미니버퍼에 표시하고 kill ring에 저장함
- 처리 중 오류가 발생하면 미니버퍼에 오류 메시지를 표시함
-
요청 URL 만들기
wttr--request-url은https://wttr.in을 기본 URL로 사용함- 입력한 위치의 공백을
+로 바꾸고/<location>?0&format=j1형태의 쿼리를 생성함 - 완성된 URL은 이후 JSON 가져오기 함수로 전달됨
-
HTTP 요청과 JSON 파싱
fetch-json-as-hash-table은url-retrieve-synchronously로 URL을 동기적으로 가져옴- 데이터를 받지 못하면
Failed to fetch data from <URL>오류를 발생시킴 - 응답 버퍼에서 HTTP 메타데이터 헤더 뒤로 이동한 다음,
json-parse-buffer로 나머지 내용을 Elisphash-table로 변환함 - 처리가 끝나면 내려받은 네트워크 버퍼를 항상 제거해 메모리 누수를 방지함
-
날씨 메시지 조합
wttr--report-message는 JSON 데이터에서 다음 값을 추출함- 가장 가까운 지역의 이름
- 지역
- 국가
- 현재 섭씨 기온
temp_C - 현재 화씨 기온
temp_F - 날씨 설명
weatherDesc
- 비어 있지 않은 위치 요소를 쉼표로 연결하고
위치: 섭씨, 화씨 날씨 설명형식의 결과를 만듦 - 전체 구현은 wttr.el 소스에서 확인할 수 있음
명령줄 도구도 서비스로 활용하기
- Emacs API는 높은 수준의 추상화를 제공하며, HTTP 요청과 JSON 처리를 직접 구현한
wttr.el도cloc측정 기준 67줄임 - 더 단순한 대안은 실제 네트워크 요청과 JSON 처리를
weather라는 Python 스크립트에 맡기는 방식임- Elisp의
weather명령이 사용자에게 위치를 입력받음 - 위치를 인자로 붙여
weather셸 명령을 구성함 shell-command-to-string으로 명령을 실행함- 반환 결과를 kill ring에 저장하고 미니버퍼에 표시함
- Elisp의
- 이 구성에서는 셸 명령이 요청을 받는 서비스가 되고 Elisp 함수가 클라이언트 역할을 맡음
- Elisp의 동적 특성 덕분에 Elisp 라이브러리와 명령줄 유틸리티를 필요에 따라 결합할 수 있으며, 이런 통합 가능성이 Emacs 안에서 모든 것을 서비스처럼 다룰 수 있게 함
댓글과 토론
Hacker News 의견들
-
Lisp Machine 계열이 주류로 자리 잡지 못했기 때문에 Emacs가 운영체제처럼 비칠 뿐임
“Symbolics Lisp Machine demo”
https://www.youtube.com/watch?v=o4-YnLpLgtk
“Emacs and Lisp”
https://funcall.blogspot.com/2025/04/emacs-and-lisp.html
Lucid는 초기 LSP 발상 중 하나를 구현하려고 Emacs를 XEmacs로 포크했으며, 당시 기능 대부분은 이제 Emacs에 다시 통합됨
https://dreamsongs.com/Cadillac.html
“Lucid Energize Demo”
https://www.youtube.com/watch?v=pQQTScuApWk- 운영체제는 여러 프로그램이 공유하도록 만든 가상 머신임. 보통은 자신이 실행되는 명령어 집합 구조(ISA)의 대부분을 노출하지만 Inferno, Taos, AS/400 같은 예외도 있음
- LISP 머신이 성공했더라도 그 위에서 실행되는 편집기가 운영체제가 되지는 않음. 플랫폼과 운영체제를 혼동하면 웹 브라우저나 심지어 Roblox까지 운영체제라고 부를 수 있게 됨
-
client,server,request를 충분히 넓게 정의하면 무엇이든 클라이언트/서버 구조에 끼워 맞출 수 있음. LISP 함수가 한 가지 일을 잘 수행한다는 이유만으로 Emacs가 Unix 철학을 따른다고 애써 주장하던 것과 비슷함
Emacs가 LISP 머신의 발상을 따른다는 데는 대부분 동의할 수 있고, 그 위에서 사실상 원하는 무엇이든 구현할 수 있음. CLI 도구와 훌륭하게 연동되지만 이를 클라이언트/서버라고 정의해서 무엇을 얻는지는 불분명함
수십 년간 여러 유행을 거치며 기능을 흡수해 왔고, 내부에는 지금 거의 쓰이지 않는 CEDET 의미 분석 엔진도 있음. 이후 LSP가 등장했고, 이제는 에이전트 시대인데 Emacs는 에이전트용 프런트엔드로도 꽤 괜찮음- Emacs는 Unix 세계로 피신한 LISP 난민임. Unix 철학이 아니라 LISP 철학을 따르지만 Unix와 잘 통합됨
- 과거에는 대부분의 IDE가 자체 의미 분석 엔진을 갖는 것이 흔했음. 최초의 Java 언어 서버도 Eclipse의 Java 의미 분석 엔진에서 분리돼 나온 것으로 기억함
-
Emacs를 25년 넘게 사용했지만 지난해 이직한 회사에서는 Emacs가 특히 잘 맞는 작업에도 쓰지 못하게 함. 모든 팀원이 같은 도구를 써야 한다는 이유였고, 다른 사람들을 Emacs로 전환시키는 데는 실패함
이제 작업마다 별도의 단일 목적 도구를 훨씬 비효율적으로 사용하면서 새로운 UI와 키 매핑까지 계속 익히는 중임- 회사가 커지면서 설치 소프트웨어를 통제하기 시작했고, Microsoft Intune으로 설치 허용·차단을 관리하는 듯함. Emacs를 더는 쓰지 못할까 봐 노트북 업데이트나 교체도 미루고 있음
관리자는 새 프로젝트에서 모두 Visual Studio Code를 쓰자고 하겠지만, 사용하는 소비 모델은 VSCode도 지원하지 않음. Git과 배포 절차만 맞춘다면 편집기는 각자 잘 쓰는 것을 선택해도 되는데, Microsoft가 지원하지 않는 오픈 소스라 위험하고 회사가 검증하지 않은 소프트웨어라는 답이 돌아올 것 같음
Emacs는 매일 쓰는 핵심 도구라 금지된다면 사직할 생각임. 관리자는 이해하거나 논리적으로 판단하려는 게 아니라 다른 IT 부서의 지시를 따를 뿐임 - 모든 팀원에게 telnet을 쓰게 하고 ssh를 금지해도 타당하다고 할 것인가? Emacs 사용 허가를 묻지 말고 그냥 쓰는 것이 중요함
회사가 범용 텍스트 편집기를 지정했다면 Notepad를 실행해도 문제가 되는지, 개인용 할 일 관리 도구까지 지정했는지 확인해볼 만함. Emacs가 수행할 수 있으면서 아직 회사가 도구를 지정하지 않은 범주를 찾아 그 용도로 설치하면 됨 - 서로 다른 성격을 관리하려면 사람마다 다르게 대해야 해서 비효율적이니, 팀원 전원에게 전두엽 절제술을 시행했다는 논리와 같음
- 다른 도구에도 Emacs만큼의 자유와 개조 가능성이 있었다면 Emacs 사용자도 모든 업무를 그 안에 욱여넣으려 하지 않았을 것임. Emacs가 무조건 우월하다기보다 다른 도구가 더 제한적이고 자체 문서화가 부족함
- 모든 팀원이 같은 도구를 써야 한다는 주장이 왜 타당한지 의문임
- 회사가 커지면서 설치 소프트웨어를 통제하기 시작했고, Microsoft Intune으로 설치 허용·차단을 관리하는 듯함. Emacs를 더는 쓰지 못할까 봐 노트북 업데이트나 교체도 미루고 있음
-
Emacs는 플랫폼이고 운영체제 역시 여러 플랫폼 중 하나임. 플랫폼은 그 위에 새로운 것을 만들 수 있도록 설계된 소프트웨어 계층이므로, 만들려는 Y에 어떤 플랫폼 X가 적합한지를 물어야 함
내게 X는 Emacs일 때가 많지만 Racket이나 Rust일 수도 있음. 응용 프로그램이면서 좋은 플랫폼이기도 한 도구라면 단순한 응용 프로그램보다 더 많은 학습 투자를 할 가치가 있음 -
Emacs를 충분히 사용해 “Emacs는 운영체제다”라는 말을 농담이 아니라 실제로 믿을 수 있는 개념으로 이해한 순간이 경력의 중요한 전환점이 됨
- 이미 운영체제도 있었고 프로그래밍도 할 수 있었는데 Emacs가 정말 새로운 능력을 제공했는지는 의문임. Emacs는 IDE나 범용 자동화 실행 환경이 아니라 텍스트 편집기인데, MSPaint에 Lisp를 추가한다고 갑자기 대단한 도구가 된다는 논리는 이해하기 어려움
-
org mode를 써보려고 몇 년 전 Emacs를 시작했고, 극단적으로 높은 유연성 때문에 계속 사용하게 됨
- 한동안 Spacemacs를 사용했지만 Caps Lock을 재프로그래밍할 수 있는 Keychron G6 Pro를 구했으니, 이제 본격적으로
init.el을 직접 구성해볼 생각임
- 한동안 Spacemacs를 사용했지만 Caps Lock을 재프로그래밍할 수 있는 Keychron G6 Pro를 구했으니, 이제 본격적으로
-
Emacs는 텍스트 편집기가 내장된 프로그래밍 환경에 더 가까움. 일부 Smalltalk 이미지와 비슷하다고 보면 꽤 흥미로운 도구임
-
Emacs는 운영체제가 아니라 셸에 가깝지만, 셸이라는 개념 자체가 널리 이해되지는 않음
- 셸을 다른 도구를 사용하는 수단으로 본다면
vi가 오히려 셸에 더 가까움. 많은 기능을:.!로 다른 표준 Unix 프로그램에 맡겨야 하기 때문임
반면 Emacs는 운영체제처럼 온갖 기능을 하나의 거대한 배포판에 포함
- 셸을 다른 도구를 사용하는 수단으로 본다면
-
Emacs를 쓰지 않는 사람에게 보여주기 좋은 짧은 입문 영상을 최근 발견함
https://www.youtube.com/watch?v=mJZDmO5yOxE- Anon Emoose의
init.el이 정말 궁금해짐
- Anon Emoose의
-
Emacs 자체를 클라이언트와 서버로 실행할 수 있음.
emacs --daemon으로 서버를 시작한 뒤emacsclient로 연결하면 터미널과 GUI의 모든 인스턴스가 같은 서버를 사용하며 열린 파일과 버퍼를 공유함
아쉽게도 로컬에서만 동작했고, Emacs 서버 소켓을 ssh로 전달해 원격 클라이언트에서 연결하려 했지만 실패함- 돌이켜 보면
emacsclient라는 이름은 좋지 않았음. 2026년에 Emacs를 처음 접하는 사람은 REST 클라이언트처럼 네트워크를 통해 클라이언트와 서버의 실행 상태를 동기화한다고 기대하기 쉬움
여기서 클라이언트와 서버는 Unix 로컬 도메인, 즉 파일 시스템 소켓을 통해 클라이언트가 간단한 제어 명령을 보내는 구조를 뜻함. 이후 네트워크 소켓도 지원하게 됐지만 클라이언트가 보내는 것은 여전히 단순한 제어 명령뿐임 - 소켓 전달은 안 되지만 X11을 사용한다면
ssh -X로 원격 Emacs의 프레임을 로컬 X 서버에 띄울 수 있음. 단, 비-PGTK GTK 빌드에서는 새 프레임을 닫을 때 원격 Emacs가 충돌할 수 있으니 주의해야 함 - 소켓 전달이 실패한 원인을 확인했는지 궁금함
- 돌이켜 보면