แค่อยากทำให้ Emacs ดูสวยขึ้น – การใช้สี 24 บิตในเทอร์มินัล
(chadaustin.me)- หากต้องการให้ธีมอย่าง 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: ตั้งค่า RGBr,g,bเป็นสีพื้นหน้า
- ตัวเลข
5และ2เชื่อมโยงกับโหมดสีแบบขยายของ ISO 8613-6 หรือ ITU T.4162: สีโดยตรงในปริภูมิ RGB5: สีแบบดัชนี
- ลำดับการทำให้เป็นมาตรฐานมีดังนี้
- ทศวรรษ 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 แบบโคลอน แต่หลายสภาพแวดล้อมยังรองรับเฉพาะ ไวยากรณ์เซมิโคลอน
- รายการ terminfo ประกอบด้วย building blocks
xterm+direct: ไวยากรณ์โคลอนที่ใกล้เคียงมาตรฐานxterm+indirect: สำหรับเทอร์มินัลรุ่นเก่าที่รองรับเฉพาะเซมิโคลอน
- จากการค้นหา
xterm+indirectพบว่าvscode-directดูเหมาะสมที่สุด- เนื่องจากมุ่งเป้าไปที่เทอร์มินัลของ Microsoft จึงถือว่าใกล้เคียงกับ Windows Terminal และ Windows Console เพียงพอ
- ไม่ได้ตรวจสอบทุกความสามารถอย่างละเอียด แต่ใช้งานได้
- เซิร์ฟเวอร์จำนวนมากอาจไม่ได้ติดตั้งรายการ terminfo แบบ
-direct- ในระบบส่วนใหญ่ ฐานข้อมูล terminfo พื้นฐานอยู่ในแพ็กเกจ
ncurses-base - รายการเทอร์มินัลแบบขยายต้องใช้แพ็กเกจ
ncurses-term
- ในระบบส่วนใหญ่ ฐานข้อมูล terminfo พื้นฐานอยู่ในแพ็กเกจ
- ระหว่างเขียน 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 มาตรฐาน จึงต้องเลือกค่าที่ใกล้เคียงพอ
- ภายใน tmux ใช้
การตั้งค่าตามสภาพแวดล้อม
-
เทอร์มินัลอีมูเลเตอร์แบบกราฟิก
- เทอร์มินัลส่วนใหญ่ตั้งค่า
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ไว้
- เมื่อรัน tmux ค่า
-
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 ความคิดเห็น
ความคิดเห็นจาก Hacker News
การไปคุ้ย terminfo ให้ความรู้สึกเหมือนส่องอักษรภาพด้วยคบเพลิงริบหรี่ในสุสานใต้ดินลึก
พอนึกถึงว่ามีความซับซ้อนมากแค่ไหนถูกยัดอยู่ในแอปเทอร์มินัลตัวเดียว มันก็น่าแปลกอยู่เหมือนกัน และยิ่งทำให้รู้สึกขอบคุณนักพัฒนาเทอร์มินัลอย่าง iTerm กับ Kitty มากขึ้น
รวมฟังก์ชันสำหรับตั้งค่าสีแท็บใน iTerm+zsh ไว้ที่นี่: https://gist.github.com/aclarknexient/84ebe33c1879f921685304...
ถ้าเทียบกับสมัยก่อนที่ต่อเข้า HTTP หรือ SMTP ผ่าน telnet ตัวข้อความเองอาจเรียบง่าย แต่ฝั่งที่ใช้แสดงข้อความนั้นเป็นแอปพลิเคชันซับซ้อนที่รองรับความสามารถสารพัด
ตอนนี้เป็นตัวเลือกที่ทำได้เพราะแทบจะมีผู้ใช้เทอร์มินัลนั้นอยู่แค่ตัวผมเอง แต่เทอร์มินัลสมัยใหม่รองรับชุดความสามารถร่วมกันพอสมควร เลยเจ็บปวดน้อยกว่าการที่แอปงงเพราะไม่รู้จักค่า
TERMแปลกๆแน่นอนว่าถ้าคุณไม่ได้ SSH เข้าเครื่องใหม่บ่อยๆ เรื่องนี้ก็สำคัญน้อยลง
มันอาจไม่ใช่เทอร์มินัลอีมูเลเตอร์ที่เร็วที่สุด แต่หน้าตาดีที่สุดแบบทิ้งห่างตัวอื่น
สำหรับแต่ละแอปเทอร์มินัล การปรับ พาเล็ต 16 สี นั้นง่ายกว่าการไปจูนโค้ดฝั่งแอปพลิเคชันที่เกี่ยวกับเทอร์มินัลให้เป๊ะ
ตั้งค่าสี rxvt-unicode ใน
~/.Xdefaultsแล้วในธีม Emacs แบบ.elก็กำหนดชื่อสีต่างกันตามว่าจะเป็นการแสดงผลแบบกราฟิกหรือไม่ จากนั้นค่อยนำไปใช้กับหลาย faceของแถมคือเอาต์พุต
lsที่มีสีก็ดูดีขึ้นด้วย พาเล็ต 16 สีมาตรฐานมักอิ่มสีเกินไปและคอนทราสต์ไม่ดี(if (display-graphic-p)นี่แหละคือหัวใจEmacs รองรับ การแสดงผลแบบกราฟิก จริงๆ และบน X11/Cocoa/Win32 ปุ่ม Esc ก็ทำงานเป็น Esc จริง รวมถึงใช้คีย์ลัด Ctrl+Shift หรือ Cmd, ใช้หลายฟอนต์พร้อมกัน, แสดงภาพ, เปลี่ยนรูปร่างเคอร์เซอร์ ฯลฯ ได้
เหมือนเครื่องย้อนเวลาที่พาคุณไปยังปี 1989 ซึ่งล้ำหน้าไปอีก 20 ปี
เส้นสีแดงมีได้แค่แดงแรงสุดหรือไม่ติดไปเลย และถ้าเพิ่มเส้น intensity เข้ามาก็จะกลายเป็นแดง 100%
DIRCOLORSlsก็รองรับ สี 24 บิต ได้จริงสีตั้งต้นมืดเกินไปเมื่อเทียบกับพื้นหลังสีเข้ม เลยเพิ่ม ความสว่างเชิงรับรู้ ของทุกสีขึ้น
ถ้าผู้เขียนรู้จัก
export COLORTERM=truecolorก็น่าจะลำบากน้อยกว่านี้มากมันมีอยู่ทั้งในเชิงอรรถเรื่องการตรวจจับ truecolor ของเอกสาร Emacs ที่ลิงก์ไว้ และยังเห็นในภาพหน้าจอ Konsole ด้วย แต่มีโอกาสสูงว่าค่านี้หายไประหว่างทางในเทอร์มินัลมัลติเพล็กเซอร์ที่ซ้อนหลายชั้น
การตั้งค่านี้ทำให้แอปรู้ได้ทันทีว่าต้องการ ทรูคัลเลอร์ จึงข้ามส่วนที่ยากไปได้ และไม่ต้องใช้ฐานข้อมูล terminfo ด้วย
RGBของ terminfo เข้าไปด้วยเพียงแต่ไม่ใช่ทุกโปรแกรมที่จะเคารพ COLORTERM ดังนั้นผมเคยตั้งใน
.bashrcให้ unsetCOLORTERMเมื่อเป็นlinux | screen*และในกรณีอื่นก็ exportCOLORTERM=truecolorเดี๋ยวนี้ Screen รองรับสี 24 บิตแล้ว ดังนั้นนี่น่าจะเป็นการตั้งค่าสมัย Ubuntu 18
trampหรือsshfsก็ได้อีกด้านหนึ่งก็เป็นเพราะผู้ดูแล ncurses ค่อนข้างอนุรักษนิยม ขณะที่นักพัฒนาเทอร์มินัลรุ่นใหม่อยากขยับให้เร็ว
Emacs ที่เก่ากว่านั้นยังคงต้องใช้ฐานข้อมูล terminfo อยู่
ส่วนใหญ่ไม่จำเป็นต้องกำหนดมัน แต่ถ้าตั้ง
COLORTERM=truecolorไว้ในเซสชัน screen จู่ๆ หน้าจอก็จะแสดงผลเพี้ยนมาก และพอลบตัวแปรสภาพแวดล้อมนี้ออกก็กลับมาปกติเวลาโต้ตอบกับ Emacs ก็ไม่ได้จำเป็นต้องใช้เทอร์มินัลเสมอไป
สามารถใช้ กราฟิกฟรอนต์เอนด์ สำหรับ macOS, Windows, X.org และ Wayland ได้
Emacs แบบกราฟิกถ้าปิด toolbar ไว้ จะหน้าตาคล้ายกับ Emacs ที่รันในเทอร์มินัลมาก จนคนที่ไม่รู้จัก Emacs อาจเข้าใจผิดได้ง่ายว่าหน้าต่างกราฟิก Emacs บนเครื่องเพื่อนร่วมงานเป็นหน้าต่างเทอร์มินัล
ในแบบสำรวจผู้ใช้ Emacs มีคนตอบว่า 80% ใช้กราฟิกฟรอนต์เอนด์
xterm-mouse-modeก็ให้ข้อดีได้ถึง 80% แล้วใส่
mouse,xterm-mouse-mode,mouse-wheel-mode, การตั้งค่าการเลื่อนหน้าจอ ฯลฯ ก็ใช้งานได้ดีพอสมควร และauto-save-defaultก็ปล่อยเป็นnilตามพระประสงค์ของพระเจ้าโปรแกรมเทอร์มินัลทั้งหมดรันในบัฟเฟอร์ shell-mode ของกราฟิก Emacs และจะใช้ term-mode เฉพาะกับโปรแกรมหายากที่ต้องควบคุมแบบเต็มหน้าจอ
แม้จะไม่ใช่ตัวที่ฟีเจอร์เยอะที่สุดหรือเร็วที่สุด แต่สามารถย้ายไปมาเหมือนบัฟเฟอร์อื่น ๆ และทำงานร่วมกับเนื้อหาที่กำลังแก้ไขได้อย่างลื่นไหล
ถ้าเปิดกราฟิก Emacs บนเครื่องระยะไกลไม่ได้ ก็ใช้ tramp แก้ไขไฟล์ระยะไกล หรือเปิด headless Emacs server แล้วเชื่อมต่อด้วยกราฟิก emacsclient
ไม่เคยคิดมาก่อนว่าคนอื่นอาจคิดว่าฉันรัน Emacs อยู่ในเทอร์มินัล
กราฟิก Emacs ดีกว่ามาก แต่การที่ในเทอร์มินัลยังทำงานและดูเหมือนได้ราว 90% แบบเดียวกันก็ยังยอดเยี่ยมอยู่ดี
ความรู้สึกเบาพอ ๆ กับเทอร์มินัล และไม่ได้ให้ความรู้สึกแบบ VNC
มีข้อดีอย่างฟอนต์, การใช้หลายฟอนต์พร้อมกัน, เมนู, เมาส์, สี, หลายเฟรม/หน้าต่าง
ถ้ารันกราฟิกไว้ที่เครื่องโลคัลแล้วเข้าถึงระบบระยะไกลด้วย tramp ก็แทบจะสามารถแก้ไขไฟล์ตั้งค่าบนเราเตอร์ Linux ระยะไกลที่มีแค่ busybox ได้ พร้อมสิ่งอำนวยความสะดวกครบครัน
ใช้ 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 กันไม่ให้คัดลอกข้อความที่กำลังแสดงอยู่ จนต้องมานั่งพิมพ์ใหม่ด้วยมือ
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
แต่การไฮไลต์ไวยากรณ์ค่อนข้างกวนตา
Cool Retro Term ยอดเยี่ยมมาก และฉันก็อยากลองใช้ตอนพรีเซนต์เหมือนกัน
สำหรับฉันแล้ว เทอร์มินัลแนวเรโทรตัวอื่นดูไม่ดีได้เท่านี้
การเอามาตรฐานไปขังไว้หลังราคาที่แพงขนาดนั้นเป็นเรื่องน่าอับอายจริงๆ
ผู้คนต้องอ้อมหลีกกันถึงขั้นนี้เพื่อไม่ต้องซื้อ และสุดท้ายก็อาจเกิดผลลัพธ์แบบนี้ได้
ถ้าเป็น มาตรฐาน ก็ควรเข้าถึงได้ สมัยที่ยังออกมาเป็นหนังสืออย่างเดียวจะเก็บค่าโรงพิมพ์ก็ยังพอเข้าใจได้ แต่ PDF คุณภาพต่ำราคา 200 ดอลลาร์นี่แทบไม่น่าเชื่อ
ฉันเป็นคนเขียน แพตช์สี 24 บิตของ xterm แต่เพิ่งมารู้วันนี้ว่าทำให้ ncurses ทำงานด้วย
xterm-directได้ถึงจะใช้ไลบรารีเทอร์มินัลของตัวเองที่เขียนด้วย Lisp อยู่แล้ว แต่การมีเส้นทางสำรองผ่าน ncurses ก็ยังมีประโยชน์
ขอบคุณ Mr. Dickey ที่ตอบคำถามบน Stack Overflow และ Chad ที่ยกประเด็นนี้ขึ้นมา