วิธีใช้ Windows Terminal ของฉัน – ระบบอัตโนมัติบนเทอร์มินัลขั้นสุดด้วย tmux และเวิร์กโฟลว์แบบคัสตอม
(jyn.dev)- ผสาน tmux, SSH, nvim และสคริปต์ค้นหา/อัตโนมัติอันทรงพลัง เพื่อสร้างเวิร์กโฟลว์เฉพาะตัวสำหรับสำรวจ แก้ไข และค้นหาไฟล์บนรีโมตเซิร์ฟเวอร์ได้ทันทีโดยไม่ต้องใช้ GUI
- กดคีย์ลัดเพียงครั้งเดียวก็ค้นหาชื่อไฟล์อัตโนมัติจากหลายหน้าต่างของ tmux และเปิดได้ทันที รวมถึงสลับไฟล์และจัดการบัฟเฟอร์ได้ทั้งหมดด้วยคีย์ลัด
- รู้สึกไม่พอใจกับ ความช้าของ VSCode และปัญหาคีย์ไบน์ชนกัน จึงรวมทุกการทำงานเข้าด้วยกันผ่านสคริปต์ที่เขียนเอง
- ผสาน เครื่องมือสายยูนิกซ์อย่าง regex, perl, tmux, nvim เพื่อให้ตรวจจับและเปิดพาธไฟล์/ข้อมูลบรรทัดได้อัตโนมัติ
- แม้ว่า กระบวนการลงมือทำเองจะซับซ้อนมาก แต่ก็แสดงให้เห็นว่าสามารถดึงพลังและความยืดหยุ่นของเทอร์มินัลออกมาได้สูงสุด
วิธีใช้เทอร์มินัลในแบบของฉัน
- บทความนี้แบ่งปันประสบการณ์การสร้างสภาพแวดล้อมพัฒนาที่มีประสิทธิภาพด้วยการผสานเทอร์มินัลเข้ากับเครื่องมือต่าง ๆ
- เนื่องจากเป็นกระบวนการที่ซับซ้อนซึ่งปกติต้องอาศัยวิดีโอ จึงแนบวิดีโอการใช้งานจริงควบคู่กับข้อความไว้ด้วย (ควรดูวิดีโอประกอบ)
- บางช่วงในวิดีโอ (0:11, 0:21, 0:41) เป็นจุดที่หลายคนถึงกับตกใจว่า “ทำแบบนี้ได้ด้วยเหรอ?”
สรุปขั้นตอนเวิร์กโฟลว์เทอร์มินัลในวิดีโอแบบเป็นลำดับ
- 0:00 : เปิด Windows Terminal บนแล็ปท็อป
- 0:02 : ใช้คีย์ลัด ctrl + shift + 5 เพื่อเปิดแท็บเทอร์มินัลใหม่ จากนั้นเชื่อมต่อเดสก์ท็อปที่บ้านด้วย
sshแล้ว รัน tmux ทันที - 0:03 : รันเชลล์เริ่มต้น zsh ภายใน tmux แสดงพรอมป์ต์และโหลดการตั้งค่าทั้งหมดแบบอะซิงก์
- 0:08 : ใช้
zoxideค้นหาไดเรกทอรีล่าสุดแบบ fuzzy แล้วเข้าไปยังไดเรกทอรีนั้น - 0:09 : เริ่มพิมพ์คำสั่ง ripgrep แล้ว zsh เติมคำสั่งอัตโนมัติตามประวัติการใช้งานก่อนหน้า และ กด ctrl + f เพื่อยอมรับ
- 0:11 : ใช้คีย์ลัด
ctrl + kfเพื่อค้นหาชื่อไฟล์จาก scrollback ทั้งหมดของ tmux โดยชื่อไฟล์จะถูกไฮไลต์เป็นสีน้ำเงิน - 0:12 : กดปุ่ม
nต่อเนื่องเพื่อไล่ดูไฟล์ที่ค้นพบจนเจอไฟล์ที่ต้องการ - 0:21 : กดปุ่ม
oเพื่อเปิดไฟล์ที่เลือกในแอปเริ่มต้น (nvim) โดย tmux จะรันในหน้าต่างใหม่ (และยังทำงานอยู่บนรีโมตเซิร์ฟเวอร์) - 0:26 : พยายามย้ายไปยังรีเฟอเรนซ์หลายจุดในโค้ดด้วย rust-analyzer โดยบางแมโครยังตรวจจับไม่ได้ แต่ที่ 0:32 ก็ย้ายได้สำเร็จตามปกติ
- 0:38 : ใช้
ctrl + khเพื่อย้ายโฟกัสของ tmux ไปยังหน้าต่างด้านซ้าย - 0:39 : กดปุ่ม
nอีกครั้งเพื่อไล่ดูผลการค้นหาไฟล์ก่อนหน้าต่อในสถานะcopy-mode - 0:41 : กดปุ่ม
oอีกครั้ง คราวนี้เปิดอีกไฟล์หนึ่งใน nvim อินสแตนซ์เดิม - 0:43 : กดปุ่ม
bเพื่อตรวจสอบรายการบัฟเฟอร์ของไฟล์ที่เปิดอยู่ แล้วสลับไปมาระหว่างสองไฟล์เพื่อจบงาน
ทำไมถึงหันมาใช้เวิร์กโฟลว์เทอร์มินัลแบบนี้?
- VSCode ช้า โดยเฉพาะเมื่อใช้ปลั๊กอิน vim จะหน่วงมาก
- มักเกิด คีย์ไบน์ชนกัน ระหว่างเอดิเตอร์ ปลั๊กอิน vim เทอร์มินัล และฟังก์ชันจัดการหน้าต่าง จนใช้งานไม่สะดวก
- เคยลองใช้ Zed editor ด้วย แต่ตอนนั้นยังไม่สมบูรณ์ และ ปัญหาคีย์ไบน์ชนกันก็ยังคงอยู่
- จึงเริ่ม ใช้ nvim (Neovim) โดยตรงในเทอร์มินัล แต่
- กระบวนการ คัดลอกชื่อไฟล์จากผลค้นหาของ ripgrep ไปวางในเอดิเตอร์ทีละไฟล์ นั้นยุ่งยากเกินไป
- โดยเฉพาะเมื่อผลลัพธ์ของ ripgrep มีทั้งชื่อไฟล์และเลขบรรทัดมาด้วย
- ทุกครั้งที่วางจะเกิดข้อผิดพลาดทางไวยากรณ์
- และมักต้องเสียเวลาแก้ไขโดยไม่จำเป็นก่อนจะเปิดไฟล์จริง
- จึงรู้สึกว่าต้องมี เวิร์กโฟลว์ที่เปิดพาธไฟล์ได้ทันที แบบเดียวกับ ctrl-click ของ VSCode
- สุดท้ายจึง ใช้ tmux ลงมือทำฟังก์ชันที่ต้องการขึ้นมาเอง
- ถ้ามีคนถามว่าทำไมถึงใช้ tmux ก็จะตอบทันทีว่า เพราะระบบอัตโนมัติแบบนี้และการคงสถานะเซสชัน
- เทอร์มินัลทรงพลังกว่าที่หลายคนคิดมาก แต่ด้วยฟังก์ชันพื้นฐานเพียงอย่างเดียว พลังของมันยังไม่ถูกแสดงออกมา
- แม้ tmux จะเก่า ไวยากรณ์ซับซ้อน และมีบั๊กอยู่บ้าง แต่ก็เลือกใช้เพราะ ความสามารถในการขยายและการปรับแต่ง
วิธีการหลักที่ใช้ทำ
ค้นหาชื่อไฟล์จาก scrollback ทั้งหมดใน tmux
- ใช้ การจับคู่แพตเทิร์นชื่อไฟล์ด้วย regular expression ที่ซับซ้อนใน tmux copy-mode
- ใช้สคริปต์ regex ที่ทำขึ้นเอง (
search-regex.sh) เพื่อไฮไลต์ทั้งพาธไฟล์ บรรทัด และคอลัมน์ - ตัวอย่างการตั้งค่า tmux:
bind-key f copy-mode \; send-keys -X search-backward '정규표현식'
เปิดไฟล์ที่เลือกในหน้าต่างใหม่/หน้าต่างปัจจุบัน
- ปรับแต่ง คีย์ลัดของ tmux ให้เปิดไฟล์ที่เลือกด้วยแอปเริ่มต้นหรือเอดิเตอร์ (เช่น nvim)
- รองรับพาธแบบ relative และการขยาย
~bind-key -T copy-mode-vi o send-keys -X copy-pipe 'cd #{pane_current_path}; ...' bind-key -T copy-mode-vi O send-keys -X copy-pipe-and-cancel 'tmux send-keys ...'
เปิดไฟล์ใน nvim อินสแตนซ์ที่เปิดอยู่แล้ว
- ใช้ สคริปต์ perl ให้ tmux ค้นหา nvim pane ที่ต้องการ แล้วส่งคีย์อินพุตพร้อมข้อมูลไฟล์/บรรทัดเข้าไปยัง pane นั้นโดยตรง
- แปลงรูปแบบ
file:line:columnให้เป็นคำสั่ง vim เพื่อเปิดไฟล์โดยอัตโนมัติ
ข้อดีและข้อจำกัดของแนวทางนี้
- ก้าวข้ามข้อจำกัดของความสามารถในเทอร์มินัลฝั่งโลคัล: ใช้ tmux เพื่อสำรวจ/แก้ไข/ค้นหาไฟล์บนรีโมตเซิร์ฟเวอร์ได้อย่างอิสระ
- ถึงเอดิเตอร์จะไม่รองรับโปรโตคอลแก้ไขระยะไกล ก็ยังใช้เวิร์กโฟลว์เดียวกันได้
- รวมทุกอย่างตั้งแต่คีย์ไบน์ การค้นหา การสลับไฟล์ การจัดการบัฟเฟอร์ ฯลฯ ให้เข้ากับสไตล์ของตัวเองได้อย่างสมบูรณ์
- ทำระบบอัตโนมัติได้เร็วและง่ายกว่าการสร้างปลั๊กอิน VSCode
- แต่สคริปต์ที่ทำขึ้นเอง เปราะบางและดูแลรักษายาก จึงแนะนำต่อคนอื่นได้ลำบาก
โซลูชันทางเลือก
- ชุดโอเพนซอร์ส/เครื่องมือที่โดยรวมแล้วแนะนำเป็นทางเลือก:
fish + zoxide + fzf: ใช้แทนเวิร์กโฟลว์การค้นหาไดเรกทอรีแบบ fuzzy การค้นหาคำสั่ง และบางส่วนของการค้นหาไฟล์ได้- ฟังก์ชันในตัวของเอดิเตอร์ (แท็บ หน้าต่าง fuzzy finder เป็นต้น) ก็เพียงพอสำหรับผู้ใช้ส่วนใหญ่
qf: สามารถเลือกไฟล์จากเอาต์พุตของเทอร์มินัลได้ แต่เชื่อมต่อกับเครื่องมือแบบโต้ตอบไม่ได้ และใช้ CLI สไตล์ vie: ยูทิลิตีขนาดเล็กที่รู้จักพาธแบบ file:line (ต้องมีสคริปต์แยกตามชนิดของเอดิเตอร์)vim --remote,code filename,emacsclientฯลฯ ก็ให้ผลคล้ายกัน แต่ยังรู้จักรูปแบบ file:line ได้ไม่สมบูรณ์
บทสรุปและสิ่งที่ได้เรียนรู้
- เทอร์มินัลทรงพลังกว่าที่คิดมาก และเมื่อผสานเข้ากับสคริปต์ที่เขียนเอง ก็ทำระบบอัตโนมัติที่เครื่องมือ GUI ทำไม่ได้ได้
- แต่ก็ยังมีข้อจำกัดเชิงปฏิบัติ เช่น การบำรุงรักษาและบั๊กที่แฝงอยู่ในสคริปต์
- หากสนใจระบบอัตโนมัติของเวิร์กโฟลว์บนเทอร์มินัล วิธีที่เป็นจริงที่สุดคือ ค่อย ๆ สร้างสภาพแวดล้อม tmux/nvim/fzf แบบคัสตอมขึ้นทีละขั้น
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ฉันก็ใช้ทริกคล้าย ๆ กันอยู่ ใช้ tmux scrollback แล้ว pipe เอา output ที่ tokenize แล้วเข้า zsh เพื่อใช้ autocomplete ได้กับทุกอย่างที่มองเห็นอยู่บนหน้าจอ tmux โพสต์ใน Threads ที่เกี่ยวข้อง และ โค้ด gist มีประโยชน์มากจริง ๆ
ชอบ workflow แบบนี้มาก เลยค่อย ๆ ทำของคล้ายกันและขัดเกลามาหลายปีแล้ว พอเวลาผ่านไปก็พยายามลดชั้น custom ลงให้มากที่สุด เพราะยิ่งมี overlay มาก ต้นทุนการดูแลรักษายิ่งสูง จริง ๆ แล้วใน Vim แบบเดิม ๆ (โดยไม่ต้องมี tmux เพิ่ม) ก็ทำสิ่งที่บทความนี้พูดถึงได้เกือบทั้งหมด เช่น
rg --vimgrep restore_tool | vim -c cb -(vim -c cb -เป็นฟีเจอร์โปรดที่สุดอย่างหนึ่งใน Vim และแปลกใจที่แทบไม่มีใครใช้กัน) แน่นอนว่าการรัน rg ซ้ำทุกครั้งอาจหนักไปหน่อย ดังนั้นฉันมักจะวิเคราะห์ผลลัพธ์ในเทอร์มินัลก่อน แล้วถ้าจำเป็นค่อยใช้คำสั่ง custom ของ tmux เพื่อคัดลอก output ของคำสั่งล่าสุดแล้วส่งเข้า vim บางทีก็ใช้ ทริกใช้ตัวอักษร Unicode ใน prompt หรือส่งผ่านด้วยtmux saveb - | vim -c cb -vim -c cb -เป็นฟีเจอร์โปรดใน Vim อยากรู้ว่ามันทำอะไร ลองls | vim -กับls | vim -c cb -แล้วก็ยังไม่เห็นความต่างแบบชัด ๆ)vim -q <(ripgrep --vimgrep restore_tool)หรือเปล่าเซ็ตอัปนี้ดูดีเพราะมีทั้ง tmux, fzf, rg, zoxide และ nvim ที่สะอาดเรียบร้อย ถ้ายังไม่มี อยากแนะนำ atuin, starship, bat, glow, duf, dogdns, viddy, gum/sesh, dust, btop ด้วย หาได้ทั้งหมดจากลิสต์ Awesome Terminal XYZ บน GitHub atuin นี่แทบจะเป็นของจำเป็น ส่วนถ้าไม่มี zoxide ก็เหมือนเป็นนักกีฬาแต่ใส่รองเท้าไม่พอดี เวลาจะอัดวิดีโอเทอร์มินัล asciinema เป็นตัวเลือกที่ดีกว่า จริง ๆ สมัยก่อนเซ็ตอัปแบบนี้เรียกว่า “เป็นโปรแกรมเมอร์” ทุกวันนี้ยังต้องมีเครื่องมืออย่าง VSCode, Zed, Cursor และต้องรู้ด้วยว่าควรโยนอะไรให้ LLM ตัวไหนทำ เครื่องมือเหล่านี้ตอนนี้เป็นเพียง “ขั้นต่ำแบบใหม่” แต่ไม่ได้มาแทนสภาพแวดล้อมเดิม ต่อให้ใช้ Claude Code หรือ gptel เก่งแค่ไหน บางครั้งมันก็ยังทำ tree พังได้ และนึกไม่ออกเลยว่าจะใช้ git โดยไม่มี magit ได้ยังไง ถ้าใครคิดว่าใช้ Cursor แบบเดิม ๆ แล้วเร็วกว่าเจ้าของโพสต์ ก็ลองอัดวิดีโอตอนตัวเองใช้ LLM ทำงานจริงให้ดูหน่อย
ผู้ใช้ vim/tmux ทุกคนน่าจะมีโอกาสสูงที่จะสร้าง “Emacs เลียนแบบ” แบบไม่เป็นทางการขึ้นมาเองสักตัว ที่เร็วก็จริงแต่มีบั๊กอยู่ครึ่ง ๆ กลาง ๆ
เขาบอกว่าใช้ tmux บน Windows เลยสงสัยว่าในทางปฏิบัติเขาใช้งานกันยังไง ถ้ามีใครอธิบายได้จะดีมาก
ชอบการแชร์ workflow แบบนี้มาก เหมาะกับผู้อ่านเป้าหมายสุด ๆ ฉันแอบอยากให้วิดีโอมีเสียง แต่การได้อ่าน action list ภายหลังก็โอเค ได้ไอเดียไปปรับใช้กับ workflow ของตัวเองด้วย เขาพูดถึงคีย์ลัด tmux ที่ชวนงง เลยอยากถามว่ามีใครใช้ byobu ที่นี่ไหม byobu เป็น wrapper ของ tmux ที่เอาคำสั่งส่วนใหญ่ไปผูกกับปุ่ม F# ฉันเริ่มใช้เมื่อ 10 ปีก่อนแล้วก็ใช้มาตลอด ก่อนหน้านั้นใช้ tmux เพียว ๆ อยู่หลายปี
ctrl-kเป็น prefix และhก็ไม่ใช่ค่าเริ่มต้นของ “เลือก pane ซ้าย” ฉันไม่เคยใช้ byobu แต่จากที่ฟังดูเหมือนเป็นแค่ทำให้คีย์ลัดเริ่มต้นสะดวกขึ้นอีกหน่อย ซึ่งไม่ได้มีอะไรที่อยากซ้อนเพิ่มเข้าไปมากนักถ้าทำแบบนี้ก็สามารถขยายความสามารถของ copy mode และอื่น ๆ ผ่านปลั๊กอิน tmux ได้ โดยไม่ต้องเขียน regex มหึมาเอง มี tmux-fpp, tmux-copycat, tmux-fingers, tmux-urlview เป็นต้น ลองพึ่งพาฟีเจอร์ในตัวให้มากที่สุดอาจได้เปรียบเรื่องความเร็วด้วย ฉันชอบ tmux-resurrect (บันทึก/กู้คืน session), tmux-continuum (automation), และ tmux-zen สำหรับ Oh-My-Fish มากเหมือนกัน ขอแนะนำ tmux-resurrect, tmux-continuum, tmux-zen ด้วย อยากย้ำว่าการเซ็ตอัปสภาพแวดล้อม tmux เท่ ๆ นั้นง่ายกว่าที่คิดมาก
:ได้ไม่ค่อยดี และ b) copycat ใช้ abstraction ของ viewer เอง ทำให้การค้นหาหนึ่งครั้งทำ action ได้แค่อย่างเดียว วิธีของฉันคือเอาระบบค้นหาในตัวของ tmux มาใช้ซ้ำ เพื่อให้ bind action อะไรก็ได้กับไฟล์ที่ถูก highlight นั่นเอง เหตุผลที่ปลั๊กอินส่วนใหญ่รองรับแค่ copy/paste หรือไม่ก็ต้องยกโหมดของตัวเองขึ้นมา ก็เพราะ tmux แทบจะเปิดให้ควบคุม highlight ได้ก็ผ่านระบบค้นหาในตัวนี่แหละเซ็ตอัปแบบนี้สวยงามจริง ๆ แต่ยังเป็นปริศนาว่าทำไมถึงยังไม่มี AI typeahead สำหรับเทอร์มินัลแบบจริงจังออกมา Cursor Tab ดูเหมือนจะเข้ากันได้พอดี แต่ดันเอามาใช้กับเทอร์มินัลไม่ได้ ชั่วคราวฉันยังรู้สึกอยากทำโปรดักต์แบบลวก ๆ ที่ pipe output ของเทอร์มินัลไปเป็นไฟล์ปลอมแล้วส่งให้ cursor
ชื่อบทความจริง ๆ คือ "How I use my terminal"