Emacs 31.1에 추가된 주요 기능, 변경 사항, 사용 중단 항목을 살펴봅니다.
Emacs 31.1이 마침내 출시되었습니다! 이전 Emacs 버전들과 달리, 이번 릴리스에는 하나의 거대한 핵심 기능이 없습니다. 제가 파악한 바로는 새 가비지 컬렉터를 Emacs 31.1에 포함할 계획이었던 듯하지만 Emacs 32로 연기되었습니다. 하지만 그것은 다음 글에서 더 이야기하겠습니다. 흥미로운 주제입니다.
Emacs 31.1에서 눈에 띄는 기능들 중 상당수는 작지만 삶의 질을 높이는 수정 사항이며, 한 시대의 끝을 알리는 사용 중단도 하나 있습니다.
언제나처럼 출시를 기념하여 다음 주 동안 제 책, Mastering Emacs를 31% 할인합니다.
unexec/pdumper 논쟁과 뒤이은 사용 중단
Emacs는… 평범한 애플리케이션이 아닙니다. 컴파일하고 링크하면 Emacs의 핵심이지만 함께 배포되는 대부분의 라이브러리는 없는 temacs를 얻습니다. C 코어와 인터프리터 외에는 거의 없는 최소 구성 Emacs이며, 실제로는 그다지 쓸모가 없습니다.
익숙하고 사랑하는 Emacs 바이너리를 얻으려면 temacs를 실행하고 표준 라이브러리를 메모리에 적재하라고 해야 합니다. 이는 느립니다. 많은 elisp와 정리 작업이 필요합니다. 이런 방식으로 Emacs를 시작하면 몇 분과 상당한 CPU 및 RAM이 들 수 있으므로, 감당할 수 없습니다.
이는 수십 년 동안 Emacs를 괴롭혀 온 문제입니다. 오늘날에는 큰 문제가 아니지만, 과거에는 열성적인 Emacs 사용자 여럿이 아침에 동시에 Emacs를 실행하기로 하면 가정용 컴퓨터나 공유 다중 사용자 환경을 무너뜨릴 수도 있었습니다.
해결책은 무엇일까요? 모든 것을 한 번 적재한 뒤, _Emacs 메모리의 text/data/bss/etc. 세그먼트를 문자 그대로 새 바이너리에 덤프하는 것_입니다. 그러면 Emacs Lisp 상태를 반복해서 부트스트랩할 필요가 없습니다. 거의 레슬링 기술처럼 느껴집니다. 위쪽이 무거운 Emacs를 자리에 몰아넣고 The Attitude Adjustment를 적용해 새 바이너리로 내리꽂으면, 모든 것이 준비되어 실행할 수 있게 됩니다.
아주 대담한 수법입니다.
하지만 이, 음, 레슬링 기술을 작동시키기 위해 Emacs는 glibc의 여러 특수 함수를 사용했습니다. 이런 좋지 않은 행태를 수십 년 동안 지원한 뒤 glibc 팀은 그만두기로 했고, Emacs는 다른 방법을 찾아야 했습니다.
Daniel Colascione은 훨씬 나은 해결책을 만들었습니다. 모두가 만족한 것은 아니지만, 간단히 말하면 Emacs 내부 구조의 직렬화를 내부 메모리 구조의 1:1 덤프가 아닌 형태로 표준화합니다.
포터블 덤퍼는 수년간 기본값이었습니다. 약 10년 전에 처음 도입되었고, 하위 호환성의 긴 역사를 지닌 Emacs답게 포터블 덤퍼를 우스꽝스럽거나 쓸 수 없다고 여긴 한두 명의 사용자를 위해 옛 unexec 덤퍼도 명목상 남아 있었습니다.
하지만 이제 마침내 완전히 사라졌습니다. 한 시대의 끝입니다.
사용자 Lisp 디렉터리
고전적인 문제입니다. Emacs 패키지를 어딘가에 git clone하거나 내려받았고 이제 작동하게 하고 싶습니다. 하지만 어떻게 할까요? 그렇게 간단하지는 않습니다. 경쟁하는 방법이 꽤 많습니다. 가장 단순한 방법은 사용자가 .emacs.d 디렉터리의 user-lisp/에 패키지를 넣으면 Emacs가 로딩과 autoload 설정을 처리하게 하는 것입니다. 그러면 알맞은 항목이 M-x에 나타납니다.
미니버퍼와 완성
Emacs 30.1에는 Company나 Corfu와 비슷하지만, Company와 그 친구들처럼 떠 있는 자식 프레임을 쓰는 대신 *Completions* 창을 사용하는 Emacs식 네이티브 “팝업 창” 시스템인 completion-preview-mode가 추가되었습니다.
Emacs 31.1은 네이티브 방식으로 전환하려는 사용자가 분명 사용자 지정하고 싶을 폭넓은 옵션으로 이를 확장합니다.
창 레이아웃 회전
M-x window-layout-rotate-clockwise(C-x w C-h에서 다양한 새 옵션을 확인하세요) 같은 명령은 창 레이아웃을 회전합니다. 또 하나의 훌륭한 작은 UI 개선입니다.
영역을 활성화하지 않고 포인트와 마크 교환하기
저는 (주로 제 책에서) transient-mark-mode가 kill-region(C-w) 같은 수많은 “영역 영향” 명령 위에 덮인 다소 어색한 만능 해법이라는 이야기를 했습니다.
따라서 포인트와 마크를 교환하는 C-x C-x도, 원하든 원하지 않든 영역을 활성화합니다. transient mark mode에서 마크 명령 고치기는 정확히 그것을 하는 방법을 보여 주는 제 오래된 글입니다. 하지만 이제 그렇게 하지 않게 하는 내장 옵션이 생겼습니다. 좋습니다.
Tree-sitter가 이제 문법 설치를 제안합니다
Emacs에서 tree-sitter의 폭넓은 채택을 막는 두 가지 장애물이 함께 작동합니다.
전자는 여전히 문제지만 후자는 이제 대부분 해결되었습니다. Emacs는 이제 자신이 아는 TS 모드에 맞는 언어 문법 설치를 마침내 제안할 수 있습니다.
이제 Combobulate: Structured Movement and Editing with Tree-Sitter를 시험해 보지 않을 이유가 없습니다.
그 밖에도 훨씬 더 많은 것들
수많은 작은 조정과 변경이 있습니다. 읽어 보세요.
unexec dumper removed.
The traditional unexec dumper, deprecated since Emacs 27, has been
removed.
The portable dumper now works on m68k a.out targets.
글 첫머리에서 썼듯, 이것은 정말 한 시대의 끝입니다.
Emacs's old 'ctags' program is no longer built or installed.
You are encouraged to use Universal Ctags <https://ctags.io/> instead.
For now, to get the old 'ctags' behavior you can can run 'etags --ctags'
or use a shell script named 'ctags' that runs 'etags --ctags "$@"'.
TAGS 사용자라면 where로 확인하여 더 최신 버전이 설치되어 있는지 확인해야 합니다. (TAGS를 쓰는지 모른다면, 쓰지 않는 것입니다.)
In compatible terminals, 'xterm-mouse-mode' is turned on by default.
For these terminals the mouse will work by default. A compatible
terminal is one that supports Emacs setting and getting the OS selection
data (a.k.a. the clipboard) and mouse button and motion events. With
'xterm-mouse-mode' enabled, you must use Emacs keybindings to copy to the
OS selection instead of terminal-specific keybindings.
You can keep the old behavior by customizing 'xterm-mouse-mode' to nil.
대부분의 사람은 모르지만 Emacs는 수년 전에 터미널 Emacs에 마우스 지원을 추가했지만 꺼 둔 채였습니다. 터미널 기능은 크게 다르므로 안전한 결정이었습니다. 하지만 이제는 기대하는 대로 작동합니다. 메뉴를 클릭할 수 있고 그 밖의 기능도 됩니다. 좋습니다.
New User Lisp directory feature.
If you have a subdirectory "user-lisp/" in your Emacs configuration
directory, then Lisp files in it and any subdirectories are now
recursively byte-compiled, scraped for autoload cookies and added to
'load-path'.
이 기능은 정말 유용합니다. 저는 23년 동안 제 파일이 든 디렉터리를 불러오기 위해 같은 코드 조각을 그대로 복사해 사용해 왔습니다. use-package가 도움이 되기는 하지만 여전히 수작업이 많이 듭니다. 진작 필요했습니다!
'line-spacing' now supports specifying spacing above the line.
Previously, only spacing below the line could be specified. The user
option can now be set to a cons cell to specify spacing both above and
below the line, which allows you to vertically center text.
이는 Emacs 전체에 적용되는 전역 값이며 face 설정이 아닙니다. 따라서 M-x customize-face로 변경할 수 없습니다. setopt 또는 customize UI로 설정하세요.
'prettify-symbols-mode' attempts to ignore undisplayable characters.
Previously, such characters would be rendered as, e.g., white boxes.
Support for immediate display of the "*Completions*" buffer.
Whenever a minibuffer with completion is opened, then if the completion
table sets the 'eager-display' completion property to non-nil, the
"*Completions*" buffer will now be displayed immediately.
이는 Emacs 30.1에서 Emacs의 미니버퍼 완성 시스템을 전통적인 company/corfu 스타일 완성기처럼 조금 더 동작하게 만든 변경과 잘 맞물립니다.
저는 이 새 기능들을 높게 평가하지만, 방해되지 않는 방식으로 작동하게 하려면 상당한 사용자 지정이 필요하다는 점은 경고합니다.
New mode 'mouse-shift-adjust-mode' extends selection with 'S-<mouse-1>'.
When enabled, you can use the left mouse button with the '<Shift>' modifier
to extend the boundaries of the active region by dragging the mouse pointer.
멋집니다. 저는 Emacs에서 드래그 선택을 거의 하지 않지만, 까다로운 작업을 한 번만 해야 할 때는 실제로 키보드보다 빠릅니다.
New commands to modify window layouts of frames.
'window-layout-rotate-clockwise' ('C-x w r <RIGHT>') and its counterpart
'window-layout-rotate-anticlockwise' ('C-x w r <LEFT>') rotate an entire
window layout.
'window-layout-flip-topdown' ('C-x w f <DOWN>', 'C-x w f <UP>') and
'window-layout-flip-leftright' ('C-x w f <LEFT>', 'C-x w f <RIGHT>')
flip the window layout vertically and horizontally.
'window-layout-transpose' ('C-x w t') reorganizes windows such that
every horizontal split becomes a vertical split and vice versa.
이 기능이 마음에 듭니다. 다만 저는 아마 시계 방향 같은 한 방향만 골라 접근하기 쉬운 키에 바인딩하고 몇 번 누르는 수고를 감수할 것입니다. 이런 일을 자주 하지는 않으니까요.
New user option 'mode-line-collapse-minor-modes'.
This is a new, built-in facility to hide minor mode lighters. If
non-nil, minor mode lighters on the mode line are collapsed into a
single button.
마침내 내장된 것이 기쁩니다. 이것이 use-package의 :delight / :diminish와 연동되는지는 알 수 없습니다.
New binding 'C-h u' for 'apropos-user-option'.
In 'customize-face', the "Font family" attribute now supports completion.
정말 반가운 소식입니다. 저는 .Xresources, 프레임 설정 face, 기본 글꼴을 정하는 온갖 복잡한 방법으로 씨름하는 것이 나쁜 습관이라고 오래 주장해 왔습니다. M-x customize-face RET default RET가 대안보다 가장 단순하고 효과적입니다. 이제 글꼴 이름을 추측할 필요가 없습니다. Emacs가 마침내 자동 완성을 할 수 있습니다. 훌륭한 변경입니다.
New command 'unfill-paragraph'.
This is the inverse of 'M-q' ('fill-paragraph').
아마 org mode나 무언가에는 오래전부터 코드 어딘가에 묻혀 있었을 것입니다. 그래도 좋은 기능입니다.
Project는 이미 Emacs에 포함된 긴 프로젝트 도구 계열 중 최신 프로젝트 관리 도구입니다. 좋으니 사용해 보세요.
New command 'project-save-some-buffers' bound to 'C-x p C-x s'.
This is like 'C-x s', but only for this project's buffers.
Tree-sitter는 코드, markdown 같은 구조화된 텍스트를 위한 고급 파싱 도구 모음입니다. 저는 tree-sitter와 상호작용하는 코드에 대해 엄청나게 많이 썼습니다.
How to Get Started with Tree-Sitter, Combobulate: Structured Movement and Editing with Tree-Sitter 등을 참고하세요.
New user option 'treesit-auto-install-grammar'.
It controls the automatic installation of tree-sitter grammar libraries
needed for tree-sitter-based modes, if these grammar libraries are not
available when such modes are turned on.
진작 필요했습니다. tree-sitter 라이브러리의 알맞은 마법 같은 버전에 맞춘 복잡한 git ref 수십 개를 들고 다녀야 하는 일은 모두에게 끔찍한 UX였습니다.
Emacs가 Docker 컨테이너, Kubernetes, SSH, Android debug bridge 등으로 원격 시스템과 통신하고 상호작용하는 방식입니다. 진정 Emacs의 가장 위대한 기능 중 하나입니다.
New command 'tramp-dired-find-file-with-sudo'.
This command, bound to '@' in Dired, visits the file or directory on the
recent Dired line with superuser, or root, permissions.
저는 이미 파일과 dired 버퍼에서 정확히 이를 하는 sudo라는 작은 보조 명령을 가지고 있습니다. 그래도 매우 반가운 추가입니다. 멀티홉에서도 작동해야 한다는 점을 기억하세요.
Dired는 Emacs의 뛰어난 디렉터리 편집기이자 파일 브라우저입니다. 폭넓은 고급 기능을 갖추고 있습니다. Dired Shell Commands: The find & xargs replacement, WDired: Editable Dired Buffers, Working with multiple files in dired를 참고하세요.
'dired-copy-filename-as-kill' supports project-relative names.
With a prefix argument value of 1, this command now copies file names
relative to the root directory of the current project.
훌륭하지만 접두 인수 값 1 뒤에 숨겨져 있어 문서 문자열을 읽지 않으면 찾기 어렵습니다.
Emacs의 패키지 관리자입니다.
'package-refresh-contents' runs asynchronously.
Refreshing the package index will no longer block when invoked
interactively.
New command 'package-autosuggest'.
Using a built-in database of ELPA package suggestions, this command will
install viable packages if no specific major mode is available for the
contents of the current buffer.
사람들에게 유용할 기능처럼 보입니다. 다른 유용한 패키지를 알려 줄 수 있으니까요.
New major mode 'icalendar-mode'.
A major mode for displaying and editing iCalendar (RFC 5545) data. This
mode handles line unfolding and fontification, including highlighting
syntax errors in invalid data.
New minor mode 'delete-trailing-whitespace-mode'.
A simple buffer-local mode that runs 'delete-trailing-whitespace'
before saving the buffer.
많은 사람이 결국 직접 만들어 쓰는 기능을 하는 마이너 모드입니다.
New library 'timeout'.
This library provides functions to throttle or debounce Emacs Lisp
functions. This is useful for corralling overeager code that is slow
and blocks Emacs, or does not provide ways to limit how often it runs.
New mode 'system-taskbar-mode'.
This is a global minor mode and companion functions that integrate Emacs
with system GUI taskbars (also called docks or launchers or something
similar) to display a taskbar icon badge overlay, a progress bar report
overlay, and alerts that an Emacs session needs attention.
꽤 멋집니다. 저는 Hyprland를 사용하므로 제게 차이가 있을지는 모르겠지만, 이를 사용하는 사람들의 경험과 도움이 되는지 듣고 싶습니다.
Emacs 31.1은 단일한 대형 기능보다 수많은 실용적인 개선을 담은 릴리스입니다. 사용자 Lisp 디렉터리, tree-sitter 문법 자동 설치 지원, 완성 인터페이스 개선, 창 레이아웃 명령, Dired·VC·Tramp의 강화, 그리고 다양한 새 옵션과 모드는 일상적인 Emacs 사용을 조금씩 더 편하게 만듭니다.
특히 tree-sitter, 프로젝트, 원격 작업, 버전 관리 워크플로를 적극적으로 쓰는 사용자라면 이번 릴리스에서 살펴볼 내용이 많습니다.