Những thay đổi tôi đã dùng hằng ngày trong Emacs 31
(rahuljuliato.com)- Emacs 31 vẫn chưa phát hành chính thức, nhưng trên nhánh
emacs-31vàmasterđã tích lũy đủ nhiều thay đổi có thể cảm nhận rõ trong thực tế, và nhiều thiết lập đang chuyển theo hướng được giải quyết chỉ bằng lõi Emacs, không cần gói ngoài - Việc bổ sung chuyển đổi Tree-sitter tự động và cài đặt ngữ pháp giúp giảm gánh nặng tự quản lý major mode và nguồn ngữ pháp
markdown-ts-mode, cơ chế render tài liệu của Eglot,eldoc-help-at-pt, eager completion,xref-edit-modecủng cố luồng chỉnh sửa, điều hướng và tra cứu tài liệu dựa chủ yếu vào tính năng tích hợp sẵn- Những tùy chọn nhỏ như cửa sổ bên của Speedbar, tự động ẩn VC, điều kiện log của ERC,
kill-region-dwim,ielm-history-file-name,native-comp-async-on-battery-powergiúp giảm bớt những va chạm lặp đi lặp lại - Tên tính năng và giá trị mặc định trong Emacs 31 vẫn có thể thay đổi, và
markdown-ts-modecùng cơ chế render tài liệu của Eglot dùng nó đều được ghi rõ là tính năng thử nghiệm, cần bật thủ công
Tiền đề của bản xem trước Emacs 31
- Emacs 31 vẫn chưa phát hành; môi trường tham chiếu là cấu hình build từ nhánh
emacs-31vàmastervào giữa năm 2026 để sử dụng - Các mục được giới thiệu là những thay đổi đã thực sự đi vào cấu hình hằng ngày, và phần lớn đã vào lõi Emacs hoặc ở rất gần mức đó
- Tên tính năng và giá trị mặc định có thể thay đổi cho tới trước bản phát hành cuối cùng
- Có thể xem ví dụ cấu hình trong
init.elcủa Emacs Solo với chú thích; EMACS-31
Giảm cấu hình Tree-sitter
- Trong Emacs 31, hai tùy chọn giúp đơn giản hóa luồng chuyển mode dựa trên Tree-sitter và cài đặt ngữ pháp
treesit-enabled-modes ttreesit-auto-install-grammar t
- Khi đặt
treesit-enabled-modesthànht, các major mode có biến thể Tree-sitter sẽ được chuyển sang mode đó treesit-auto-install-grammarkhông chỉ báo lỗi khi thiếu ngữ pháp mà sẽ đề xuất để Emacs tải về và build ngữ pháp- Khi nguồn ngữ pháp cho các ngôn ngữ như TypeScript, TSX, Rust, TOML, YAML, Dockerfile được đưa vào trong mode, có thể giảm bớt cấu hình phải tự điền URL và đường dẫn vào
treesit-language-source-alist - Cần lưu ý nếu dùng thư mục Emacs dùng chung giữa nhiều kiến trúc
- Ngữ pháp được cài tự động không được tách theo từng kiến trúc
.sochox86_64và.sochoarm64nằm dưới cùng một tên, nên binary build trên máy này có thể không được máy khác nạp thành công
markdown-ts-mode tích hợp sẵn
- Emacs 31 bao gồm
markdown-ts-modeở trạng thái thử nghiệm - Mode này bắt đầu từ một đề xuất gửi lên emacs-devel vào đầu năm 2025, sau đó Stéphane Marks tham gia đồng tác giả và tiếp tục cải tiến
- Nó không xem Markdown chỉ là đối tượng tô sáng cú pháp đơn thuần mà gần hơn với một môi trường biên tập dễ viết, dễ đọc
- Cung cấp cách di chuyển tiêu đề, thu gọn và di chuyển phần tử cấu trúc quen thuộc với người dùng Org
- Fenced code block không còn là văn bản chữ rộng cố định phẳng, mà được font-lock bằng major mode thật của ngôn ngữ đó
- Các block Emacs Lisp và những mode tích hợp khác cũng nhận được tô sáng cú pháp thực sự
- Lệnh chỉnh sửa code block phần lớn đã hoạt động, nhưng tính năng hoàn thành trong block vẫn còn hơi thô
- Liên kết ảnh được render inline ngay trong buffer
- Hiện nó vẫn chưa được nối vào
auto-mode-alist, nên chưa tự động nhận file.md- Có thể nạp thư viện bằng
M-x load-library RET markdown-ts-moderồi bật trong buffer - Hoặc tự thêm vào
auto-mode-alist
- Có thể nạp thư viện bằng
- Có thể gửi phản hồi bằng
M-x report-emacs-bugtới bug list - Có thêm ảnh chụp màn hình tại markdown-ts-mode-lab demo
Cải thiện Eglot, Eldoc, completion
- Trong Emacs 31, Eglot có thể render tài liệu LSP bằng
markdown-ts-view-modeeglot-documentation-renderer 'markdown-ts-view-mode- Có thể xem hover docs đã được định dạng mà không cần gói ngoài
- Tính năng này phụ thuộc vào
markdown-ts-mode, nên tương tự cũng là thử nghiệm
- Có thể tắt gợi ý code action inline mới bằng
eglot-code-action-indications- Trên một số language server, các gợi ý này có thể gây ồn
eglot-events-buffer-sizeđang được thay bằngeglot-events-buffer-configeldoc-help-at-pt thiển thị trợ giúp cho mục nằm dưới con trỏ mà không cần gọi riêng- Dùng cùng
eldoc-echo-area-prefer-doc-buffersẽ tăng mức độ hướng dẫn khi khám phá code lạ
- Dùng cùng
- Các thiết lập completion mới cập nhật UI tích cực hơn trong lúc nhập
completion-eager-update tcompletion-eager-display 'autominibuffer-visible-completions 'up-down
completion-eager-updatevàcompletion-eager-displaycập nhật UI completion theo đầu vào ngay cả trước khi người dùng yêu cầu- Khi đặt
minibuffer-visible-completionsthành'up-down, có thể di chuyển giữa các ứng viên đang hiện bằng phím mũi tên - icomplete đã bao gồm bản vá bug#75784 để có hành vi dọc trong buffer và prefix indicator
icomplete-vertical-in-buffer-adjust-listicomplete-vertical-render-prefix-indicator
Bố trí cửa sổ và Speedbar
- Emacs 31 bổ sung các lệnh đổi bố cục mà không cần tự chia lại hay đóng cửa sổ
window-layout-transposewindow-layout-rotate-clockwisewindow-layout-flip-leftrightwindow-layout-flip-topdown
- Transpose đổi giữa bố trí ngang và dọc, rotate xoay toàn bộ layout, còn các lệnh flip sẽ lật gương trái-phải hoặc trên-dưới
- Hữu ích khi muốn đổi vị trí cửa sổ trình soạn thảo trong cấu hình 3 cửa sổ mà vẫn giữ nguyên các buffer
- Trong Emacs 31, Speedbar có thể được đặt trong side window thay vì frame riêng
speedbar-window-default-widthspeedbar-window-max-widthspeedbar-window
speedbar-windowdock Speedbar sang bên cạnh như một cây file hiện đại- Trong môi trường tiling hoặc laptop một màn hình, cách side window hợp hơn frame nổi kiểu cũ
VC và xref có thể chỉnh sửa
- VC có các thiết lập giúp giảm bớt thao tác trong luồng quản lý phiên bản hằng ngày
vc-auto-revert-mode tvc-allow-rewriting-published-history tvc-dir-auto-hide-up-to-date 'revert
vc-dir-auto-hide-up-to-datetự động ẩn các file đã ở trạng thái mới nhất khi làm mới buffervc-dir- Có thể xóa các hack gán phím trước đây vốn gọi
vc-dir-hide-up-to-datesauvc-dir-refresh
- Có thể xóa các hack gán phím trước đây vốn gọi
vc-allow-rewriting-published-historyphù hợp với các luồng cố ý viết lại lịch sử đã push như Jujutsu hoặc force-push trên feature branch- Emacs 31 có buffer xref có thể chỉnh sửa
- Trước đây buffer xref chỉ có
xref-query-replace-in-resultstrên phímr, và bị giới hạn ở thay thế dựa trên regex - Không có luồng chỉnh sửa trực tiếp trong buffer kết quả như
wdired-modecủa Dired haygrep-edit-modecủa buffer grep
- Trước đây buffer xref chỉ có
- Đề xuất ban đầu là dùng
xref-export-to-grepđể xuất kết quả xref sang một buffergrep-modedạngfile:line:contentrồi chỉnh sửa ở đó - Dmitry Gutov, người bảo trì xref, đã đề xuất chỉnh sửa inline ngay trong buffer xref thay vì vòng qua buffer grep, và sau đó
xref-edit-modeđược viết và đưa vào xref-edit-modeloại bỏ việc chuyển qua buffer phụ và chạy nhanh hơn cả với buffer xref lớn- Cách dùng là tìm bằng
C-x p g, rồi trong buffer*xref*nhấneđể vào chế độ chỉnh sửa, sau khi sửa thì nhấnC-c C-cđể xác nhận - Thảo luận liên quan được công khai tại bug#80616
ERC và các cải thiện chất lượng nhỏ
- ERC có thể chỉ chèn log cũ khi mở target buffer mới bằng
erc-log-insert-log-on-open 'erc-log-new-target-buffer-p - Trong Emacs 31, module
scrolltobottomcủa ERC không còn phụ thuộc vàoerc-fill-wrap, nên có thể bỏ cấu hình điều kiện cho các phiên bản trước - Các giá trị cấu hình nhỏ cũng góp phần cải thiện khả năng sử dụng
delete-pair-push-mark t: push mark saudelete-pair, để có thể chọn phần bên trong bằngC-x C-xibuffer-human-readable-size t: hiển thị KB/MB thay vì byte thôielm-history-file-name: giữ lịch sử nhập của IELM sau khi khởi động lạikill-region-dwim 'emacs-word: khi không có region đang hoạt động,C-wsẽ kill từ phía sau thay vì báo lỗinative-comp-async-on-battery-power nil: dừng native compilation nền khi đang dùng pinview-lossage-auto-refresh t:C-h lcập nhật các phím vừa bấm theo thời gian thựcdisplay-fill-column-indicator-warning nildired-hide-details-hide-absolute-location t: ẩn đường dẫn thư mục tuyệt đối trongdired-hide-details-modeworld-clock-sort-order "%FT%T": điều chỉnh cách sắp xếp world clockzone-all-frames tzone-all-windows-in-frame tuniquify-after-kill-buffer-flag t: đổi tên từ biến thể-pcũ
kill-region-dwimgiúp tránh lỗi “the mark is not active” khi dùngC-wview-lossage-auto-refreshhữu ích để hiển thị phím bấm theo thời gian thực khi chia sẻ màn hình hoặc giảng dạynative-comp-async-on-battery-power nilgiúp giảm tình trạng quạt quay do biên dịch nền khi đang di chuyển mà không cắm điệntty-tip-modecung cấp tooltip ngay cả trong Emacs chạy với-nw
term, giao diện Modus và lý do dùng master
- Emacs 31 sửa các lỗi trong
termvàansi-termkhiến dòng bị nuốt hoặc màn hình bị vỡ- Các chương trình dùng định vị con trỏ và redraw toàn màn hình như
htop,nethack, hay chương trình dựa trên curses giờ redraw đúng bên trong terminal của Emacs - Giảm bớt một lý do phải mở terminal emulator ngoài
- Các chương trình dùng định vị con trỏ và redraw toàn màn hình như
- Emacs đi kèm các theme Modus 5 của Protesilaos
modus-operandi-deuteranopia: theme nền trắng tối ưu cho deuteranopiamodus-operandi: theme nền trắng có độ dễ đọc caomodus-operandi-tinted: theme dễ đọc với nền vàng đất sángmodus-operandi-tritanopia: theme nền trắng tối ưu cho tritanopiamodus-vivendi-deuteranopia: theme nền đen tối ưu cho deuteranopiamodus-vivendi: theme nền đen có độ dễ đọc caomodus-vivendi-tinted: theme dễ đọc với nền bầu trời đêmmodus-vivendi-tritanopia: theme nền đen tối ưu cho tritanopia
- Lý do dùng Emacs chưa phát hành mỗi ngày là để trực tiếp kiểm chứng những gì đang vào lõi và nhìn thấy lượng glue code tự viết giảm dần qua từng bản phát hành
- Có thể đọc thêm bài đi kèm về các tính năng đã được tích hợp sẵn: Even More Batteries Included with Emacs
1 bình luận
Ý kiến trên Lobste.rs
Thay đổi về tree-sitter thật sự rất đáng mong đợi. Tôi luôn thấy quá trình cấu hình của nó khá awkward
Cũng tò mò về eager complete.
icompletevàfido-modekhá gần với thứ tôi muốn, nhưng vẫn chưa tiện dùng bằng các gói bên thứ ba nhưcorfuverticov.v. chỉ bằng tính năng tích hợp sẵn, lại còn được bật mặc địnhChỉ cần tinh chỉnh vài thứ và bật các tính năng tích hợp là độ tiện dụng đã khác hẳn,
bedrockvàemacs-solođược cấu hình theo kiểu đóMỗi lần khởi động Emacs lại hiện ra một thông báo lớn về
dylibbị thiếuCú pháp
(treesit-auto-install-grammar t)và(treesit-enabled-modes t)trong ví dụ trông như gọi hàm, nhưng thực ra là các tùy chọn cần cấu hìnhTrong bản phát hành tới cũng có vài thay đổi nhỏ tôi thích:
minibuffer-nonselected-modeđược bật mặc định nên dễ thấy hơn khi còn công việc dang dở trong minibuffer, vàdiff-modevớidiff-delete-other-hunksrất hữu ích khi dùng cùng hành vi VC của buffer diff được giới thiệu từ Emacs 29with-work-buffergiốngwith-temp-buffer, nhưng tái sử dụng một pool buffer. Tôi biết đến nó khi tình cờ dùng cùng quy ước tên buffer*work*trong cấu hình cá nhânEmacs 31 đã bao gồm
lua-modenên không cần cài riêng nữaTôi cũng phải tinh chỉnh vài thứ để nó lại hoạt động đúng như ý:
xterm-mouse-modeđược bật mặc định nên tôi tắt đi một cách tường minh, còn facemode-linethì thay đổi để hợp với theme tối nhưng tôi đã đổi lại vì quen màu mặc định cũEmacs 31 sẽ cảnh báo nếu file nguồn không có cookie
lexical-binding. Nếu thấy phiền thì có thể tắt nó đi, có thể sửa dễ dàng bằng lệnhelisp-enable-lexical-binding, và cũng có thể đặtlexical-bindinglàm mặc định toàn cụcNếu không có bug mới nào thì có vẻ đây sẽ là một bản phát hành rất vững chắc như thường lệ
:customcủause-packageVì thế tôi thấy hơi lấn cấn với
:custom. Khi muốn thử nghiệm hoặc chia sẻ giá trị thì bất tiện hơnwith-work-bufferlà vì mục đích hiệu năng à? Tài liệu không nói vì sao nên dùng nó thay chowith-temp-buffer, mà chỉ nói rằng cần cẩn thận hơnelpathì không cảnh báo, chỉ cảnh báo file của tôi thôiNgoài ra, 64 trong số 68 cảnh báo trong Emacs của tôi đến từ các file được tạo ra là
-autoloads.el. Có lẽ chuyện này nên được sửa ở công cụ sinh file phíaelpa/melpaCuối cùng cũng có xref có thể chỉnh sửa được như tôi vẫn mong, và có vẻ nó sẽ giúp cuộc sống của tôi dễ chịu hơn nhiều
Có rất nhiều thay đổi tuyệt vời chạm đến những thứ tôi dùng hằng ngày nhiều hơn mức đáng ngạc nhiên
Nvim đã đổi mặc định từ regex kiểu vim sang treesitter, và nó làm hỏng môi trường viết lách của tôi
treesitter cần cấu hình thêm để parse comment HTML bên trong Markdown, và kể cả sau khi ghép đủ các mảnh lại thì nó vẫn không chạy
Cuối cùng tôi giải quyết bằng cách tắt treesitter đi
Với hạ tầng nền tảng như editor, tôi rất bảo thủ. Thay đổi editor hầu như lúc nào cũng làm hỏng thứ gì đó vốn đã hoạt động ổn suốt nhiều năm