
Emacs 31 출시 임박: 내가 이미 매일 사용 중인 변화들
요약
Emacs 31 출시를 앞두고 새롭게 도입될 핵심 기능들을 미리 살펴보는 글입니다. 특히 Tree-sitter 설정 과정이 자동화되어 별도의 패키지 없이도 구문 분석 기능을 편리하게 사용할 수 있게 된 변화를 중점적으로 다룹니다.
핵심 포인트
- Emacs 31에서 Tree-sitter 설정 및 문법 설치 과정이 대폭 자동화됨
- treesit-auto-install-grammar를 통해 문법 누락 시 자동 빌드 제안 가능
- treesit-enabled-modes 설정으로 Tree-sitter 기반 메이저 모드 자동 전환
- 외부 패키지 의존성 없이 코어 기능만으로 향상된 개발 환경 제공
Emacs 31 출시 임박: 내가 이미 매일 사용 중인 변화들

Karthik Chikmagalur는 최근 그의 훌륭한 시리즈 중 하나인 "Even More Batteries Included with Emacs" 포스트를 통해, 현재 Emacs에 이미 포함되어 있는 덜 알려진 기능들을 깊이 있게 다루었습니다. 저는 그와 반대되는 내용을 쓰고 싶었습니다. 그의 포스트가 이미 박스 안에 들어있는 배터리(기본 기능)를 다룬다면, 저의 포스트는 Emacs 31에 도착할 배터리들을 다룹니다.
Emacs 31은 아직 출시되지 않았지만, 저는 emacs-31 브랜치와 master 브랜치 양쪽 모두에서 빌드하여 수개월 동안 매일 사용(daily driving)해 왔습니다. 새롭고 유용한 기능이 추가될 때마다, 저는 이를 외부 패키지가 없는 저만의 설정인 Emacs Solo에 포함시키고, 정식 출시 후에 다시 확인하기 위해 ; EMACS-31이라는 작은 주석을 달아둡니다.
이 포스트는 그 흔적들을 따라갑니다. 아래의 모든 변화는 제가 현재 설정에서 직접 만지고 있는 것들이며, 각 기능이 무엇을 하는지, 그리고 왜 유지하고 있는지에 대한 메모를 포함합니다. 이 중 어떤 것도 패키지를 필요로 하지 않습니다. 모두 이미 master에 있거나 곧 추가될 예정입니다.
한 가지 주의사항이 있습니다: Emacs 31은 아직 개발 중(실제로는 프리릴리스(pre-release) 단계)이므로, 최종 출시 전까지 이름과 기본값이 변경될 수 있습니다. 아래의 모든 내용은 2026년 중반 기준으로 제가 실행하고 있는 내용입니다. 만약 emacs-31 브랜치나 master에서 빌드하여 사용하고 있지 않다면, 이 글을 곧 다가올 기능들에 대한 프리뷰로 간주하십시오.
그냥 바로 작동하는 Tree-sitter
제가 가장 기뻐하는 단 하나의 변화를 꼽아야 한다면, 바로 이것입니다. 수년 동안 *-ts-mode를 사용하려면 treesit-language-source-alist를 수동으로 채우고, treesit-install-language-grammar를 호출하며, 문법(grammar)을 컴파일할 수 있도록 툴체인이 설정되어 있기를 기도해야 했습니다. Emacs 31에서는 이러한 번거로운 절차의 상당 부분이 사라집니다:
(treesit-auto-install-grammar t) ; EMACS-31
(treesit-enabled-modes t) ; EMACS-31
treesit-enabled-modes를 t로 설정하면 Tree-sitter 변형이 있는 메이저 모드(major modes)들을 해당 모드로 전환하며, treesit-auto-install-grammar는 문법이 누락되었을 때 에러를 내는 대신 Emacs가 문법을 가져와서 빌드할 것을 제안하게 만듭니다. 이것이 treesit-auto입니다.
패키지 경험(package experience)이었으나, 이제는 코어(core)가 그 작업을 수행합니다.
이러한 연쇄 효과는 제 설정(config) 곳곳에서 나타납니다. 이전에는 각 문법(grammar)이 어디에 있는지 Emacs에게 알려주기 위해 다음과 같은 코드들을 유지해 왔습니다:
(add-to-list 'treesit-language-source-alist
'(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src"))
Emacs 31에서는 TypeScript, TSX, Rust, TOML, YAML, Dockerfile과 같은 언어의 문법 소스(grammar sources)가 각 모드(mode) 내부에 포함되어 있습니다. 그래서 저는 ;; EMACS-31 this is now defined on mode code라는 주석을 남겨두었는데, 이는 31 버전이 출시되면 삭제할 수 있는 블록들을 표시해 둔 것입니다. 동일한 작업을 수행하면서 설정(config)은 더 줄어든다면 저는 언제든 환영입니다.

Emacs에는 더 많은 tree-sitter 개선 사항들이 예정되어 있습니다. 개발자들은 이를 위해 끊임없이 노력해 왔으며, Yuan Fu를 비롯한 많은 이들이 여러 분야에 걸쳐 tree-sitter 경험을 지속적으로 개선해 왔습니다. 더 나은 언어 지원부터 사용성 및 성능 향상에 이르기까지, Emacs의 tree-sitter는 놀라운 속도로 계속 진화하고 있습니다.
내장된 markdown-ts-mode (실험적 기능)
Emacs 31은 markdown-ts-mode를 기본적으로 포함하고 있으며, 이 모드는 제게 매우 각별합니다. 제가 시작했기 때문입니다. 이 모드는 제가 2025년 초 emacs-devel에 보냈던 제안에서 시작되었으며, 그 아이디어와 코드의 첫 번째 버전은 제 것이었습니다.
이 모드가 저 혼자만의 노력이라고 생각하게 만든다면 저는 이 모드에 결례를 범하는 것입니다. Stéphane Marks가 조금 나중에 합류하여 소매를 걷어붙였고, 이후 이 모드의 공동 저자(co-author)가 되었습니다. 그는 오늘날 이 모드를 사용하기 좋게 만드는 많은 요소의 원동력입니다. 그는 패치 한두 개를 보내고 떠난 것이 아니라, 머물면서 제가 스케치했던 것 이상으로 모드를 밀어붙였고, "작동한다"를 "즐겁다"로 바꾸는 세부 사항들에 공을 들였습니다. 제가 곧 자랑할 많은 다듬기(polish) 작업들은 그의 공로입니다. 이제 이 모드는 우리의 것이 되었으며, 덕분에 더욱 좋아졌습니다.
아이디어가 메일링 리스트(mailing-list) 메시지에서 핵심 코드(core code)로 변모하는 과정을 지켜보고, 그 과정에서 훌륭한 협력자를 만나는 것은 Emacs 커뮤니티에 머무는 가장 보람찬 일 중 하나입니다.
(use-package markdown-ts-mode
:ensure nil
:defer t)
이것은 단순한 색상 그 이상의 가치를 제공하며, 제가 자랑하고 싶은 부분들은 다음과 같습니다:
✔️ Org 사용자들은 편안함을 느낄 것입니다. 키 바인딩(keybindings)과 편집 방식이 Org와 매우 유사합니다: 헤딩(headings) 탐색, 섹션 접기(folding), 구조적 요소 간 이동 등이 그렇습니다. 만약 당신의 손가락이 Org에 익숙하다면, Markdown를 새로 배울 필요가 없을 것입니다.
✔️ Tree-sitter를 지원하지 않는 언어에서도 실시간으로 색상이 입혀진 코드 블록을 사용할 수 있습니다. 이것이 제가 가장 좋아하는 기능입니다. 구분된 코드 블록(fenced code block)은 단순한 단조로운 고정폭(monospace) 텍스트로 던져지는 것이 아니라, 해당 언어의 실제 메이저 모드(major mode)를 사용하여 폰트화(fontified)됩니다. 이는 Emacs 자체의 내부 모드에도 적용되므로,
````elisp`
블록은 진정한 Emacs Lisp 폰트 락킹(font-locking)이 적용되며, 다른 내장 모드들도 마찬가지입니다. 여러분은 ...
(eglot-documentation-renderer 'markdown-ts-view-mode) ;; EMACS-31
(eglot-code-action-indications nil) ;; EMACS-31
markdown-ts-view-mode
...
(eldoc-help-at-pt t) ;; EMACS-31
이 설정을 켜두면, 제가 별도로 호출하지 않아도 eldoc이 커서 아래에 있는 무엇이든 도움말 텍스트를 보여줍니다. 다음 설정과 결합하면 더욱 강력합니다:
...
(completion-eager-update t) ;; EMACS-31
(completion-eager-display 'auto) ;; EMACS-31
(minibuffer-visible-completions 'up-down) ;; EMACS-31
completion-eager-update
...
(when (and (>= emacs-major-version 31)
(boundp 'icomplete-vertical-in-buffer-adjust-list))
(setq icomplete-vertical-in-buffer-adjust-list t)
(setq icomplete-vertical-render-prefix-indicator t))
윈도우 레이아웃 체조 (Window layout gymnastics)
...
("C-x w t" . window-layout-transpose) ; EMACS-31
("C-x w r" . window-layout-rotate-clockwise) ; EMACS-31
("C-x w f h" . window-layout-flip-leftright) ; EMACS-31
("C-x w f v" . window-layout-flip-topdown) ; EMACS-31
Transpose는 수평 및 수직 배치를 서로 바꾸고, rotate는 전체 레이아웃을 회전시키며, flip 명령은 좌우 또는 상하로 반전시킵니다. 만약 3개의 윈도우 레이아웃을 구성한 후 에디터 창이 반대편에 있었으면 좋겠다고 생각한 적이 있다면, 이 기능들이 그 역할을 수행하며 그 과정에서 모든 버퍼(buffer)의 위치를 그대로 유지해 줍니다.
...
(speedbar-window-default-width 25) ;; EMACS-31
(speedbar-window-max-width 25) ;; EMACS-31
;; 제 설정에서는 M-I에 바인딩되어 있습니다:
(speedbar-window) ;; EMACS-31
`speedbar-window`
...
(setopt
vc-auto-revert-mode t ; EMACS-31
vc-allow-rewriting-published-history t ; EMACS-31
vc-dir-hide-up-to-date-on-revert t) ; EMACS-31
`vc-dir-hide-up-to-date-on-revert`
...
;; EMACS-31 새로운 Emacs에는 xref 버퍼 편집을 위한 'e' 기능이 포함되므로 이 부분을 제거합니다.
;; 참조: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=80616
이 이야기에 대해서는 조금 더 길게 늘어놓아 보려 합니다. 제가 그 과정의 일부였고, 기능들이 어떻게 Emacs에 도입되는지를 보여주기 때문입니다.
...
(add-to-list 'save-some-buffers-action-alist
(list "d"
(lambda (buffer)
(diff-buffer-with-file (buffer-file-name buffer)))
"show diff between the buffer and its file"))
다시 주제로 돌아가서, 최종 결과는 이렇습니다: Emacs 31은 편집 가능한 xref 버퍼를 제공하며, 제 설정에서는 직접 만든 임시 방편(workaround)을 제거하게 됩니다. 그리고 그 기능은...
...
(erc-log-insert-log-on-open 'erc-log-new-target-buffer-p) ;; EMACS-31
이 설정은 ERC가 새로 열린 대상 버퍼(target buffer)에 대해서만 이전 로그를 삽입하도록 만드는데, 이는 제가 채널을 다시 합칠 때 원하는 동작입니다. 그리고 제...
...
(delete-pair-push-mark t) ; EMACS-31: delete-pair 이후에 마크 (mark)를 푸시하여 C-x C-x가 내부 내용을 선택할 수 있게 함
(ibuffer-human-readable-size t) ; EMACS-31: 가공되지 않은 바이트 수 대신 KB/MB 단위 사용
(ielm-history-file-name ...) ; EMACS-31: IELM 입력 히스토리가 마침내 저장됨
(kill-region-dwim 'emacs-word) ; EMACS-31: 영역(region) 지정 없이 C-w를 누르면 단어를 삭제함
(native-comp-async-on-battery-power nil) ; EMACS-31: 배터리 사용 시 네이티브 컴파일 (native-comp) 작업 중단
(view-lossage-auto-refresh t) ; EMACS-31: C-h l이 실시간으로 업데이트됨, 교육/디버깅에 매우 유용함
(display-fill-column-indicator-warning nil) ; EMACS-31
(dired-hide-details-hide-absolute-location t); EMACS-31: dired-hide-details-mode에서 절대 디렉토리 경로를 숨김
(world-clock-sort-order "%FT%T") ; EMACS-31: 세계 시계 (world clock) 정렬을 합리적으로 변경
(zone-all-frames t) ; EMACS-31
(zone-all-windows-in-frame t) ; EMACS-31
(uniquify-after-kill-buffer-flag t) ; EMACS-31: -p 변형 버전에서 이름 변경
이 중 몇 가지는 설명할 가치가 있습니다:
✔️ kill-region-dwim은 수십 년 된 사소한 불편함(papercut)을 해결합니다. 이를 'emacs-word로 설정하면, 활성화된 영역(region)이 없는 상태에서 C-w를 눌렀을 때 에러를 발생시키는 대신 단어를 뒤쪽 방향으로 삭제합니다. 더 이상 "마크가 활성화되어 있지 않습니다"라는 방해를 받지 않아도 됩니다.
✔️ view-lossage-auto-refresh는 C-h l을 마지막 키 입력의 실시간 뷰로 바꿔줍니다. 제가 화면을 공유하거나 누군가를 가르칠 때, 사람들이 제가 누르는 키를 실시간으로 볼 수 있습니다.
✔️ ielm-history-file-name은 comint나 셸(shell)이 이미 그러하듯, 제 IELM 스크래치 세션이 재시작 후에도 유지되도록 해줍니다.
✔️ native-comp-async-on-battery-power nil은 노트북을 보호합니다. 기차 안에서 전원을 연결하지 않은 채 사용할 때, 백그라운드 네이티브 컴파일 (native compilation) 작업으로 인해 갑자기 팬이 돌아가는 일이 없습니다.
✔️ tty-tip-mode는 터미널에 툴팁 (tooltips) 기능을 가져다줍니다. -nw 모드로 Emacs를 실행하는 사용자들에게 아주 좋은 기능입니다.
언급할 가치가 있는 것: term이 줄을 먹어치우는 현상 중단
이 항목은 설정할 코드가 없습니다. 왜냐하면 설정할 것이 없기 때문입니다. 버그가 수정되었는데, 이는 제가 기대했던 것 이상으로 저를 기쁘게 만듭니다.
오랫동안 term (그리고 ansi-term
)은 줄을 삼켜버리는 (swallowing lines) 고약한 습관이 있었습니다. 전체 화면을 사용하거나 커서 주소를 지정하는 프로그램들은 프로그램이 화면을 다시 그릴 때 행이 먹히거나 잘못 배치되어 디스플레이를 엉망으로 만들었습니다. 이는 실제 터미널을 가장 필요로 하는 프로그램들, 즉 htop, nethack 등 curses 기반의 모든 것들을 Emacs 내부에서 거의 사용할 수 없게 만들었습니다.
Emacs 31은 이를 수정합니다. 이제 term이 올바르게 다시 그려지며, 버퍼가 종이 조각처럼 흩어지는 현상 없이 프로세스를 관찰하기 위해 htop을 실행하거나 "잠깐" 쉬기 위해 nethack을 실행할 수 있습니다. 사소해 보일 수 있지만, 이는 제가 외부 터미널 에뮬레이터를 찾아야 했던 마지막 이유 중 하나를 제거해 줍니다.


언급할 만한 가치가 있는 것 2: Modus 5 테마!
Protesilaos 덕분에 Emacs는 이제 여러 modus 테마를 포함하여 배포됩니다:
✔️ modus-operandi-deuteranopia -- 흰색 배경의 제2색맹 (Deuteranopia) 최적화 테마.
✔️ modus-operandi -- 흰색 배경의 우아하고 가독성이 높은 테마.
✔️ modus-operandi-tinted -- 연한 황토색 배경의 우아하고 가독성이 높은 테마.
✔️ modus-operandi-tritanopia -- 흰색 배경의 제3색맹 (Tritanopia) 최적화 테마.
✔️ modus-vivendi-deuteranopia -- 검은색 배경의 제2색맹 (Deuteranopia) 최적화 테마.
✔️ modus-vivendi -- 검은색 배경의 우아하고 가독성이 높은 테마.
✔️ modus-vivendi-tinted -- 밤하늘 배경의 우아하고 가독성이 높은 테마.
✔️ modus-vivendi-tritanopia -- 검은색 배경의 제3색맹 (Tritanopia) 최적화 테마.
왜 굳이 master 버전을 실행하나요?
사람들은 왜 제가 출시되지 않은 Emacs를 데일리 드라이브 (daily drive)로 사용하는지 묻습니다. 제가 패키지 없는 설정을 사용하는 것과 같은 이유입니다. 저는 상자 안에 무엇이 들어있는지 알고 싶고, 다가올 변화를 배우는 방법은 그 안에서 직접 살아보는 것이기 때문입니다. 이러한 변화의 대부분은 작지만, 매 릴리스마다 제가 작성해야 하는 접착 코드 (glue code)를 줄여주는 에디터로 쌓여갑니다. 제가 직접 구현해야 했던 기능들을 코어 (core)가 흡수함에 따라 제 설정 파일이 더 짧아지는 것을 지켜보는 것은 Emacs 사용자로서 누릴 수 있는 조용한 즐거움 중 하나입니다.
이 동전의 다른 면, 즉 이미 발견되기를 기다리고 있는 배터리들에 대해서는 Karthik의 포스트를 읽어보시기 바랍니다.
그 글은 이 글의 훌륭한 동반자가 될 것입니다. 그리고 위에 언급된 모든 코드 조각(snippet)들을 문맥과 함께 확인하려면, Emacs Solo init.el에 모두 포함되어 있으며, 각 조각은 ; EMACS-31이라는 작은 breadcrumb(경로 표시)으로 표시되어 있습니다.
31 버전이 출시되면 다시 뵙겠습니다. 그때가 되면 저는 쌓여 있는 코드 더미를 삭제하러 갈 수 있겠네요. 즐거운 해킹(Happy hacking) 되시길 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기