Emacs diary EP2: สภาพแวดล้อม

Emacs diary EP2: สภาพแวดล้อม

ผมไม่รู้ว่าจะมีใครมาใช้ emacs แบบ เป็น text-editor ตัวแรกเลยมั้ย ผมไม่ใช่คนนึงแน่ๆ ซึ่งพอเราเปลี่ยนเครื่องมือ มันจะอารมณ์เดียวกับเราเปลี่ยนภาษา Programming ที่เราเขียนทุกวันเลย เพราะสิ่งแรกๆ ที่เราพยายามทำคือ "เราพยายามจะทำสิ่งเดียวกับที่เราเคยทำได้จากภาษาเก่า ในภาษาใหม่" ลองเปลี่ยนคำว่า ภาษา เป็น text-editor ดูครับ แล้วลองตอบตัวเองดูว่าเราอยากทำอะไรได้บ้าง

คำตอบของคำถามข้างบนมันน่าจะเยอะมาก หรืออาจจะขอแค่มี syntax highlight ผมเชื่อว่าแต่ละคนมีคำตอบของตัวเอง ซึ่งผมก็มีคำตอบของผมด้วย และคิดว่าเป็นหัวข้อที่ดีที่จะเอามาเขียน EP2 ที่ค้างคาไว้มานาน หลังจากเกริ่นมานาน วันนี้ขอเสนอตอน "สภาพแวดล้อม" ครับ

💬 ในบล็อกนี้ผมอาจจะมี Reference ถึง key Vim เยอะมาก ไม่ใช่เพราะมันไม่ดี แต่เพื่อต้องการให้เห็นภาพว่า Design philosophy มันต่างกัน และส่วนตัวผมยังชอบ Vim อยู่นะ :wq!

เปิดประตูและปิดประตู

มันจะมี Joke ที่คนใช้ Vim โดนล้อกันบ่อยๆ คือปิด Vim กันไม่เป็น ซึ่งส่วนตัวผมมองว่า Emacs ก็ไม่ต่างกัน ถึงมันจะมี Menu bar ให้ข้างบนก็เถอะ

ถ้าต้องการเปิดไฟล์ใน emacs เราจะเปิดจาก terminal เป็น emacs ก็ได้ แต่ถ้าเผลอเข้ามาใน emacs แล้วจะใช้ C-x C-f ครับ

💬 วิธีกดปุ่มอย่างที่เห็นข้างบนตัว ctrl หรือที่ชอบเขียนใน Document เป็น C- ก็คือกด ctrl แช่ไว้แล้วตามด้วยตัวอักษรครับ แต่ถ้าเป็น combo แบบข้างบนกด ctrl ค้างไว้เลยแล้วกด x f ก็ได้ครับ

ทีนี้ก็มาถึง Highlight เรา เราจะปิด emacs ยังไงดี การปิด emacs จะใช้คีย์ C-x C-c ครับ ซึ่งถ้าเราไม่ได้แก้ไขอะไรใน buffer ที่เราเปิดมันก็จะปิดไปเลย แต่ถ้ามีมันก็จะถามว่าจะ Save มั้ย จะปิดจริงๆ ใช่มั้ยนะ

เดินและกระโดด

สิ่งแรกที่ผมโฟกัสเลยคือการเดิน ซึ่งเอาจริงๆ เราสามารถเลือกที่จะไม่รู้อันนี้ก็ได้ แล้วใช้แค่ Arrow key ที่มีติดมากับคีย์บอร์ดส่วนใหญ่ก็ได้ แต่เหตุผลแรกคีย์บอร์ดผมไม่ใช่คีย์บอร์ดเหมือนคนส่วนใหญ่และสองคือ พอเราเคยใช้ Vim มา เราจะรู้ได้ถึงประสิทธิภาพในการเดินที่ไม่ต้องขยับมือออกจาก Homerow อยู่แล้ว ซึ่งสองเหตุผลนี้คือเหตุผลที่ผมเลือกที่จะเรียนรู้การเดินแบบ emacs ครับ

วิธีการเดินใน emacs จะใช้ Modifier key → Ctrl แล้วตามด้วยคีย์ที่เอาไว้ใช้เดิน ซึ่งประกอบด้วย

  • C-f → Forward คือเลื่อน cursor ไปข้างหน้า
  • C-b → Backward คือเลื่อน cursor ไปข้างหลัง
  • C-p → Previous คือเลื่อน cursor ขึ้นบน
  • C-n → Next คือเลื่อน cursor ลงล่าง

ซึ่งสำหรับคนที่เปลี่ยน Keyboard layout อย่างผมมันจำง่ายกว่าคีย์ Vim ที่ intention เอาไว้มือขวา แต่ emacs เลือกที่จะแมพตามคำที่ระบุ Behavior มัน ซึ่งแปปเดียวก็จำได้เลย

ในส่วนของการกระโดดนั้น ถ้าเป็นการกระโดดข้ามคำ การเดินหน้ากับถอยหลังจะใช้คีย์เดียวกันเลยคือ f, b แต่เปลี่ยน Modifier คีย์เป็น M หรือ Meta key หรือ Alt หรือ Option key (1) แต่ถ้าเป็นการกระโดดไปที่ตัวสุดท้ายของบรรทัดหรือถอยไปต้นบรรทัดจะใช้ a, e แทน ซึ่งสรุปได้ตามนี้ครับ

  • M-f → Forward Word
  • M-b → Backward Word
  • C-a → Beginning of Line
  • C-e → End of Line

ส่วนการกระโดดขึ้นลงนั้น จะเริ่มจำยากกว่าที่ไล่มาข้างบนคือ movement by balanced expression. ซึ่งจะใช้ { } ในการกระโดดระหว่าง Block ของ expression หรือ Paragraph ถ้าพูดแบบบ้านๆ แต่เราก็สามารถกระโดดขึ้นไปบรรทัดแรกหรือบรรทัดสุดท้ายของไฟล์ได้ด้วยตามนี้ครับ

  • M-{ → Move to Beginning of Paragraph
  • M-} → Move to End of Paragraph
  • M-< → Move to Beginning of Buffer
  • M-> → Move to End of Buffer

อันที่จริง ยังมีอีกหลายคีย์ที่ช่วยให้เราเดินและกระโดดได้อีกในหลายรูปแบบ แต่ข้างบนเป็นรูปแบบที่ผมใช้บ่อยจนติดเป็น Muscle Memory ไปละ

💬 แรงบันดาลใจหนึ่งที่ผมมาใช้ emacs เพราะตอนผมไปเรียน HtDP รุ่นพี่ผมเค้าบอกว่าเนี่ยคีย์ที่กดใน Racket เนี่ยมันคีย์เดียวกับ emacs เลย แล้วมันกดได้ในหลายโปรแกรมเลยนะ พอผมไปลองเท่านั้นแหละ จริง! แทบจะทุกโปรแกรมครับ

Buffer

ก่อนจะไปถึง Window ที่ผมเชื่อว่าหลายๆ คนชินมากับ Editor อื่นๆ เหมือนผม ผมอยากจะให้ทุกคนลองรู้จักกับระบบ Buffer ใน emacs ก่อน เพราะส่วนตัวผมชอบ emacs มากระดับที่เรียกได้ว่า Paradigm shift กันเลยทีเดียว

เวลาเราเปิดไฟล์ขึ้นมาใน emacs ตัวไฟล์จะไม่โดนแก้ไขตรงๆ แต่แรกครับ แต่มันจะถูกโหลดมาเก็บไว้ใน buffer ของ emacs ซึ่งใน emacs มี buffer หลายแบบมากทั้ง

*file* - ตัวนี้เราน่าจะยุ่งบ่อยสุดละ มันคือ buffer ที่เกิดจากเวลาเราเปิดไฟล์ขึ้นมาใน emacs ครับ ซึ่งปกติมันก็จะตั้งชื่อให้เป็นชื่อไฟล์ที่เราเปิดโดยอัตโนมัติ

*scratch* - ตัวนี้เป็นเหมือนกระดาษทด เอาไว้ให้เราจดอะไรก็ได้

*message* - ตัวนี้เป็นพวกแจ้งเตือนที่ emacs เตือนเรา อย่างเช่นตอนเราจะปิด emacs ตอนยังไม่เซฟไฟล์

*help* - ตัวนี้ตามตัวครับเป็นคู่มือให้เราใช้ emacs

ทีนี้เวลาเราทำงานกับ buffer สำหรับผมคิดว่ามี 2 อย่างที่ควรรู้เอาไว้คือ การสลับ buffer เวลาเราเปิดหลายๆ ไฟล์ และการลบ buffer ที่ไม่ใช้แล้วออกไปครับ

Screen Shot 2564-12-04 at 09.30.33.png

การสลับ buffer เราสามารถกด C-x b ได้ครับ จะเป็นการเปิดเมนูให้เราสลับ buffer ได้โดยพิมพ์ชื่อเอาก็ได้ หรือจะเลื่อนขึ้นลงก็ได้ครับ (ในภาพเป็นตัวที่ Modify ใน Doom แล้วแต่ตัวมาตรฐานก็กด tab เพื่อดู list ของ buffer ทั้งหมดได้ครับ

อีกอย่างคือ พอเราเปิดไฟล์มาเยอะๆ ตัว buffer เราก็จะเริ่มล้นหรือทำให้หาไฟล์ที่ต้องการยากขึ้น ไม่ต่างจากเวลาเราเปิด chrome tab ไว้เยอะๆ เลย ซึ่งวิธีการลบ buffer คือกด C-x k ครับ ซึ่งจะเหมือนกับตอนเราปิด emacs คือถ้าเรายังไม่เซฟไฟล์มันจะถามก่อนว่าจะเซฟก่อนมั้ย

Buffer ยังทำอะไรได้อีกเยอะมากครับ ทั้งเปิด email, feed, calendar หรือแม้กระทั่งเป็น terminal emulator แต่เอาไว้ตอนต่อๆ ไปผมค่อยไปเล่าถึงตรงนั้น แล้วก็ท้ายสุด ใน Vim ก็มี buffer นะ แต่ผมไม่เคยใช้เลย ฮาาา

Window

ถ้าเป็นใน text-editor ตัวอื่นๆ แทบจะทั้งหมดหรืออย่างน้อยก็ที่ผมรู้จัก เค้าจะเรียกสิ่งนี้ว่า Pane ครับ ซึ่งสามารถ Split ได้ทั้ง Horizontal, Vertical เลยโดยคีย์หลักๆ ที่ผมใช้จะมี

C-x 2 - อันนี้ไว้ Split Horizontal หรือแบ่งบนล่างครับ

C-x 3 - อันนี้ไว้ Split Vertical หรือแบ่งซ้ายขวาครับ

C-x o - อันนี้เป็นตัวอักษร O (Omongo) นะครับ เอาไว้สลับระหว่าง Window

C-x 0 - อันนี้เป็นเลข 0 นะครับ เอาไว้ลบ window ที่กำลังโฟกัสอยู่ (Close this window)

C-x 1 - อันนี้เอาไว้ปิดที่เหลือทั้งหมด (Close other window)

ซึ่งหลังจากใช้ได้ซักพักผมรู้สึกว่ามันคุ้นๆ นะ จนผมค้นพบว่าคีย์มันคล้าย tmux มากๆ เลยครับ อาจจะคล้ายแค่ C-x o พวก Split อะไรอาจจะไม่ตรง แต่มันทำให้ผมเข้าใจ concept switch window ได้เร็วมากๆ นอกจากนั้น ถ้าเราเปิด 3 Window ขึ้นไป ใน Doom emacs มันจะมีฟีเจอร์ highlight window ต่างๆ เป็นตัวอักษรครับ ถ้าอยากไปหน้าไหน ก็กดตัวอักษรที่มัน highlight แดงๆ เลยไม่ต้องกด C-x o ย้ำๆ หลายๆ ครั้งครับ

Screen Shot 2564-12-04 at 09.41.06.png

Frame

Frame ถ้าแปลตรงตัวคือกรอบใช่มั้ยครับ ใน emacs มันหมายถึงหน้าต่างทั้งหน้าเลย (ไม่ใช่หน้าต่าง Window ที่ผมพูดถึงข้างบนนะ) ซึ่งผมว่าสิ่งที่อธิบายได้ดีที่สุดคือมันเหมือน tmux window ที่เรากด C-b c มากๆ ครับ

ตัว Frame มีประโยชน์มากๆ เอาไว้ให้เราแยก Workspace ได้จะในกรณีที่เราเปิด Window เยอะๆ แล้ว ก็อยากเปิดอันอื่นด้วย แต่หน้าไม่พอ ส่วนตัวผมไม่ค่อยได้ใช้ฟีเจอร์นี้เท่าไร แทบจะนับครั้งได้ เลยไม่รู้จะเล่าอะไรเท่าไร

Tab

พอผ่านมาทั้ง Buffer, Windows, Frame หลายคนน่าจะสงสัยว่า อ่าวแล้ว Tab ละในพวก text-editor อื่นๆ ก็มีนิ ใช่ครับ emacs ก็มีแต่ผมไม่เคยใช้ครับ ผมใช้แค่ข้างบนก็พอละ

แต่ถ้ามามองอีกมุมนึงผมว่า concept ของ buffer มันทดแทน tab ได้เลยนะ เพราะถ้าอยากไปดูไฟล์ไหนก็เปิด buffer ขึ้นมาดูเอา อีกเหตุผลนึงคือผมว่ามันโฟกัสกว่าด้วย ไม่ต้องเห็น tab ให้รกหูรกตา

Emacs Pinky

ถ้าใครเพิ่งมาลอง emacs ใหม่ๆ แล้วมาถึงจุดนี้ ขอแสดงความยินดีด้วยครับ คุณได้สัมผัสกับสิ่งที่ชาว emacs โดนล้อมาหลายปีนั่นก็คือ Emacs Pinky ครับ ถ้าสังเกตุ เราใช้นิ้วก้อยกด Ctrl (C) กันซ้ำๆ เยอะมากและถ้าใช้บ่อยๆ หนักๆ มันก็เกิดอาการบาดเจ็บได้ ซึ่งเอาจริงๆ มันก็ไม่ค่อยดีกับสุขภาพนิ้วเท่าไร วิธีการบรรเทาขั้นแรก แต่ก็ยังเจ็บนิ้วก้อยอยู่ คือย้าย ctrl มาไว้ที่ปุ่ม Caplock เอาครับ อารมณ์เดียวกับชาว Vim ที่ย้าย ESC มาอยู่ที่ Caplock เหมือนกัน

ถ้าใครย้ายแล้วยังรู้สึกปวดนิ้วก้อยอยู่ ผมก็แนะนำคีย์บอร์ดที่ช่วยเพิ่มการใช้งานนิ้วโป้ง อย่างมีนัยยะสำคัญอย่าง Ergodox EZ หรือ Kinesis Advantage2 ก็ได้ครับ จะช่วยให้เราย้ายปุ่มพวก Modifier key ให้มาอยู่ที่นิ้วโป้งเราได้ ช่วยลดภาระของนิ้วก้อยไปได้มากๆ

แต่ส่วนตัวผมถึงจะใช้ Ergodox EZ แต่ผมก็ยังแมพไว้ที่นิ้วก้อยอยู่ครับ เพราะ Thumb cluster ผมมันแมพปุ่มอื่นจนเต็มแล้ว T_T

Screen Shot 2564-12-04 at 08.21.46.png

ก็ประมาณนี้ครับตอนสอง ผมว่าวิธีการที่ emacs เค้าออกแบบสภาพแวดล้อมขึ้นมานี่น่าสนใจมากเป็นอีก Philosophy ที่ก็มีจุดแข็งในตัวมันเองครับ ถ้าใครชอบซีรีย์นี้ก็กดติดตามได้ใน Hashnode ครับ พอถึงเวลาที่ผมออกตอนใหม่เดี๋ยวมันก็แจ้งเตือนเอง แล้วเจอกันใหม่ตอนหน้าครับ

Reference

Footnote

(1) อันนี้แล้วแต่ emacs variations ที่ลงในเครื่องเลยครับส่วนตัวผมใช้ Homebrew-emacsmacport ทำให้มันแมพกับ Option แทนที่จะแมพกับ Cmd เหมือนกับบาง Variations