# Emacs에서는 모든 것이 서비스처럼 보인다

> Clean Markdown view of GeekNews topic #31336. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31336](https://news.hada.io/topic?id=31336)
- GeekNews Markdown: [https://news.hada.io/topic/31336.md](https://news.hada.io/topic/31336.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-07-12T03:48:20+09:00
- Updated: 2026-07-12T03:48:20+09:00
- Original source: [yummymelon.com](http://yummymelon.com/devnull/in-emacs-everything-looks-like-a-service.html)
- Points: 1
- Comments: 1

## Topic Body

- 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 안에서만 생활한다**”는 발상도 성립함

### 요청과 응답으로 보는 클라이언트-서버 모델
- [클라이언트-서버 모델](https://en.wikipedia.org/wiki/Client%E2%80%93server_model)은 자원을 제공하는 **서비스**와 이를 요청하는 **클라이언트**가 작업을 나누는 상호작용 패턴임
  - 클라이언트가 요청을 보냄
  - 서버가 요청을 처리한 뒤 응답을 반환함
- 요청과 응답으로 이뤄진 트랜잭션은 네트워크를 통하거나 한 시스템 안에서 로컬로 수행될 수 있음
- 네트워크 기반 모델은 [REST 스타일 소프트웨어 아키텍처](https://en.wikipedia.org/wiki/REST)에서 폭넓게 발전함

### Emacs 클라이언트를 이루는 세 영역
- 일반적인 클라이언트는 다음 세 영역을 담당함
  - **UI:** 필요에 따라 사용자 입력과 출력을 처리함
  - **클라이언트 경계(Client Edge):** 서비스와 통신하며, 네트워크 클라이언트에서는 네트워크 하위 시스템이 이 역할을 맡음
  - **로컬 데이터베이스:** 서버와 교환하거나 동기화할 데이터를 표현하며, 구체적인 관리 방식은 구현 요구사항에 따라 달라짐
- ## 사용자 인터페이스 구성
  - Emacs는 클라이언트 UI를 만들 수 있는 여러 내장 기능을 제공함
  - [Minibuffers](https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffers.html)
  - [Buffers](https://www.gnu.org/software/emacs/manual/html_node/elisp/Buffers.html)
  - [Completion](https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html)
  - [Tabulated List Mode](https://www.gnu.org/software/emacs/manual/html_node/elisp/Tabulated-List-Mode.html)
  - [Variable Pitch Table(vtable)](https://www.gnu.org/software/emacs/manual/html_node/vtable/)
  - [Transient](https://www.gnu.org/software/emacs/manual/html_node/transient/)
- ## 서비스 통신과 데이터 변환
  - 서비스에 연결되는 **클라이언트 경계**에는 다음 기능을 활용할 수 있음
    - [URL](https://www.gnu.org/software/emacs/manual/html_node/url/)
    - [Socket(TCP/UDP)](https://www.gnu.org/software/emacs/manual/html_node/elisp/Network.html)
    - [SMTP](https://www.gnu.org/software/emacs/manual/html_node/smtpmail/)
  - 직렬화와 역직렬화에는 내장 파서를 이용함
    - [JSON](https://www.gnu.org/software/emacs/manual/html_node/elisp/Parsing-JSON.html)
    - [XML](https://www.gnu.org/software/emacs/manual/html_node/elisp/Parsing-HTML_002fXML.html)
- ## 로컬 데이터 관리
  - 서버 데이터의 로컬 표현에는 Elisp 컬렉션을 활용할 수 있음
    - [Association Lists](https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html)
    - [Property Lists](https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Lists.html)
    - [Hash Tables](https://www.gnu.org/software/emacs/manual/html_node/elisp/Hash-Tables.html)
  - 영속적인 로컬 저장소가 필요하면 [SQLite](https://www.gnu.org/software/emacs/manual/html_node/elisp/Database.html)를 사용할 수 있음
  - 실제 클라이언트의 복잡도는 요구사항에 따라 달라지며, 무거운 처리를 담당할 기존 명령줄 유틸리티가 있다면 **셸 호출로 접근하는 서비스**로 재구성할 수 있음

### Elisp로 기능을 결합하는 방식
- 앞의 라이브러리는 모두 [Emacs Lisp(Elisp)](https://www.gnu.org/software/emacs/manual/html_node/elisp/)에서 접근할 수 있음
- Elisp는 실행 중 높은 수준의 즉흥적 구성을 허용하는 **동적 프로그래밍 언어**임
- Elisp 함수부터 셸 명령까지 Emacs가 사용할 수 있는 동작을 결합해 복잡한 흐름을 조율할 수 있음

### wttr.in 날씨 클라이언트 구현
- [wttr.in](https://github.com/chubin/wttr.in)은 콘솔 중심의 일기예보 웹 서비스이며 [JSON 출력](https://github.com/chubin/wttr.in#different-output-formats)을 지원함
- Emacs용 `wttr` 명령은 다음 순서로 동작함
  1. 사용자에게 위치를 입력받음
  2. wttr.in 요청 URL을 생성함
  3. HTTP 요청을 전송함
  4. JSON 응답을 처리함
  5. 결과를 미니버퍼에 표시하고 kill ring에 저장함
  6. 처리 중 오류가 발생하면 미니버퍼에 오류 메시지를 표시함
- ## 요청 URL 만들기
  - `wttr--request-url`은 `https://wttr.in`을 기본 URL로 사용함
  - 입력한 위치의 공백을 `+`로 바꾸고 `/&lt;location&gt;?0&format=j1` 형태의 쿼리를 생성함
  - 완성된 URL은 이후 **JSON 가져오기 함수**로 전달됨
- ## HTTP 요청과 JSON 파싱
  - `fetch-json-as-hash-table`은 `url-retrieve-synchronously`로 URL을 동기적으로 가져옴
  - 데이터를 받지 못하면 `Failed to fetch data from &lt;URL&gt;` 오류를 발생시킴
  - 응답 버퍼에서 HTTP 메타데이터 헤더 뒤로 이동한 다음, `json-parse-buffer`로 나머지 내용을 Elisp **`hash-table`** 로 변환함
  - 처리가 끝나면 내려받은 네트워크 버퍼를 항상 제거해 메모리 누수를 방지함
- ## 날씨 메시지 조합
  - `wttr--report-message`는 JSON 데이터에서 다음 값을 추출함
    - 가장 가까운 지역의 이름
    - 지역
    - 국가
    - 현재 섭씨 기온 `temp_C`
    - 현재 화씨 기온 `temp_F`
    - 날씨 설명 `weatherDesc`
  - 비어 있지 않은 위치 요소를 쉼표로 연결하고 `위치: 섭씨, 화씨 날씨 설명` 형식의 결과를 만듦
  - 전체 구현은 [wttr.el 소스](https://gist.github.com/kickingvegas/40290cef2751c133666eb19921f91eee)에서 확인할 수 있음

### 명령줄 도구도 서비스로 활용하기
- Emacs API는 높은 수준의 추상화를 제공하며, HTTP 요청과 JSON 처리를 직접 구현한 `wttr.el`도 `cloc` 측정 기준 **67줄**임
- 더 단순한 대안은 실제 네트워크 요청과 JSON 처리를 `weather`라는 Python 스크립트에 맡기는 방식임
  - Elisp의 `weather` 명령이 사용자에게 위치를 입력받음
  - 위치를 인자로 붙여 `weather` 셸 명령을 구성함
  - `shell-command-to-string`으로 명령을 실행함
  - 반환 결과를 kill ring에 저장하고 미니버퍼에 표시함
- 이 구성에서는 **셸 명령이 요청을 받는 서비스**가 되고 Elisp 함수가 클라이언트 역할을 맡음
- Elisp의 동적 특성 덕분에 Elisp 라이브러리와 명령줄 유틸리티를 필요에 따라 결합할 수 있으며, 이런 통합 가능성이 Emacs 안에서 모든 것을 서비스처럼 다룰 수 있게 함

## Comments



### Comment 61636

- Author: neo
- Created: 2026-07-12T03:48:21+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48857230) 
- **Lisp Machine** 계열이 주류로 자리 잡지 못했기 때문에 Emacs가 운영체제처럼 비칠 뿐임  
  “Symbolics Lisp Machine demo”  
  [https://www.youtube.com/watch?v=o4-YnLpLgtk](<https://www.youtube.com/watch?v=o4-YnLpLgtk>)  
  “Emacs and Lisp”  
  [https://funcall.blogspot.com/2025/04/emacs-and-lisp.html](<https://funcall.blogspot.com/2025/04/emacs-and-lisp.html>)  
  Lucid는 초기 LSP 발상 중 하나를 구현하려고 Emacs를 **XEmacs**로 포크했으며, 당시 기능 대부분은 이제 Emacs에 다시 통합됨  
  [https://dreamsongs.com/Cadillac.html](<https://dreamsongs.com/Cadillac.html>)  
  “Lucid Energize Demo”  
  [https://www.youtube.com/watch?v=pQQTScuApWk](<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가 무조건 우월하다기보다 다른 도구가 더 제한적이고 자체 문서화가 부족함
  - 모든 팀원이 같은 도구를 써야 한다는 주장이 왜 타당한지 의문임

- 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`을 직접 구성해볼 생각임

- Emacs는 텍스트 편집기가 내장된 **프로그래밍 환경**에 더 가까움. 일부 Smalltalk 이미지와 비슷하다고 보면 꽤 흥미로운 도구임

- Emacs는 운영체제가 아니라 **셸**에 가깝지만, 셸이라는 개념 자체가 널리 이해되지는 않음
  - 셸을 다른 도구를 사용하는 수단으로 본다면 `vi`가 오히려 셸에 더 가까움. 많은 기능을 `:.!`로 다른 표준 Unix 프로그램에 맡겨야 하기 때문임  
    반면 Emacs는 운영체제처럼 온갖 기능을 하나의 거대한 배포판에 포함

- Emacs를 쓰지 않는 사람에게 보여주기 좋은 짧은 **입문 영상**을 최근 발견함  
  [https://www.youtube.com/watch?v=mJZDmO5yOxE](<https://www.youtube.com/watch?v=mJZDmO5yOxE>)
  - Anon Emoose의 `init.el`이 정말 궁금해짐

- Emacs 자체를 **클라이언트와 서버**로 실행할 수 있음. `emacs --daemon`으로 서버를 시작한 뒤 `emacsclient`로 연결하면 터미널과 GUI의 모든 인스턴스가 같은 서버를 사용하며 열린 파일과 버퍼를 공유함  
  아쉽게도 로컬에서만 동작했고, Emacs 서버 소켓을 ssh로 전달해 원격 클라이언트에서 연결하려 했지만 실패함
  - 돌이켜 보면 `emacsclient`라는 이름은 좋지 않았음. 2026년에 Emacs를 처음 접하는 사람은 REST 클라이언트처럼 네트워크를 통해 클라이언트와 서버의 실행 상태를 동기화한다고 기대하기 쉬움  
    여기서 클라이언트와 서버는 Unix 로컬 도메인, 즉 파일 시스템 소켓을 통해 클라이언트가 간단한 제어 명령을 보내는 구조를 뜻함. 이후 네트워크 소켓도 지원하게 됐지만 클라이언트가 보내는 것은 여전히 단순한 제어 명령뿐임
  - 소켓 전달은 안 되지만 X11을 사용한다면 `ssh -X`로 원격 Emacs의 프레임을 로컬 X 서버에 띄울 수 있음. 단, **비-PGTK GTK 빌드**에서는 새 프레임을 닫을 때 원격 Emacs가 충돌할 수 있으니 주의해야 함
  - 소켓 전달이 실패한 원인을 확인했는지 궁금함
