ความเปลี่ยนแปลงใน Emacs 31 ที่ใช้อยู่ทุกวันแล้ว
(rahuljuliato.com)- แม้ Emacs 31 จะยังไม่เปิดตัวอย่างเป็นทางการ แต่ใน branch
emacs-31และmasterก็มีความเปลี่ยนแปลงที่สัมผัสได้จริงสะสมเข้ามาแล้ว และการตั้งค่าหลายอย่างกำลังขยับไปในทิศทางที่แก้ได้ด้วย Emacs core เพียงอย่างเดียว โดยไม่ต้องใช้แพ็กเกจภายนอก - เมื่อมี การสลับ Tree-sitter อัตโนมัติและการติดตั้ง grammar เข้ามา ภาระในการดูแล major mode และการตั้งค่าแหล่ง grammar ด้วยตัวเองก็ลดลง
markdown-ts-mode, การเรนเดอร์เอกสารของ Eglot,eldoc-help-at-pt, eager completion และxref-edit-modeช่วยเสริมเวิร์กโฟลว์ด้านการแก้ไข การนำทาง และการดูเอกสาร โดยเน้น ความสามารถที่มีมาในตัว- ตัวเลือกเล็ก ๆ อย่าง Speedbar แบบ side window, การซ่อน VC อัตโนมัติ, เงื่อนไข log ของ ERC,
kill-region-dwim,ielm-history-file-name,native-comp-async-on-battery-powerช่วยลดความติดขัดที่เกิดซ้ำ ๆ - ชื่อฟีเจอร์และค่าเริ่มต้นใน Emacs 31 ยังอาจเปลี่ยนได้ และ
markdown-ts-modeรวมถึงการเรนเดอร์เอกสารของ Eglot ที่ใช้มันยังถูกระบุว่าเป็น ฟีเจอร์ทดลอง จึงต้องเปิดใช้อย่างชัดเจน
ข้อสมมติของพรีวิว Emacs 31
- Emacs 31 ยังไม่ออก และสภาพแวดล้อมอ้างอิงคือการ build
emacs-31branch และmasterมาใช้งานเองในช่วง กลางปี 2026 - รายการที่แนะนำเหล่านี้คือความเปลี่ยนแปลงที่ถูกนำมาใช้จริงในค่าตั้งประจำวัน และส่วนใหญ่ได้เข้าไปอยู่ใน Emacs core แล้วหรืออยู่ในสถานะใกล้เคียงมาก
- ชื่อฟีเจอร์และค่าเริ่มต้นอาจเปลี่ยนได้จนกว่าจะถึง release สุดท้าย
- ตัวอย่างการตั้งค่าดูได้จาก
init.elของ Emacs Solo ที่มีคอมเมนต์; EMACS-31
การลดภาระการตั้งค่า Tree-sitter
- ใน Emacs 31 มีสองตัวเลือกที่ทำให้การสลับไปใช้โหมดที่อิง Tree-sitter และขั้นตอนติดตั้ง grammar เรียบง่ายขึ้น
treesit-enabled-modes ttreesit-auto-install-grammar t
- หากตั้ง
treesit-enabled-modesเป็นtmajor mode ที่มีเวอร์ชัน Tree-sitter จะถูกสลับไปใช้โหมดนั้น treesit-auto-install-grammarไม่ได้แค่แจ้ง error เมื่อไม่มี grammar แต่ Emacs จะเสนอให้ดึง grammar มาและ build ให้ด้วย- เมื่อ source ของ grammar สำหรับภาษาอย่าง TypeScript, TSX, Rust, TOML, YAML, Dockerfile ถูกใส่เข้ามาในตัวโหมดแล้ว ก็ลดความจำเป็นในการกำหนด URL และ path เองใน
treesit-language-source-alist - หากใช้ไดเรกทอรี Emacs ร่วมกันข้ามหลายสถาปัตยกรรม ต้องระวัง
- grammar ที่ติดตั้งอัตโนมัติจะ ไม่ถูกแยกตามสถาปัตยกรรม
- ไฟล์
.soสำหรับx86_64และarm64อาจถูกวางไว้ภายใต้ชื่อเดียวกัน ทำให้ไบนารีที่ build บนเครื่องหนึ่งอาจโหลดไม่ได้บนอีกเครื่อง
markdown-ts-mode ที่มีมาในตัว
- Emacs 31 มี
markdown-ts-modeแบบ ทดลอง รวมมาให้ - โหมดนี้เริ่มจากข้อเสนอที่ส่งเข้า emacs-devel เมื่อต้นปี 2025 และหลังจากนั้น Stéphane Marks ก็เข้ามาร่วมเขียนและพัฒนาต่อ
- มันปฏิบัติต่อ Markdown ไม่ใช่แค่เป้าหมายของ syntax highlighting แบบเรียบ ๆ แต่ใกล้เคียงกับสภาพแวดล้อมการแก้ไขที่เขียนและอ่านได้สะดวก
- มีการย้ายหัวข้อ การพับ และการย้ายองค์ประกอบเชิงโครงสร้างแบบที่ผู้ใช้ Org คุ้นเคย
- fenced code block ไม่ได้เป็นแค่ข้อความ fixed-width แบบแบน ๆ แต่ทำ font-locking ตาม major mode จริงของภาษานั้น
- บล็อก Emacs Lisp และโหมดที่มีมาในตัวอื่น ๆ ก็ได้รับ syntax highlighting จริงเช่นกัน
- คำสั่งแก้ไข code block หลายอย่างใช้งานได้แล้ว แต่ความสามารถด้าน completion ภายในบล็อกยังมีส่วนที่หยาบอยู่
- ลิงก์รูปภาพจะถูกเรนเดอร์แบบ inline ภายใน buffer
- ตอนนี้ยังไม่ถูกผูกเข้ากับ
auto-mode-alistจึงยังไม่รับไฟล์.mdโดยอัตโนมัติ- สามารถโหลดไลบรารีด้วย
M-x load-library RET markdown-ts-modeแล้วเปิดใช้ใน buffer ได้ - หรือจะเพิ่มเข้า
auto-mode-alistเองก็ได้
- สามารถโหลดไลบรารีด้วย
- สามารถส่ง feedback ไปยัง bug list ด้วย
M-x report-emacs-bug - มีภาพหน้าจอเพิ่มเติมที่ markdown-ts-mode-lab demo
การปรับปรุง Eglot, Eldoc และ completion
- ใน Emacs 31, Eglot สามารถเรนเดอร์เอกสาร LSP ด้วย
markdown-ts-view-modeได้eglot-documentation-renderer 'markdown-ts-view-mode- ทำให้ดู hover docs แบบจัดรูปแบบได้โดยไม่ต้องใช้แพ็กเกจภายนอก
- ฟีเจอร์นี้พึ่งพา
markdown-ts-modeจึงยังเป็น ฟีเจอร์ทดลอง เช่นกัน
- สามารถปิด hint ของ inline code action แบบใหม่ได้ด้วย
eglot-code-action-indications- สำหรับบาง language server hint นี้อาจรู้สึกว่ารบกวนสายตา
eglot-events-buffer-sizeกำลังถูกแทนที่ด้วยeglot-events-buffer-configeldoc-help-at-pt tจะแสดงข้อมูลช่วยเหลือของรายการใต้เคอร์เซอร์โดยไม่ต้องเรียกแยกต่างหาก- หากใช้ร่วมกับ
eldoc-echo-area-prefer-doc-bufferก็จะมีคำแนะนำเพิ่มขึ้นเวลาไล่อ่านโค้ดที่ไม่คุ้นเคย
- หากใช้ร่วมกับ
- การตั้งค่าใหม่ที่เกี่ยวกับ completion ทำให้ UI อัปเดตเชิงรุกมากขึ้นระหว่างพิมพ์
completion-eager-update tcompletion-eager-display 'autominibuffer-visible-completions 'up-down
completion-eager-updateและcompletion-eager-displayจะอัปเดต UI ของ completion ให้ตรงกับอินพุตแม้ผู้ใช้ยังไม่ได้ร้องขอ- หากตั้ง
minibuffer-visible-completionsเป็น'up-downจะย้ายไปมาระหว่าง候補ที่มองเห็นได้ด้วยปุ่มลูกศร - ใน icomplete มีแพตช์ bug#75784 รวมเข้ามา ทำให้ได้ พฤติกรรมแนวตั้งใน buffer และ prefix indicator
icomplete-vertical-in-buffer-adjust-listicomplete-vertical-render-prefix-indicator
การจัดวางหน้าต่างและ Speedbar
- Emacs 31 เพิ่มคำสั่งสำหรับเปลี่ยน layout โดยไม่ต้องแบ่งและปิดหน้าต่างใหม่เอง
window-layout-transposewindow-layout-rotate-clockwisewindow-layout-flip-leftrightwindow-layout-flip-topdown
- transpose จะสลับการจัดวางแนวนอน/แนวตั้ง, rotate จะหมุน layout ทั้งหมด, ส่วนคำสั่ง flip จะสะท้อนซ้ายขวาหรือบนล่าง
- มีประโยชน์เมื่ออยากเปลี่ยนแค่ตำแหน่งหน้าต่างแก้ไขในชุดหน้าต่าง 3 บาน โดยยังคง buffer เดิมไว้
- ใน Emacs 31, Speedbar สามารถอยู่ใน side window แทน frame แยกได้
speedbar-window-default-widthspeedbar-window-max-widthspeedbar-window
speedbar-windowจะ dock Speedbar ไว้ด้านข้างเหมือนไฟล์ทรีสมัยใหม่- ในสภาพแวดล้อมแบบ tiling หรือโน้ตบุ๊กจอเดียว วิธี side window จะเหมาะกว่าฟลอตติ้งเฟรมแบบเดิม
VC และ xref ที่แก้ไขได้
- VC มีการตั้งค่าที่ช่วยลดขั้นตอนในเวิร์กโฟลว์ version control ประจำวัน
vc-auto-revert-mode tvc-allow-rewriting-published-history tvc-dir-auto-hide-up-to-date 'revert
vc-dir-auto-hide-up-to-dateจะซ่อนไฟล์ที่เป็นสถานะล่าสุดโดยอัตโนมัติเมื่อรีเฟรช buffervc-dir- ทำให้ลบ key hack ที่เคยเรียก
vc-dir-hide-up-to-dateหลังvc-dir-refreshได้
- ทำให้ลบ key hack ที่เคยเรียก
vc-allow-rewriting-published-historyเหมาะกับเวิร์กโฟลว์ที่ตั้งใจเขียนทับ history ที่ push ไปแล้ว เช่น Jujutsu หรือการ force-push feature branch- Emacs 31 มี editable xref buffer เข้ามาแล้ว
- ก่อนหน้านี้ buffer xref มีแค่
rของxref-query-replace-in-resultsและจำกัดอยู่กับการแทนที่แบบ regex - xref ไม่เคยมีเวิร์กโฟลว์แบบแก้ไขผลลัพธ์ใน buffer โดยตรงเหมือน
wdired-modeของ Dired หรือgrep-edit-modeของ grep buffer
- ก่อนหน้านี้ buffer xref มีแค่
- ข้อเสนอแรกคือใช้
xref-export-to-grepเพื่อส่งออกผลลัพธ์ xref ไปเป็น grep-mode buffer รูปแบบfile:line:contentแล้วค่อยแก้ไข - แต่ Dmitry Gutov ผู้ดูแล xref เสนอให้ใช้ การแก้ไข inline ใน xref buffer แทน UI ที่อ้อมผ่าน grep buffer และต่อมาก็มีการเขียน
xref-edit-modeขึ้นมาแล้วรวมเข้าไป xref-edit-modeตัดความจำเป็นในการย้ายไปยัง buffer เพิ่ม และทำงานได้เร็วขึ้นแม้กับ xref buffer ขนาดใหญ่- เวิร์กโฟลว์คือค้นหาด้วย
C-x p gแล้วไปที่ buffer*xref*กดeเพื่อเข้าโหมดแก้ไข จากนั้นแก้เสร็จแล้วกดC-c C-cเพื่อยืนยัน - การพูดคุยที่เกี่ยวข้องเปิดเผยไว้ที่ bug#80616
ERC และการปรับปรุงคุณภาพเล็ก ๆ
- ERC สามารถแทรก log ก่อนหน้าได้เฉพาะตอนเปิด target buffer ใหม่ด้วย
erc-log-insert-log-on-open 'erc-log-new-target-buffer-p - ใน Emacs 31, โมดูล
scrolltobottomของ ERC ไม่ต้องพึ่งerc-fill-wrapอีกต่อไป ทำให้ลบการตั้งค่าแบบมีเงื่อนไขสำหรับเวอร์ชันเก่าออกได้ - ค่าตั้งเล็ก ๆ หลายอย่างก็ช่วยเพิ่มการใช้งานได้จริง
delete-pair-push-mark t: หลังdelete-pairจะ push mark ทำให้เลือกด้านในได้ด้วยC-x C-xibuffer-human-readable-size t: แสดง KB/MB แทน raw byteielm-history-file-name: เก็บประวัติอินพุตของ IELM ข้ามการรีสตาร์ตkill-region-dwim 'emacs-word: เมื่อไม่มี active region,C-wจะ kill คำถัดไปแทนการขึ้น errornative-comp-async-on-battery-power nil: หยุด background native compilation ระหว่างใช้แบตเตอรี่view-lossage-auto-refresh t:C-h lอัปเดตรายการคีย์ล่าสุดแบบเรียลไทม์display-fill-column-indicator-warning nildired-hide-details-hide-absolute-location t: ซ่อนพาธไดเรกทอรีแบบ absolute ในdired-hide-details-modeworld-clock-sort-order "%FT%T": ปรับลำดับการเรียงของ world clockzone-all-frames tzone-all-windows-in-frame tuniquify-after-kill-buffer-flag t: เปลี่ยนชื่อมาจากตัวแปรแบบ-pเดิม
kill-region-dwimช่วยหลีกเลี่ยง error “the mark is not active” จากC-wview-lossage-auto-refreshมีประโยชน์เมื่อแชร์หน้าจอหรือสอน เพราะแสดงคีย์ที่กดล่าสุดแบบเรียลไทม์native-comp-async-on-battery-power nilช่วยลดสถานการณ์ที่พัดลมทำงานเพราะ background compilation ระหว่างพกพาโดยไม่ได้เสียบไฟtty-tip-modeเพิ่ม tooltips ให้ Emacs ที่รันแบบ-nwได้ด้วย
term, ธีม Modus และเหตุผลที่ใช้ master
- Emacs 31 แก้ปัญหาใน
termและansi-termที่เคยมีอาการกลืนบรรทัดหรือทำให้หน้าจอเพี้ยน- โปรแกรมอย่าง
htop,nethack, และโปรแกรมที่ใช้ curses ซึ่งมีการระบุตำแหน่งเคอร์เซอร์และ redraw เต็มหน้าจอ สามารถ redraw ภายในเทอร์มินัลของ Emacs ได้ถูกต้อง - จึงมีเหตุผลหนึ่งน้อยลงที่จะต้องเปิด terminal emulator ภายนอก
- โปรแกรมอย่าง
- Emacs รวม Modus 5 themes ของ Protesilaos มาให้
modus-operandi-deuteranopia: ธีมพื้นขาวที่ปรับให้เหมาะกับ deuteranopiamodus-operandi: ธีมพื้นขาวที่อ่านง่ายสูงmodus-operandi-tinted: ธีมพื้นสีเหลืองดินอ่อนที่อ่านง่ายสูงmodus-operandi-tritanopia: ธีมพื้นขาวที่ปรับให้เหมาะกับ tritanopiamodus-vivendi-deuteranopia: ธีมพื้นดำที่ปรับให้เหมาะกับ deuteranopiamodus-vivendi: ธีมพื้นดำที่อ่านง่ายสูงmodus-vivendi-tinted: ธีมพื้นท้องฟ้ายามค่ำคืนที่อ่านง่ายสูงmodus-vivendi-tritanopia: ธีมพื้นดำที่ปรับให้เหมาะกับ tritanopia
- เหตุผลที่ใช้งาน Emacs เวอร์ชันที่ยังไม่ออกทุกวัน คือเพื่อดูด้วยตัวเองว่ามีอะไรเข้ามาใน core บ้าง และเพื่อเห็นว่าทุก release ช่วยลด glue code ที่ต้องเขียนเองลงอย่างไร
- อีกบทความที่เป็นคู่กันและพูดถึงฟีเจอร์ที่มีมาแล้วในตัวคือ Even More Batteries Included with Emacs
1 ความคิดเห็น
ความคิดเห็นจาก Lobste.rs
การเปลี่ยนแปลงของ tree-sitter น่าตื่นเต้นมาก รู้สึกมาตลอดว่าขั้นตอนการตั้งค่ามันค่อนข้างขัด ๆ
แล้วก็สนใจ eager complete ด้วย
icompleteกับfido-modeก็ใกล้เคียงกับสิ่งที่ต้องการพอสมควร แต่ยังใช้งานไม่สะดวกเท่าแพ็กเกจภายนอกอย่างcorfuverticoและพวกนั้น ด้วยฟีเจอร์ที่มีมาในตัวเท่านั้น แถมเปิดใช้เป็นค่าเริ่มต้นด้วยแค่ปรับแต่งนิดหน่อยและเปิดฟีเจอร์ในตัวไม่กี่อย่าง การใช้งานก็ดีขึ้นมากแล้ว ซึ่ง
bedrockกับemacs-soloก็จัดแบบนั้นทุกครั้งที่เริ่ม Emacs จะมีข้อความใหญ่ ๆ เรื่อง
dylibที่หายไปเด้งขึ้นมาทุกครั้งไวยากรณ์ของ
(treesit-auto-install-grammar t)กับ(treesit-enabled-modes t)ในตัวอย่างดูเหมือนการเรียกฟังก์ชัน แต่จริง ๆ แล้วเป็น ตัวเลือก ที่ต้องตั้งค่าในรีลีสถัดไปก็มีการเปลี่ยนแปลงเล็ก ๆ ที่ชอบเหมือนกัน:
minibuffer-nonselected-modeถูกเปิดเป็นค่าเริ่มต้น ทำให้เห็นได้ชัดขึ้นว่ามีงานที่ยังค้างใน minibuffer หรือไม่ และdiff-modeมีdiff-delete-other-hunksซึ่งมีประโยชน์มากเมื่อใช้ร่วมกับพฤติกรรม VC ของบัฟเฟอร์ diff ที่เพิ่มเข้ามาใน Emacs 29with-work-bufferคล้ายกับwith-temp-bufferแต่ใช้บัฟเฟอร์พูลซ้ำ รู้เรื่องนี้เพราะบังเอิญใช้รูปแบบชื่อบัฟเฟอร์เดียวกันคือ*work*ในการตั้งค่าส่วนตัวEmacs 31 มี
lua-modeมาให้แล้ว จึงไม่ต้องติดตั้งแยกอีกต่อไปผมก็ต้องปรับอีกนิดเพื่อให้มันกลับมาทำงานตรงตามที่ต้องการ:
xterm-mouse-modeถูกเปิดเป็นค่าเริ่มต้นเลยต้องปิดเอง และ face ของmode-lineจะเปลี่ยนให้เข้ากับธีมมืด แต่ผมชินกับสีค่าเริ่มต้นแบบเดิมเลยเปลี่ยนกลับEmacs 31 จะเตือนถ้าไฟล์ซอร์สไม่มีคุกกี้
lexical-bindingถ้ารำคาญก็ปิดได้ และแก้ได้ง่ายด้วยคำสั่งelisp-enable-lexical-bindingรวมถึงสามารถตั้งให้lexical-bindingเป็นค่าเริ่มต้นแบบโกลบอลได้ด้วยถ้าไม่มีบั๊กใหม่ ๆ ก็น่าจะเป็น รีลีสที่แข็งแกร่ง ตามเคย
:customของuse-packageเลยทำให้ผมรู้สึกก้ำกึ่งกับ
:customเวลาอยากทดลองค่าหรือแชร์ มันยุ่งยากกว่าเดิมwith-work-bufferมีไว้เพื่อ ประสิทธิภาพ หรือเปล่า? ในเอกสารไม่ได้บอกว่าทำไมควรใช้แทนwith-temp-bufferมีแต่บอกว่าต้องระวังมากกว่าelpaแต่เตือนเฉพาะไฟล์ของผมเองอีกอย่าง จากคำเตือน 68 รายการใน Emacs ของผม มีถึง 64 รายการที่มาจากไฟล์ที่ถูกสร้างขึ้นอย่าง
-autoloads.elเรื่องนี้คงต้องไปแก้ที่เครื่องมือสร้างฝั่งelpa/melpaในที่สุดก็มี xref ที่แก้ไขได้ อย่างที่อยากได้มานาน ดูแล้วน่าจะทำให้ชีวิตผมสะดวกขึ้นมาก
มีการเปลี่ยนแปลงดี ๆ เยอะมากที่ส่งผลถึงสิ่งที่จับต้องทุกวันอย่างน่าทึ่ง
Nvim เคยเปลี่ยนค่าเริ่มต้นจาก regex แบบ vim ไปเป็น treesitter แล้วทำให้สภาพแวดล้อมการเขียนของผมพัง
treesitter ต้องตั้งค่าเพิ่มพอสมควรถึงจะ parse คอมเมนต์ HTML ใน Markdown ได้ และต่อให้ปะติดปะต่อทุกอย่างแล้วมันก็ยังไม่ทำงาน
สุดท้ายเลยแก้ด้วยการปิด treesitter
ผมค่อนข้างอนุรักษ์นิยมมากกับโครงสร้างพื้นฐานระดับแกนอย่างเอดิเตอร์ การเปลี่ยนเอดิเตอร์ส่วนใหญ่มักทำให้ของบางอย่างที่ใช้งานได้ดีมาหลายปีพัง