1 คะแนน โดย GN⁺ 13 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • แม้ 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-31 branch และ master มาใช้งานเองในช่วง กลางปี 2026
  • รายการที่แนะนำเหล่านี้คือความเปลี่ยนแปลงที่ถูกนำมาใช้จริงในค่าตั้งประจำวัน และส่วนใหญ่ได้เข้าไปอยู่ใน Emacs core แล้วหรืออยู่ในสถานะใกล้เคียงมาก
  • ชื่อฟีเจอร์และค่าเริ่มต้นอาจเปลี่ยนได้จนกว่าจะถึง release สุดท้าย
  • ตัวอย่างการตั้งค่าดูได้จาก init.el ของ Emacs Solo ที่มีคอมเมนต์ ; EMACS-31

การลดภาระการตั้งค่า Tree-sitter

  • ใน Emacs 31 มีสองตัวเลือกที่ทำให้การสลับไปใช้โหมดที่อิง Tree-sitter และขั้นตอนติดตั้ง grammar เรียบง่ายขึ้น
    • treesit-enabled-modes t
    • treesit-auto-install-grammar t
  • หากตั้ง treesit-enabled-modes เป็น t major 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-config
  • eldoc-help-at-pt t จะแสดงข้อมูลช่วยเหลือของรายการใต้เคอร์เซอร์โดยไม่ต้องเรียกแยกต่างหาก
    • หากใช้ร่วมกับ eldoc-echo-area-prefer-doc-buffer ก็จะมีคำแนะนำเพิ่มขึ้นเวลาไล่อ่านโค้ดที่ไม่คุ้นเคย
  • การตั้งค่าใหม่ที่เกี่ยวกับ completion ทำให้ UI อัปเดตเชิงรุกมากขึ้นระหว่างพิมพ์
    • completion-eager-update t
    • completion-eager-display 'auto
    • minibuffer-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-list
    • icomplete-vertical-render-prefix-indicator

การจัดวางหน้าต่างและ Speedbar

  • Emacs 31 เพิ่มคำสั่งสำหรับเปลี่ยน layout โดยไม่ต้องแบ่งและปิดหน้าต่างใหม่เอง
    • window-layout-transpose
    • window-layout-rotate-clockwise
    • window-layout-flip-leftright
    • window-layout-flip-topdown
  • transpose จะสลับการจัดวางแนวนอน/แนวตั้ง, rotate จะหมุน layout ทั้งหมด, ส่วนคำสั่ง flip จะสะท้อนซ้ายขวาหรือบนล่าง
  • มีประโยชน์เมื่ออยากเปลี่ยนแค่ตำแหน่งหน้าต่างแก้ไขในชุดหน้าต่าง 3 บาน โดยยังคง buffer เดิมไว้
  • ใน Emacs 31, Speedbar สามารถอยู่ใน side window แทน frame แยกได้
    • speedbar-window-default-width
    • speedbar-window-max-width
    • speedbar-window
  • speedbar-window จะ dock Speedbar ไว้ด้านข้างเหมือนไฟล์ทรีสมัยใหม่
  • ในสภาพแวดล้อมแบบ tiling หรือโน้ตบุ๊กจอเดียว วิธี side window จะเหมาะกว่าฟลอตติ้งเฟรมแบบเดิม

VC และ xref ที่แก้ไขได้

  • VC มีการตั้งค่าที่ช่วยลดขั้นตอนในเวิร์กโฟลว์ version control ประจำวัน
    • vc-auto-revert-mode t
    • vc-allow-rewriting-published-history t
    • vc-dir-auto-hide-up-to-date 'revert
  • vc-dir-auto-hide-up-to-date จะซ่อนไฟล์ที่เป็นสถานะล่าสุดโดยอัตโนมัติเมื่อรีเฟรช buffer vc-dir
    • ทำให้ลบ key hack ที่เคยเรียก vc-dir-hide-up-to-date หลัง vc-dir-refresh ได้
  • 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
  • ข้อเสนอแรกคือใช้ 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-x
    • ibuffer-human-readable-size t: แสดง KB/MB แทน raw byte
    • ielm-history-file-name: เก็บประวัติอินพุตของ IELM ข้ามการรีสตาร์ต
    • kill-region-dwim 'emacs-word: เมื่อไม่มี active region, C-w จะ kill คำถัดไปแทนการขึ้น error
    • native-comp-async-on-battery-power nil: หยุด background native compilation ระหว่างใช้แบตเตอรี่
    • view-lossage-auto-refresh t: C-h l อัปเดตรายการคีย์ล่าสุดแบบเรียลไทม์
    • display-fill-column-indicator-warning nil
    • dired-hide-details-hide-absolute-location t: ซ่อนพาธไดเรกทอรีแบบ absolute ใน dired-hide-details-mode
    • world-clock-sort-order "%FT%T": ปรับลำดับการเรียงของ world clock
    • zone-all-frames t
    • zone-all-windows-in-frame t
    • uniquify-after-kill-buffer-flag t: เปลี่ยนชื่อมาจากตัวแปรแบบ -p เดิม
  • kill-region-dwim ช่วยหลีกเลี่ยง error “the mark is not active” จาก C-w
  • view-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: ธีมพื้นขาวที่ปรับให้เหมาะกับ deuteranopia
    • modus-operandi: ธีมพื้นขาวที่อ่านง่ายสูง
    • modus-operandi-tinted: ธีมพื้นสีเหลืองดินอ่อนที่อ่านง่ายสูง
    • modus-operandi-tritanopia: ธีมพื้นขาวที่ปรับให้เหมาะกับ tritanopia
    • modus-vivendi-deuteranopia: ธีมพื้นดำที่ปรับให้เหมาะกับ deuteranopia
    • modus-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 ก็ใกล้เคียงกับสิ่งที่ต้องการพอสมควร แต่ยังใช้งานไม่สะดวกเท่าแพ็กเกจภายนอกอย่าง corfu

    • สักวันหนึ่งคงจะดีถ้าได้ประสบการณ์ที่ใกล้กับ vertico และพวกนั้น ด้วยฟีเจอร์ที่มีมาในตัวเท่านั้น แถมเปิดใช้เป็นค่าเริ่มต้นด้วย
      แค่ปรับแต่งนิดหน่อยและเปิดฟีเจอร์ในตัวไม่กี่อย่าง การใช้งานก็ดีขึ้นมากแล้ว ซึ่ง bedrock กับ emacs-solo ก็จัดแบบนั้น
    • ผมใช้ Emacs 32 ทุกวันอยู่ แต่จะบอกว่า treesit ใช้งานได้เลยทันที ก็คงไม่เชิง
      ทุกครั้งที่เริ่ม Emacs จะมีข้อความใหญ่ ๆ เรื่อง dylib ที่หายไปเด้งขึ้นมาทุกครั้ง
  • ไวยากรณ์ของ (treesit-auto-install-grammar t) กับ (treesit-enabled-modes t) ในตัวอย่างดูเหมือนการเรียกฟังก์ชัน แต่จริง ๆ แล้วเป็น ตัวเลือก ที่ต้องตั้งค่า
    ในรีลีสถัดไปก็มีการเปลี่ยนแปลงเล็ก ๆ ที่ชอบเหมือนกัน: minibuffer-nonselected-mode ถูกเปิดเป็นค่าเริ่มต้น ทำให้เห็นได้ชัดขึ้นว่ามีงานที่ยังค้างใน minibuffer หรือไม่ และ diff-mode มี diff-delete-other-hunks ซึ่งมีประโยชน์มากเมื่อใช้ร่วมกับพฤติกรรม VC ของบัฟเฟอร์ diff ที่เพิ่มเข้ามาใน Emacs 29
    with-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
    ผมค่อนข้างอนุรักษ์นิยมมากกับโครงสร้างพื้นฐานระดับแกนอย่างเอดิเตอร์ การเปลี่ยนเอดิเตอร์ส่วนใหญ่มักทำให้ของบางอย่างที่ใช้งานได้ดีมาหลายปีพัง

    • โชคดีที่ Emacs ไม่ได้เปลี่ยนค่าเริ่มต้นไปใช้ treesitter แต่ยังคงเป็น การเปิดใช้แบบเลือกเองทั้งหมด เท่านั้น