2 คะแนน โดย GN⁺ 2024-01-31 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • หากต้องการให้ธีมอย่าง Solarized แสดงผลได้ถูกต้องใน Emacs บนเทอร์มินัล สิ่งที่สำคัญกว่า สี 24 บิต เองคือเทอร์มินัล, terminfo, tmux และ mosh เข้าใจความสามารถด้านสีเดียวกันตลอดทางหรือไม่
  • สี RGB ถูกใช้กันอย่างแพร่หลายในรูปแบบ ESC[38;2;<r>;<g>;<b>m แต่ยังคงมีทั้ง ไวยากรณ์แบบโคลอน ที่ใกล้เคียงมาตรฐาน และไวยากรณ์แบบเซมิโคลอนที่แพร่หลายในอิมพลีเมนต์จริง ทำให้ความเข้ากันได้ซับซ้อนขึ้น
  • xterm-256color และ xterm-direct ประกาศความสามารถเป็นพาเล็ต 256 สีและ 16,777,216 สีตามลำดับ แต่โมเดลของ terminfo ที่ยึดพาเล็ตเป็นหลักไม่สามารถแสดง สี RGB โดยตรง ได้อย่างเรียบร้อย
  • ในสภาพแวดล้อมจริง อาจต้องใช้ค่า TERM ทางเลือก เช่น รายการ -direct ของ ncurses-term, tmux-direct, mosh สาย 1.4, vscode-direct และบางเลเยอร์ยังรับเฉพาะรูปแบบเซมิโคลอนเท่านั้น
  • หากต้องการใช้ความสามารถของเทอร์มินัลสมัยใหม่ให้เสถียร TERM และ terminfo เพียงอย่างเดียวไม่พอ จำเป็นต้องมีวิธีแสดงความสามารถแบบแยกต่างหากที่อัปเดตได้เร็วขึ้นตามชื่อและเวอร์ชันของเทอร์มินัล

เหตุผลที่ Emacs บนเทอร์มินัลต้องใช้สี 24 บิต

  • Emacs ในสภาพแวดล้อมกราฟิกจะรองรับ สี 24 บิต โดยอัตโนมัติ ทำให้แสดงธีมอย่าง Solarized และฟอนต์ได้ถูกต้อง
  • หากใช้ธีมเดียวกันในเทอร์มินัล การแสดงสีอาจถูกจำกัด ทำให้หน้าจอดูไม่สวยเท่าที่ควร
  • เทอร์มินัลยอดนิยมรองรับสี 24 บิตมานานแล้ว แต่โปรแกรมจะใช้ได้ก็ต่อเมื่อทั้งการตรวจจับความสามารถและการตั้งค่าถูกต้อง
  • เป้าหมายมีสองข้อ
    • หาวิธีเปิดการรองรับ truecolor ในสภาพแวดล้อมเทอร์มินัลปัจจุบัน
    • ตรวจสอบว่าปัญหาสีของ Emacs เชื่อมโยงกับมาตรฐานเทอร์มินัลยุค 1970–1990 อย่างไร

ANSI escape codes และประวัติการขยายความสามารถด้านสี

  • เทอร์มินัลฮาร์ดแวร์ยุคแรกใช้ชุดรหัสควบคุมที่แตกต่างกัน และการสร้างซอฟต์แวร์ที่พอร์ตได้จำเป็นต้องมีการทำให้เป็นมาตรฐานโดย ANSI
  • ANSI escape codes มีมาตั้งแต่ทศวรรษ 1970 และในด้านสี SGR(Select Graphics Rendition) คือส่วนสำคัญ
    • ตัวหนาหรือความสว่าง
    • ตัวเอียง
    • การกะพริบ
    • สีพื้นหน้าและสีพื้นหลัง
    • คุณสมบัติการแสดงผลตัวอักษรอื่น ๆ
  • ในตอนแรก สีเป็น สี 3 บิต ที่ตรงกับจุดยอด 8 จุดของลูกบาศก์ RGB
    • รวมสีดำ สีขาว สีปฐมภูมิแบบบวก และสีปฐมภูมิแบบลบ
  • ต่อมามีการเพิ่มสีสว่างหรือบิตตัวหนา ขยายเป็น 16 สี
    • “bright black” ตรงกับสีเทาเข้ม
  • ในปี 1999 Todd Larason เพิ่มแพตช์ รองรับ 256 สี ให้ xterm
    • การสุ่มตัวอย่างลูกบาศก์สี RGB ขนาด 6x6x6
    • แถบไล่ระดับสีเทา 24 ระดับ
    • ยังมีรูปแบบ 88 สีที่พบไม่บ่อยแต่ยังรองรับอยู่ด้วย

เส้นทางที่ทำให้เกิดไวยากรณ์สี 24 บิต

  • สี 8 บิตและสี 24 บิตถูกตั้งค่าในเทอร์มินัลที่รองรับด้วยรูปแบบต่อไปนี้
    • ESC[38;5;<n>m: ตั้งหมายเลขสี n ในพาเล็ตเป็นสีพื้นหน้า
    • ESC[38;2;<r>;<g>;<b>m: ตั้งค่า RGB r, g, b เป็นสีพื้นหน้า
  • ตัวเลข 5 และ 2 เชื่อมโยงกับโหมดสีแบบขยายของ ISO 8613-6 หรือ ITU T.416
    • 2: สีโดยตรงในปริภูมิ RGB
    • 5: สีแบบดัชนี
  • ลำดับการทำให้เป็นมาตรฐานมีดังนี้
    • ทศวรรษ 1970: ANSI ทำให้ escape sequence ของเทอร์มินัลเป็นมาตรฐาน นำไปสู่ ANSI X3.64 และ ECMA-48
    • ปี 1979: ECMA-48 ฉบับที่ 2 กำหนด SGR 30~37, 40~47 ให้เป็นสีพื้นหน้าและพื้นหลังแบบ 3 บิต
    • ปี 1984: ECMA-48 ฉบับที่ 3 นำแนวคิดสีพื้นหน้าและพื้นหลังเริ่มต้นเข้ามา และกำหนด 39, 49
    • ปี 1991: ECMA-48 ฉบับที่ 5 เว้น 38 และ 48 ไว้ “สำหรับการทำให้เป็นมาตรฐานในอนาคต” พร้อมอ้างอิง ISO 8613-6
    • ปี 1993: ISO 8613-6 นิยาม 38 และ 48 เป็นโหมดสีพื้นหน้าและพื้นหลังแบบขยาย
  • การคั่นพารามิเตอร์ย่อยด้วย โคลอน ใกล้เคียงมาตรฐานกว่า แต่การใช้งานจริงยอมรับเซมิโคลอนอย่างแพร่หลาย
    • ESC[38;5;3m อาจถูกเทอร์มินัลที่ไม่รู้จัก SGR 38 ตีความเหมือนเป็นพารามิเตอร์แยกกันคือ 38, 5, 3
    • xterm FAQ ของ Thomas Dickey อธิบายว่าในตอนนั้นสำเนา ITU T.416 มีราคาแพง และการคั่นค่า RGB ด้วยเซมิโคลอนเหมือนพารามิเตอร์ SGR อื่น ๆ นั้นเป็นความผิดพลาด
  • ไทม์ไลน์ที่เกี่ยวข้องมีดังนี้
    • ปี 1999: Thomas Dickey ผสานแพตช์ 256 สีของ Todd Larason เข้า xterm และไวยากรณ์เซมิโคลอนที่กำกวมก็ถูกรวมเข้าไป
    • ปี 2006: Konsole รองรับ 256 สีและ truecolor 24 บิตด้วยไวยากรณ์เซมิโคลอนแบบเดียวกับ xterm
    • ปี 2012: xterm ถูกแก้ไขให้รับไวยากรณ์แบบโคลอนที่ใกล้เคียงมาตรฐานได้ด้วย
    • ปี 2016: คอนโซลในตัวของ Windows 10 รองรับ ANSI escape codes และสี 24 บิต แต่ใช้ไวยากรณ์เซมิโคลอน
    • ปี 2019: Windows Terminal ก็รองรับ ANSI escape codes แต่ใช้ไวยากรณ์เซมิโคลอน
    • ปี 2022: Microsoft ประกาศการเปลี่ยนผ่านของอีโคซิสเต็มจากระบบย่อยคอนโซลสไตล์ VGA รุ่นเก่าไปสู่การจำลองเทอร์มินัล ANSI
    • ปี 2022: Konsole รองรับไวยากรณ์โคลอนที่เข้ากันได้กับมาตรฐาน

วิธีที่ terminfo แสดงความสามารถด้านสี

  • terminfo ให้ฐานข้อมูลความสามารถของเทอร์มินัลและความสามารถในการสร้าง escape sequence ที่เหมาะสม
  • ตัวแปรสภาพแวดล้อม TERM ชี้ไปยังเรคคอร์ด terminfo ที่โปรแกรมจะใช้ และจะถูกส่งต่ออัตโนมัติในการเชื่อมต่อ ssh ด้วย
  • toe แสดงรายการเรคคอร์ด terminfo ที่ติดตั้งไว้ และ infocmp ใช้ตรวจสอบความสามารถของเรคคอร์ดเฉพาะ
  • ความสามารถสำคัญที่เกี่ยวข้องกับสีมีสามอย่าง
    • colors: จำนวนสีที่เทอร์มินัลรองรับ
    • setaf: ตั้งค่าสีพื้นหน้า
    • setab: ตั้งค่าสีพื้นหลัง
  • setaf ของ xterm-256color จะส่ง sequence ต่างกันตามหมายเลขสี
    • 0~7: ใช้พารามิเตอร์ ANSI 30~37 SGR
    • 8~15: ใช้สีสว่าง 90~97 ที่ไม่ใช่มาตรฐาน
    • มากกว่านั้น: ใช้พาเล็ต 256 สีรูปแบบ 38;5;<n>
  • xterm-direct เป็นรายการ terminfo สำหรับ RGB 24 บิตที่ประกาศ colors เป็น 16,777,216
    • ปิด ccc ซึ่งระบุว่าไม่สามารถกำหนดค่า RGB ใหม่ให้ดัชนีสีได้
    • รายการที่เกี่ยวกับการเปลี่ยนสีขณะรันไทม์ เช่น initc, oc, rs1 ก็หายไปด้วย
    • setaf และ setab ใช้รูปแบบอิงโคลอน 38:2::...

ข้อจำกัดของโมเดลสีโดยตรงใน terminfo

  • โมเดลการเขียนโปรแกรมของ terminfo และ ncurses โดยพื้นฐานยึด รายการพาเล็ต เป็นศูนย์กลาง
    • มีรายการพาเล็ต N รายการ
    • แต่ละรายการมีค่า RGB เริ่มต้น
    • ถือโมเดลว่าเทอร์มินัลสามารถเปลี่ยนค่าเหล่านี้ได้
  • เทอร์มินัล -direct แสดงสี 24 บิตโดยทำเหมือนว่ามีรายการพาเล็ต 16,777,216 รายการ
    • แต่ละรายการสอดคล้องกับลูกบาศก์ RGB แบบ 8:8:8
    • ค่าไม่สามารถเปลี่ยนได้
  • เพื่อความเข้ากันได้ วิธีของ xterm-direct ใช้สีน้ำเงินเข้มที่สุด 7 สีสำหรับความเข้ากันได้กับ ANSI 8 สีพื้นฐาน
    • ไม่รวมสีดำ
    • เป็นกลไกเพื่อหลีกเลี่ยงไม่ให้โปรแกรมเดิมที่สมมติความหมายของ setaf แสดงผลเป็นสีน้ำเงินเข้มจนแทบมองไม่เห็น
  • ด้วยเหตุนี้ วิธี -direct และ -256color จึงเข้ากันไม่ได้
    • โปรแกรมต้องรู้ว่า 256 สีเป็นสีแบบดัชนี และ 16,777,216 สีเป็นสีโดยตรง
    • ยังมีข้อยกเว้นที่ต้องหลีกเลี่ยงสีน้ำเงินเข้มที่สุด 7 สีด้วย
  • ในปัญหาที่เกี่ยวข้องกับ termwiz โปรแกรมคาดหวังพาเล็ต xterm-256color แต่จริง ๆ แล้วแสดงผลเป็นกลุ่มสีน้ำเงินเข้มที่อ่านยาก
    • ตอนเขียน อิชชูนี้ยังเปิดอยู่ แต่ @quark-zju ได้นำการแก้ไขเข้าไปแล้ว และตอนนี้ termwiz ทำงานได้สมเหตุสมผล
  • ประเด็นหลักใกล้เคียงกับ ข้อจำกัดของ terminfo มากกว่าตัวเทอร์มินัลเอง
    • เทอร์มินัลที่รองรับสี 24 บิตดูเหมือนจะรองรับทั้งพาเล็ต 256 สีของ xterm และการเปลี่ยนค่า RGB แบบไดนามิกด้วย
    • terminfo ไม่เพียงพอที่จะอธิบายอีโคซิสเต็มเทอร์มินัลอีมูเลเตอร์สมัยใหม่ได้อย่างถูกต้องและรวดเร็ว

การตั้งค่า TERM และความเข้ากันได้กับเซมิโคลอน

  • เนื่องจากโปรแกรมจำนวนมากใช้ terminfo จึงต้องตั้งค่า TERM ให้ถูกต้อง
  • แม้จะอยากรวมให้ใช้ไวยากรณ์ SGR แบบโคลอน แต่หลายสภาพแวดล้อมยังรองรับเฉพาะ ไวยากรณ์เซมิโคลอน
    • Conhost ซึ่งเป็นคอนโซลในตัวของ Windows
    • Mintty และพฤติกรรมบางอย่างในสภาพแวดล้อม Cygwin
    • Mosh
    • PuTTY
    • เวอร์ชัน Konsole ที่รวมมากับ Ubuntu 22.04 LTS
  • รายการ terminfo ประกอบด้วย building blocks
    • xterm+direct: ไวยากรณ์โคลอนที่ใกล้เคียงมาตรฐาน
    • xterm+indirect: สำหรับเทอร์มินัลรุ่นเก่าที่รองรับเฉพาะเซมิโคลอน
  • จากการค้นหา xterm+indirect พบว่า vscode-direct ดูเหมาะสมที่สุด
    • เนื่องจากมุ่งเป้าไปที่เทอร์มินัลของ Microsoft จึงถือว่าใกล้เคียงกับ Windows Terminal และ Windows Console เพียงพอ
    • ไม่ได้ตรวจสอบทุกความสามารถอย่างละเอียด แต่ใช้งานได้
  • เซิร์ฟเวอร์จำนวนมากอาจไม่ได้ติดตั้งรายการ terminfo แบบ -direct
    • ในระบบส่วนใหญ่ ฐานข้อมูล terminfo พื้นฐานอยู่ในแพ็กเกจ ncurses-base
    • รายการเทอร์มินัลแบบขยายต้องใช้แพ็กเกจ ncurses-term
  • ระหว่างเขียน ncurses ได้เพิ่มรายการ terminfo winconsole แต่ไม่รองรับสี 24 บิต และยังไม่ได้ถูกปล่อยใน ncurses เวอร์ชันใด

วิธีที่ Emacs ตรวจจับ truecolor

  • Emacs จัดทำเอกสารวิธีตรวจจับการรองรับ truecolor บน TTY
  • เมื่อรัน (display-color-cells) ใน M-x eval-expression จะตรวจสอบได้ว่า Emacs รับรู้สี 16,777,216 สีหรือไม่
  • เอกสารของ Emacs ยังกล่าวถึงข้อจำกัดของ terminfo ในโหมด -direct
    • เทอร์มินัลที่มีความสามารถ RGB อาจปฏิบัติต่อ #000001 ถึง #000007 เหมือนเป็นสีแบบดัชนี ไม่ใช่ RGB โดยตรง
    • นี่ทำเพื่อรักษาความเข้ากันได้ย้อนหลังกับแอปพลิเคชันที่ไม่รู้จัก direct color
    • หากเป็นปัญหา สามารถใช้คำจำกัดความเทอร์มินัลแบบกำหนดเองที่มี setb24, setf24 ได้
  • Emacs จะค้นหาสตริง setf24 และ setb24 ก่อน หากไม่มีจึงใช้ RGB เป็นความสามารถสำรอง
  • รายการ terminfo ในระบบที่ตรวจสอบไม่มี setf24

ในเทอร์มินัลซ้อนกัน ทุกเลเยอร์ต้องตรงกัน

  • เวิร์กโฟลว์ทั่วไปจะซ้อนเลเยอร์เทอร์มินัลหลายชั้น
    • เปิดเทอร์มินัลอีมูเลเตอร์แบบกราฟิกบนเดสก์ท็อปโลคัล
    • เชื่อมต่อไปยังเครื่องรีโมตหรือ VM ด้วย mosh
    • เริ่ม tmux
    • ใช้เทอร์มินัลภายใน Emacs, Asciinema, GNU Screen ฯลฯ เพิ่มเติม
  • แต่ละเลเยอร์จะมีการใช้งาน state machine ของ ANSI escape sequence เป็นของตัวเอง
  • เพื่อให้สี 24 บิตทำงานได้ ทุกเลเยอร์ต้องเข้าใจ escape sequence ที่สร้างจาก terminfo ของค่า TERM ชั้นใน และส่งต่อให้ถูกต้องตาม terminfo ชั้นนอก
  • ดังนั้นซอฟต์แวร์ที่เกี่ยวข้องต้องใหม่พอ
    • Ubuntu LTS ปัจจุบันให้ mosh 1.3 จึงต้องเปิดใช้ mosh-dev PPA
  • TERM ภายในแต่ละเลเยอร์ก็ต้องถูกต้องด้วย
    • ภายใน tmux ใช้ tmux-direct
    • mosh ไม่มี terminfo มาตรฐาน จึงต้องเลือกค่าที่ใกล้เคียงพอ

การตั้งค่าตามสภาพแวดล้อม

  • เทอร์มินัลอีมูเลเตอร์แบบกราฟิก

    • เทอร์มินัลส่วนใหญ่ตั้งค่า TERM เริ่มต้นที่เหมาะสม หรือให้ผู้ใช้ override ได้
    • Konsole มีตัวเลือกให้เลือกค่า TERM
  • ssh

    • ssh ส่งต่อค่า TERM ไปยังเชลล์ใหม่
    • หากโฮสต์รีโมตมีเรคคอร์ด terminfo เดียวกัน การตั้งค่าจะค่อนข้างง่าย
  • tmux

    • เมื่อรัน tmux ค่า TERM อาจถูกตั้งเป็น screen
    • แก้ได้โดยเปลี่ยนเทอร์มินัลเริ่มต้นใน ~/.tmux.conf
    set -g default-terminal "tmux-direct"
    
    • อาจพิจารณาวิธีตั้ง tmux-direct แบบมีเงื่อนไขเฉพาะเมื่อ TERM ชั้นนอกรองรับสี 24 บิต และหากไม่รองรับก็รักษา screen หรือ tmux-256color ไว้
  • mosh

    • mosh รุ่นใหม่รองรับสี 24 บิต แต่ตัวมันเองประกาศความสามารถแค่ 8 สีหรือ 256 สี
    • ดังนั้นผู้ใช้ต้องตั้งค่า TERM ให้เหมาะสมเอง
    • mosh มุ่งให้เข้ากันได้กับ xterm แต่รองรับเฉพาะไวยากรณ์เซมิโคลอนใน SGR 38 และ 48
    • TERM=xterm-direct ใช้งานไม่ได้
    • vscode-direct ถูกใช้เป็นทางเลือกที่ใกล้เคียง xterm-direct ที่สุด
    • เนื่องจากไม่มีตัวแปรสะดวก ๆ ที่บอกว่ากำลังรันผ่าน mosh จึงเขียนสคริปต์ detect-mosh.rs แล้วเรียกจาก .bashrc
    • วิธีนี้ตรวจสอบว่าโปรเซสเชลล์เป็นลูกของ mosh-server หรือไม่
    • ยังไม่ได้สรุปว่าการคอมไพล์ Rust ในเส้นทางล็อกอินเหมาะกับโฮสต์ประสิทธิภาพต่ำหรือไม่

ผลลัพธ์สุดท้ายและปัญหาที่ยังเหลือ

  • หลังตั้งค่าแล้ว ธีมใน Emacs ภายใน tmux และ mosh ก็แสดงผลด้วย สี 24 บิต
  • ปัญหาที่เหลือสรุปได้สามข้อ
    • เทอร์มินัลยังไม่ได้ตกลงกันอย่างสมบูรณ์เรื่องไวยากรณ์และความสามารถ
    • terminfo เป็นเส้นทางมาตรฐานสำหรับการค้นหาความสามารถ
    • terminfo มีข้อจำกัด บางครั้งไม่ถูกต้อง และไม่ได้ออกเวอร์ชันใหม่บ่อยนัก

ทิศทางหลังยุค terminfo

  • หากเป็นซอฟต์แวร์ที่ใช้ความสามารถของเทอร์มินัลสมัยใหม่ได้เต็มที่ ก็จำเป็นต้องก้าวออกจาก terminfo
  • แนวทางที่เป็นไปได้มีดังนี้
    • ใช้ตัวแปร TERM ที่รองรับกันแพร่หลายต่อไป
    • ไม่พึ่งพาเฉพาะ terminfo เก่าของระบบปฏิบัติการหรือดิสโทร และทำให้โปรแกรมรู้ความสามารถของเทอร์มินัลได้อย่างอิสระ
    • ใส่ข้อมูลเทอร์มินัลอีมูเลเตอร์ช่วงราว 10 ปีล่าสุดตามชื่อและเวอร์ชันไว้ในไลบรารีที่อัปเดตบ่อย
    • ไม่รวมการรองรับเทอร์มินัลฮาร์ดแวร์ที่ใช้งานยากแล้ว
    • รองรับไฟล์ terminfo ที่ OS ให้มาและรูปแบบไฟล์ terminfo ต่อไป แต่มีโปรโตคอลที่ตัดสินได้ว่าข้อมูลใดล่าสุด
    • ใช้ TERMVERSION แบบเลือกได้เพื่อแยกความแตกต่างของความสามารถตามเวอร์ชัน เช่น Konsole ปี 2022 กับ Konsole ปี 2023
    • แสดงความสามารถสมัยใหม่ เช่น สี 24 บิต, แอนิเมชันพาเล็ต 256 สี, ลิงก์ URL, Kitty graphics protocol ได้อย่างไม่กำกวม
  • วิธีรองรับย้อนหลังสำหรับโปรแกรม legacy ก็เป็นไปได้
    • โปรแกรมที่รันจาก .bashrc ใช้ TERM และ TERMVERSION เพื่อสร้างไฟล์ terminfo แบบไบนารีใน $HOME/.terminfo/
    • สร้างความสามารถสี 24 บิตที่ชัดเจน เช่น RGB, setf24, setb24
    • ถือว่าโปรแกรมที่ไม่รู้จัก RGB จะสมมติว่าเป็นพาเล็ต 256 สี และคง colors#0x100, initc, oc ไว้

1 ความคิดเห็น

 
GN⁺ 2024-01-31
ความคิดเห็นจาก Hacker News
  • การไปคุ้ย terminfo ให้ความรู้สึกเหมือนส่องอักษรภาพด้วยคบเพลิงริบหรี่ในสุสานใต้ดินลึก
    พอนึกถึงว่ามีความซับซ้อนมากแค่ไหนถูกยัดอยู่ในแอปเทอร์มินัลตัวเดียว มันก็น่าแปลกอยู่เหมือนกัน และยิ่งทำให้รู้สึกขอบคุณนักพัฒนาเทอร์มินัลอย่าง iTerm กับ Kitty มากขึ้น
    รวมฟังก์ชันสำหรับตั้งค่าสีแท็บใน iTerm+zsh ไว้ที่นี่: https://gist.github.com/aclarknexient/84ebe33c1879f921685304...
    ถ้าเทียบกับสมัยก่อนที่ต่อเข้า HTTP หรือ SMTP ผ่าน telnet ตัวข้อความเองอาจเรียบง่าย แต่ฝั่งที่ใช้แสดงข้อความนั้นเป็นแอปพลิเคชันซับซ้อนที่รองรับความสามารถสารพัด

    • ตอนทำเทอร์มินัลของตัวเอง ช่วงแรกผมเลือกไม่สนใจ terminfo แล้วแกล้งทำเป็นว่าเป็น rxvt พร้อมยอมรับปัญหาที่จะเกิดขึ้น
      ตอนนี้เป็นตัวเลือกที่ทำได้เพราะแทบจะมีผู้ใช้เทอร์มินัลนั้นอยู่แค่ตัวผมเอง แต่เทอร์มินัลสมัยใหม่รองรับชุดความสามารถร่วมกันพอสมควร เลยเจ็บปวดน้อยกว่าการที่แอปงงเพราะไม่รู้จักค่า TERM แปลกๆ
      แน่นอนว่าถ้าคุณไม่ได้ SSH เข้าเครื่องใหม่บ่อยๆ เรื่องนี้ก็สำคัญน้อยลง
    • ถ้ามี ภาพหน้าจอ ที่แสดงว่าสีแท็บถูกนำไปใช้จริงก็คงดี
    • ซอฟต์แวร์ที่คิดถึงที่สุดบน Mac คือ iTerm
      มันอาจไม่ใช่เทอร์มินัลอีมูเลเตอร์ที่เร็วที่สุด แต่หน้าตาดีที่สุดแบบทิ้งห่างตัวอื่น
  • สำหรับแต่ละแอปเทอร์มินัล การปรับ พาเล็ต 16 สี นั้นง่ายกว่าการไปจูนโค้ดฝั่งแอปพลิเคชันที่เกี่ยวกับเทอร์มินัลให้เป๊ะ
    ตั้งค่าสี rxvt-unicode ใน ~/.Xdefaults แล้วในธีม Emacs แบบ .el ก็กำหนดชื่อสีต่างกันตามว่าจะเป็นการแสดงผลแบบกราฟิกหรือไม่ จากนั้นค่อยนำไปใช้กับหลาย face
    ของแถมคือเอาต์พุต ls ที่มีสีก็ดูดีขึ้นด้วย พาเล็ต 16 สีมาตรฐานมักอิ่มสีเกินไปและคอนทราสต์ไม่ดี

    • ตรง (if (display-graphic-p) นี่แหละคือหัวใจ
      Emacs รองรับ การแสดงผลแบบกราฟิก จริงๆ และบน X11/Cocoa/Win32 ปุ่ม Esc ก็ทำงานเป็น Esc จริง รวมถึงใช้คีย์ลัด Ctrl+Shift หรือ Cmd, ใช้หลายฟอนต์พร้อมกัน, แสดงภาพ, เปลี่ยนรูปร่างเคอร์เซอร์ ฯลฯ ได้
      เหมือนเครื่องย้อนเวลาที่พาคุณไปยังปี 1989 ซึ่งล้ำหน้าไปอีก 20 ปี
    • บน จอแสดงผล TTL สมัยก่อน มันทำได้มากกว่านั้นไม่ได้ สีเลยอิ่มแบบนั้น
      เส้นสีแดงมีได้แค่แดงแรงสุดหรือไม่ติดไปเลย และถ้าเพิ่มเส้น intensity เข้ามาก็จะกลายเป็นแดง 100%
    • ถ้าใส่ซีเควนซ์ลงใน DIRCOLORS ls ก็รองรับ สี 24 บิต ได้จริง
    • ผมก็ปรับพาเล็ต 16 สีของ Terminology ในไฟล์ INI ให้เข้ากับธีมที่ชอบเหมือนกัน เพื่อให้คอนโซลกับแอปเทอร์มินัล (vim) ใช้สไตล์เดียวกัน
    • ผมก็ใช้แทบจะเหมือนกัน
      สีตั้งต้นมืดเกินไปเมื่อเทียบกับพื้นหลังสีเข้ม เลยเพิ่ม ความสว่างเชิงรับรู้ ของทุกสีขึ้น
  • ถ้าผู้เขียนรู้จัก export COLORTERM=truecolor ก็น่าจะลำบากน้อยกว่านี้มาก
    มันมีอยู่ทั้งในเชิงอรรถเรื่องการตรวจจับ truecolor ของเอกสาร Emacs ที่ลิงก์ไว้ และยังเห็นในภาพหน้าจอ Konsole ด้วย แต่มีโอกาสสูงว่าค่านี้หายไประหว่างทางในเทอร์มินัลมัลติเพล็กเซอร์ที่ซ้อนหลายชั้น
    การตั้งค่านี้ทำให้แอปรู้ได้ทันทีว่าต้องการ ทรูคัลเลอร์ จึงข้ามส่วนที่ยากไปได้ และไม่ต้องใช้ฐานข้อมูล terminfo ด้วย

    • ใช่เลย ในประวัตินี้ควรใส่เรื่องลองผิดลองถูกอย่าง COLORTERM และความสามารถ RGB ของ terminfo เข้าไปด้วย
      เพียงแต่ไม่ใช่ทุกโปรแกรมที่จะเคารพ COLORTERM ดังนั้นผมเคยตั้งใน .bashrc ให้ unset COLORTERM เมื่อเป็น linux | screen* และในกรณีอื่นก็ export COLORTERM=truecolor
      เดี๋ยวนี้ Screen รองรับสี 24 บิตแล้ว ดังนั้นนี่น่าจะเป็นการตั้งค่าสมัย Ubuntu 18
    • หรือจะใช้ GUI Emacs ที่ชอบร่วมกับ tramp หรือ sshfs ก็ได้
    • เห็นด้วย ถ้าหลงลงไปบนเส้นทาง terminfo ก็มีแต่ความบ้าคลั่งรออยู่
      อีกด้านหนึ่งก็เป็นเพราะผู้ดูแล ncurses ค่อนข้างอนุรักษนิยม ขณะที่นักพัฒนาเทอร์มินัลรุ่นใหม่อยากขยับให้เร็ว
    • ที่ไม่ต้องใช้ฐานข้อมูล terminfo เป็นเรื่องตั้งแต่ Emacs 28 เป็นต้นไป
      Emacs ที่เก่ากว่านั้นยังคงต้องใช้ฐานข้อมูล terminfo อยู่
    • COLORTERM เองก็ประหลาดพอสมควร
      ส่วนใหญ่ไม่จำเป็นต้องกำหนดมัน แต่ถ้าตั้ง COLORTERM=truecolor ไว้ในเซสชัน screen จู่ๆ หน้าจอก็จะแสดงผลเพี้ยนมาก และพอลบตัวแปรสภาพแวดล้อมนี้ออกก็กลับมาปกติ
  • เวลาโต้ตอบกับ Emacs ก็ไม่ได้จำเป็นต้องใช้เทอร์มินัลเสมอไป
    สามารถใช้ กราฟิกฟรอนต์เอนด์ สำหรับ macOS, Windows, X.org และ Wayland ได้
    Emacs แบบกราฟิกถ้าปิด toolbar ไว้ จะหน้าตาคล้ายกับ Emacs ที่รันในเทอร์มินัลมาก จนคนที่ไม่รู้จัก Emacs อาจเข้าใจผิดได้ง่ายว่าหน้าต่างกราฟิก Emacs บนเครื่องเพื่อนร่วมงานเป็นหน้าต่างเทอร์มินัล
    ในแบบสำรวจผู้ใช้ Emacs มีคนตอบว่า 80% ใช้กราฟิกฟรอนต์เอนด์

    • แย้งได้ว่าถ้าอยากใช้เทอร์มินัลโดยไม่ต้องแบกความเทอะทะของ GUI เต็มรูปแบบ แค่ xterm-mouse-mode ก็ให้ข้อดีได้ถึง 80% แล้ว
      ใส่ mouse, xterm-mouse-mode, mouse-wheel-mode, การตั้งค่าการเลื่อนหน้าจอ ฯลฯ ก็ใช้งานได้ดีพอสมควร และ auto-save-default ก็ปล่อยเป็น nil ตามพระประสงค์ของพระเจ้า
    • ไม่ได้รัน Emacs อยู่ในเทอร์มินัลอีมูเลเตอร์ แต่ Emacs คือเทอร์มินัลอีมูเลเตอร์
      โปรแกรมเทอร์มินัลทั้งหมดรันในบัฟเฟอร์ shell-mode ของกราฟิก Emacs และจะใช้ term-mode เฉพาะกับโปรแกรมหายากที่ต้องควบคุมแบบเต็มหน้าจอ
      แม้จะไม่ใช่ตัวที่ฟีเจอร์เยอะที่สุดหรือเร็วที่สุด แต่สามารถย้ายไปมาเหมือนบัฟเฟอร์อื่น ๆ และทำงานร่วมกับเนื้อหาที่กำลังแก้ไขได้อย่างลื่นไหล
      ถ้าเปิดกราฟิก Emacs บนเครื่องระยะไกลไม่ได้ ก็ใช้ tramp แก้ไขไฟล์ระยะไกล หรือเปิด headless Emacs server แล้วเชื่อมต่อด้วยกราฟิก emacsclient
    • เป็นข้อสังเกตที่ดี
      ไม่เคยคิดมาก่อนว่าคนอื่นอาจคิดว่าฉันรัน Emacs อยู่ในเทอร์มินัล
      กราฟิก Emacs ดีกว่ามาก แต่การที่ในเทอร์มินัลยังทำงานและดูเหมือนได้ราว 90% แบบเดียวกันก็ยังยอดเยี่ยมอยู่ดี
    • ใช้ Emacs ที่อิงกับ X ซึ่งโปรโตคอลมีประสิทธิภาพดี
      ความรู้สึกเบาพอ ๆ กับเทอร์มินัล และไม่ได้ให้ความรู้สึกแบบ VNC
      มีข้อดีอย่างฟอนต์, การใช้หลายฟอนต์พร้อมกัน, เมนู, เมาส์, สี, หลายเฟรม/หน้าต่าง
      ถ้ารันกราฟิกไว้ที่เครื่องโลคัลแล้วเข้าถึงระบบระยะไกลด้วย tramp ก็แทบจะสามารถแก้ไขไฟล์ตั้งค่าบนเราเตอร์ Linux ระยะไกลที่มีแค่ busybox ได้ พร้อมสิ่งอำนวยความสะดวกครบครัน
    • ท้ายที่สุดก็มีอยู่สองเหตุผลที่ทำให้กลับมาใช้ Emacs แบบเทอร์มินัลเสมอ
      ใช้ X11 แบบเป็นพัก ๆ มาตั้งแต่ยุค 90 แต่เรื่องฟอนต์ก็ยังเป็นระดับที่ต้องค้นไปเรื่อย ๆ จนเจอคำสั่งที่บังเอิญใช้ได้ แล้วก็ไม่กล้าแตะต้องมันอีก
      และเมื่อเทียบกับการตั้งค่า X11 ที่ต้องใช้ในสภาพแวดล้อมองค์กร โปรแกรมเทอร์มินัลส่วนใหญ่ก็ยังแสดงผลได้เร็วกว่าอย่างเห็นได้ชัด
  • ทุกวันนี้แค่ติดตั้ง Emacs เวอร์ชันใหม่ เปิดเทอร์มินัลที่รองรับ 24-bit xterm แล้วรัน emacs -nw ก็พอ
    ถ้าใช้ธีมแล้วดูโอเคก็จบ ถ้าไม่ก็เพิ่ม export COLORTERM=truecolor ลงใน .bashrc, .zshrc, .fishrc ฯลฯ แล้ว reload shell หรือรันบรรทัดนั้นอย่างเดียว จากนั้นค่อยเริ่ม emacs -nw ใหม่
    บทความนี้ทำให้ดูเหมือนต้องไปขุด terminfo แต่โดยทั่วไปไม่จำเป็นหรอก อาจจะเมื่อ 10 ปีก่อน แต่ตอนนี้ไม่ใช่แล้ว
    ลองเช็กคร่าว ๆ อีกครั้งกับ iTerm บน macOS และ Alacritty, Kitty, Gnome Terminal บน Linux แล้ว เดี๋ยวนี้การรองรับ 24-bit xterm เป็นเรื่องปกติ

  • วันนี้เพิ่งรู้ว่าใน command prompt ของ Windows 10 ก็รองรับ ANSI escape sequence มาตรฐานเหมือนกัน
    สีแบบ 24 บิตก็ใช้ได้ดี
    ถ้ารัน echo ^[[48;2;255;0;0mHello^[[0m คำว่า Hello จะถูกแสดงด้วยพื้นหลังสีแดง RGB(255,0,0) และ ^[[0m จะรีเซ็ตสีกลับเป็นปกติ
    ต้องพิมพ์ ^[ ด้วย CTRL-[ ห้ามพิมพ์ ^ กับ [ แยกกัน

    • ถ้าไม่อยากใส่อักขระที่พิมพ์ออกมาไม่ได้ลงไปตรง ๆ ในบรรทัดคำสั่ง ก็ใช้เอสเคปโค้ด \x1b หรือ alias \e กับคำสั่งที่รับ escape code ได้
      เช่น echo -e '\e[48;2;255;0;0mHello\e[0m'
      แต่ในสคริปต์ echo -e ไม่เป็นมาตรฐาน และแม้แต่ echo ปกติก็มีพฤติกรรมต่างกันในกรณีขอบ ๆ ดังนั้นควรใช้ printf '\e[48;2;255;0;0mHello\e[0m\n' เสมอ
    • อย่าลืมเพิ่ม DEVICE=C:\DOS\ANSI.SYS ลงในไฟล์ C:\CONFIG.SYS
  • เมื่อเทียบกับ vim/neovim ข้อดีที่สุดของ Emacs คือมันมี การรองรับ GUI แบบชั้นหนึ่ง ไม่ใช่แค่อีมูเลเตอร์เทอร์มินัลในหน้าต่าง
    รู้ว่ามีทั้ง gVim และฟรอนต์เอนด์ neovim กึ่ง ๆ กลาง ๆ อยู่มากมาย แต่รูปแบบการทำงานพื้นฐานของ Emacs คือ GUI จริง ๆ และตรงนั้นแหละที่ดี
    เทอร์มินัลก็โอเค แต่มีทั้งซากประวัติศาสตร์และข้อจำกัดเยอะเกินไป หลายอย่างในยุคนี้ก็ไม่น่าเมกเซนส์แล้ว
    ถ้าปัญหาคือการรัน Emacs บนเซิร์ฟเวอร์ระยะไกล ก็มี TRAMP และ emacsclient

    • ข้อดีของการรันทุกอย่างในเทอร์มินัลคือ ไม่ว่าอะไรที่มองเห็นในเทอร์มินัลก็สามารถคัดลอกได้ทั้งหมด
      มันน่าหงุดหงิดเวลาที่แอป GUI กันไม่ให้คัดลอกข้อความที่กำลังแสดงอยู่ จนต้องมานั่งพิมพ์ใหม่ด้วยมือ
    • ไม่จริง Neovim มี native frontend อยู่หลายตัว และตัวมันเองก็ถูกออกแบบมาให้รองรับสถาปัตยกรรมแบบนั้นตั้งแต่แรก
      https://github.com/neovim/neovim/wiki/Related-projects#gui
    • เห็นด้วยเต็มที่
      ชอบ modal editing และชอบ vim มาก แต่ทนกับทางออกกึ่ง ๆ กลาง ๆ แบบที่เทอร์มินัลเอดิเตอร์ให้มาได้ยาก
      ในเมื่อมีแพลตฟอร์มกราฟิกที่สมบูรณ์อยู่แล้ว จะไม่ใช้ทำไม?
    • มันขึ้นอยู่กับเวิร์กโฟลว์อย่างมาก
      อย่างเช่น vim แทบจะใช้เพื่อแก้ไขไฟล์อย่างเดียว แล้วเครื่องมือภายนอกอย่าง git, linter, formatter, debugger, การจัดการ file tree ก็กลับไปทำใน shell
      เพราะงั้นแอปหลักของฉันก็คือเทอร์มินัลอีมูเลเตอร์อยู่แล้ว และในเวิร์กโฟลว์แบบนี้ การไม่มี GUI เฉพาะทางจึงแทบไม่สำคัญเลย
  • ฉันกลับอยากให้ Emacs ของฉันดูแบบนี้มากกว่า: https://imgur.com/a/h0jA1ro
    ไม่ได้พูดจริงจังนะ แค่ล้อเล่น Cool Retro Term ใช้เฉพาะตอนพรีเซนต์เท่านั้น
    ดูแล้ว Emacs ของฉันรองรับสี 24 บิตเป็นค่าเริ่มต้นอยู่แล้ว: https://imgur.com/a/BM5OTxp
    แต่การไฮไลต์ไวยากรณ์ค่อนข้างกวนตา

    • https://muppetlabs.com/~mikeh/crt_emacs.png
      Cool Retro Term ยอดเยี่ยมมาก และฉันก็อยากลองใช้ตอนพรีเซนต์เหมือนกัน
    • ฉันชอบ Cool Retro Term มากจริงๆ แต่ก็น่าเสียดายที่โปรเจ็กต์แทบถูกปล่อยทิ้งแล้ว และมีปัญหาหลายอย่างบน MacOS
      สำหรับฉันแล้ว เทอร์มินัลแนวเรโทรตัวอื่นดูไม่ดีได้เท่านี้
    • ตอนนี้ฉันใช้งาน เอฟเฟกต์ CRT ที่ปรับแต่งเล็กน้อยบน Windows Terminal อยู่จริงๆ
  • การเอามาตรฐานไปขังไว้หลังราคาที่แพงขนาดนั้นเป็นเรื่องน่าอับอายจริงๆ
    ผู้คนต้องอ้อมหลีกกันถึงขั้นนี้เพื่อไม่ต้องซื้อ และสุดท้ายก็อาจเกิดผลลัพธ์แบบนี้ได้
    ถ้าเป็น มาตรฐาน ก็ควรเข้าถึงได้ สมัยที่ยังออกมาเป็นหนังสืออย่างเดียวจะเก็บค่าโรงพิมพ์ก็ยังพอเข้าใจได้ แต่ PDF คุณภาพต่ำราคา 200 ดอลลาร์นี่แทบไม่น่าเชื่อ

  • ฉันเป็นคนเขียน แพตช์สี 24 บิตของ xterm แต่เพิ่งมารู้วันนี้ว่าทำให้ ncurses ทำงานด้วย xterm-direct ได้
    ถึงจะใช้ไลบรารีเทอร์มินัลของตัวเองที่เขียนด้วย Lisp อยู่แล้ว แต่การมีเส้นทางสำรองผ่าน ncurses ก็ยังมีประโยชน์
    ขอบคุณ Mr. Dickey ที่ตอบคำถามบน Stack Overflow และ Chad ที่ยกประเด็นนี้ขึ้นมา