Cách tôi dùng Windows Terminal – tự động hóa terminal ở mức tối đa với tmux và workflow tùy biến
(jyn.dev)- Kết hợp tmux, SSH, nvim và các script tìm kiếm/tự động hóa mạnh mẽ để tạo ra một workflow độc đáo, cho phép duyệt, chỉnh sửa và tìm kiếm tệp trên máy chủ từ xa ngay lập tức mà không cần GUI
- Chỉ với một tổ hợp phím, có thể tự động tìm tên tệp trong nhiều cửa sổ tmux và mở ngay, đồng thời chuyển tệp và quản lý buffer hoàn toàn bằng phím tắt
- Vì không hài lòng với tốc độ chậm của VSCode và xung đột key binding, tác giả đã tự viết script để hợp nhất mọi thao tác
- Bằng cách kết hợp các công cụ Unix như regex, perl, tmux, nvim, tác giả hiện thực hóa việc tự động nhận diện và mở đường dẫn tệp cùng thông tin dòng
- Quá trình tự triển khai rất phức tạp, nhưng cho thấy có thể khai thác tối đa sức mạnh và khả năng mở rộng của terminal
Cách tôi dùng terminal của riêng mình
- Bài viết này chia sẻ trải nghiệm xây dựng một môi trường phát triển hiệu quả bằng cách kết hợp terminal với nhiều công cụ
- Vì đây vốn là một quy trình phức tạp, thường cần video mới dễ hiểu, nên tác giả kết hợp văn bản với video minh họa thực tế (rất nên xem video)
- Một số bước trong video (0:11, 0:21, 0:41) là những đoạn khiến nhiều người phải ngạc nhiên kiểu “việc này cũng làm được à?”
Tóm tắt từng bước workflow terminal trong video
- 0:00 : Chạy Windows Terminal trên laptop
- 0:02 : Mở tab terminal mới bằng phím tắt ctrl + shift + 5, dùng
sshđể kết nối tới máy desktop ở nhà, rồi chạy tmux ngay - 0:03 : Chạy shell mặc định zsh trong tmux, hiển thị prompt và tải toàn bộ cấu hình theo kiểu bất đồng bộ
- 0:08 : Dùng
zoxideđể tìm mờ thư mục gần đây rồi di chuyển tới đó - 0:09 : Bắt đầu nhập lệnh ripgrep, zsh tự động hoàn thành dựa trên lịch sử sử dụng trước đó, rồi nhấn ctrl + f để chấp nhận
- 0:11 : Dùng phím tắt
ctrl + kfđể tìm tên tệp trong toàn bộ scrollback của tmux, tên tệp được tô sáng màu xanh - 0:12 : Liên tục nhấn phím
nđể duyệt qua danh sách tệp đã tìm được và chọn tệp mong muốn - 0:21 : Nhấn phím
ođể mở tệp đã chọn bằng ứng dụng mặc định (nvim), tmux chạy trong cửa sổ mới (vẫn hoạt động trên máy chủ từ xa) - 0:26 : Thử di chuyển qua nhiều tham chiếu trong mã bằng rust-analyzer; một số macro không được nhận diện, nhưng tới 0:32 thì di chuyển thành công bình thường
- 0:38 : Dùng
ctrl + khđể chuyển focus của tmux sang cửa sổ bên trái - 0:39 : Nhấn lại phím
nđể tiếp tục duyệt kết quả tìm tệp trước đó trong trạng tháicopy-mode - 0:41 : Nhấn phím
ođể lần này mở một tệp khác trong instance nvim đang mở sẵn - 0:43 : Nhấn phím
bđể xem danh sách buffer tệp đang mở, rồi chuyển qua lại giữa hai tệp để kết thúc
Vì sao lại dùng workflow terminal như vậy?
- VSCode chậm, và đặc biệt bị khựng rất nhiều khi dùng plugin vim
- Xung đột key binding thường xuyên xảy ra giữa editor, plugin vim, terminal và các tính năng quản lý cửa sổ, gây rất nhiều bất tiện
- Tác giả cũng đã thử editor Zed, nhưng ở thời điểm đó nó vẫn còn non nớt và vấn đề xung đột key binding vẫn còn nguyên
- Tác giả bắt đầu dùng trực tiếp nvim (Neovim) trong terminal, nhưng
- Quá trình phải sao chép từng tên tệp rồi dán vào editor sau khi tìm kiếm bằng ripgrep quá phiền phức
- Đặc biệt khi kết quả ripgrep đi kèm cả tên tệp và số dòng thì
- Mỗi lần dán vào lại phát sinh lỗi cú pháp
- Thường phải chỉnh sửa không cần thiết trước khi thực sự mở được tệp
- Tác giả cảm thấy cần một workflow mở trực tiếp đường dẫn tệp giống như ctrl-click trong VSCode
- Vì vậy tác giả đã tự hiện thực tính năng mong muốn bằng tmux
- Khi bị hỏi vì sao dùng tmux, tác giả giải thích ngay rằng chính là vì khả năng tự động hóa này và việc giữ nguyên session
- Terminal thực ra mạnh hơn nhiều so với mọi người tưởng, nhưng chỉ với tính năng mặc định thì rất khó thấy được mức tự động hóa như vậy
- Dù tmux đã cũ, cú pháp phức tạp và cũng có bug, tác giả vẫn chọn nó vì khả năng mở rộng và tùy biến
Cách triển khai chính
Tìm tên tệp trong toàn bộ scrollback của tmux
- Dùng biểu thức chính quy phức tạp trong copy-mode của tmux để khớp mẫu tên tệp
- Dùng script regex tự viết (
search-regex.sh) để tô sáng cả đường dẫn tệp, dòng và cột - Ví dụ cấu hình tmux:
bind-key f copy-mode \; send-keys -X search-backward '정규표현식'
Mở tệp đã chọn trong cửa sổ mới/cửa sổ hiện tại
- Dùng phím tắt tmux được tùy biến để mở tệp đã chọn bằng ứng dụng mặc định hoặc editor (nvim, v.v.)
- Hỗ trợ đường dẫn tương đối và mở rộng tilde
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 ...'
Mở tệp trong instance nvim đã mở sẵn
- Dùng script perl để tmux tìm đúng pane nvim cụ thể, rồi gửi trực tiếp thao tác gõ phím kèm cả thông tin tệp/dòng vào pane đó
- Chuyển cú pháp
file:line:columnthành lệnh vim để tự động mở
Ưu điểm và giới hạn của cách làm này
- Vượt qua giới hạn tính năng của terminal cục bộ: dùng tmux để hiện thực việc duyệt/chỉnh sửa/tìm kiếm tệp tự do trên máy chủ từ xa
- Ngay cả khi editor không hỗ trợ giao thức chỉnh sửa từ xa, vẫn có thể dùng cùng một workflow
- Có thể hợp nhất toàn bộ key binding, tìm kiếm, chuyển tệp, quản lý buffer, v.v. đúng theo sở thích cá nhân
- Tự động hóa nhanh và dễ hơn cả việc viết plugin cho VSCode
- Các script tự viết dễ hỏng và khó bảo trì, nên rất khó khuyến nghị cho người khác
Giải pháp thay thế
- Những tổ hợp mã nguồn mở/công cụ được khuyến nghị nói chung:
fish + zoxide + fzf: có thể thay thế workflow tìm thư mục mờ, tìm lệnh và một phần tìm tệp- Các tính năng tích hợp sẵn trong editor (tab, window, fuzzy finder, v.v.) cũng là đủ với phần lớn người dùng
qf: có thể chọn tệp từ đầu ra terminal, nhưng không thể tích hợp với công cụ có tính tương tác; dùng CLI kiểu vie: công cụ nhỏ nhận diện đường dẫn dạng file:line (cần script riêng tùy theo từng editor)vim --remote,code filename,emacsclientcũng cho hiệu ứng tương tự, nhưng khả năng nhận diện file:line vẫn chưa hoàn hảo
Kết luận và bài học rút ra
- Terminal mạnh hơn rất nhiều so với tưởng tượng, và nếu tự kết hợp bằng script thì có thể tạo ra mức tự động hóa mà công cụ GUI không làm được
- Tuy vậy, vẫn tồn tại các giới hạn thực tế như khả năng bảo trì và bug tiềm ẩn trong script
- Nếu quan tâm đến tự động hóa workflow terminal, cách thực tế là bắt đầu từng bước với môi trường tmux/nvim/fzf tùy biến
1 bình luận
Ý kiến trên Hacker News
Tôi cũng đang dùng mẹo tương tự. Tận dụng scrollback của tmux, rồi pipe phần output đã được tokenize sang zsh để có thể dùng autocomplete cho mọi thứ đang hiển thị trên màn hình tmux. Tôi có chia sẻ bài post trên Threads liên quan và mã gist. Thực sự rất hữu ích
Tôi thực sự thích kiểu workflow này, và cũng đã lặp đi lặp lại để tinh chỉnh một thứ tương tự suốt nhiều năm. Theo thời gian tôi cố giảm tối đa các lớp tùy biến, vì càng nhiều overlay thì chi phí bảo trì càng cao. Ngay cả trong Vim thuần (không cần tmux riêng) cũng làm được hầu hết những gì bài viết giới thiệu, ví dụ
rg --vimgrep restore_tool | vim -c cb -(vim -c cb -là tính năng tôi thích nhất trong Vim, đến mức lạ là hầu như chẳng ai dùng). Tất nhiên việc chạy lại tìm kiếm bằng rg mỗi lần có thể hơi tốn kém, nên tôi thường phân tích kết quả ngay trong terminal rồi khi cần thì dùng lệnh tùy biến của tmux để copy output của lệnh gần nhất và gửi sang vim. Lúc đó tôi cũng dùng mẹo tận dụng ký tự Unicode trong prompt hoặc chuyển bằngtmux saveb - | vim -c cb -vimrcrất ngắn, mỗi năm chỉ thêm chừng 1–2 dòng. Thường thì các thiết lập mặc định của phần mềm lâu đời đều có lý do tồn tại; tôi khuyên nên hiểu lý do đó trước khi thay đổi bừa bãivim -c cb -là tính năng yêu thích trong Vim, nên tôi tò mò nó làm gì. Tôi thửls | vim -vàls | vim -c cb -nhưng chưa nhận ra khác biệt ngay)vim -q <(ripgrep --vimgrep restore_tool)khôngBộ setup này nhìn rất ổn vì có đủ tmux, fzf, rg, zoxide và một nvim gọn gàng. Nếu chưa có thì tôi cũng muốn gợi ý atuin, starship, bat, glow, duf, dogdns, viddy, gum/sesh, dust, btop, v.v. Có thể tìm hết trong các danh sách Awesome Terminal XYZ trên GitHub. atuin thực sự gần như bắt buộc, còn nếu không có zoxide thì giống như một vận động viên đi đôi giày không vừa chân. Khi quay video terminal thì asciinema là lựa chọn tốt hơn. Thật ra ngày xưa người ta gọi kiểu setup này là “lập trình viên”. Bây giờ thì còn phải có VSCode, Zed, Cursor và biết giao việc gì cho LLM nào. Những công cụ đó giờ chỉ là mức “tối thiểu” mới, chứ không thay thế môi trường cũ. Dù dùng Claude Code hay gptel giỏi đến đâu thì đôi lúc vẫn có thể làm hỏng cả cây thư mục, còn dùng git mà không có magit thì tôi không tưởng tượng nổi. Nếu ai nghĩ dùng Cursor thuần còn nhanh hơn OP, hãy bảo họ tự quay một video dùng LLM trong thực chiến xem sao
Mọi người dùng vim/tmux nhiều khả năng đều đã tự chế ra một kiểu “Emacs giả lập” không chính thức, hơi lỗi nhưng chạy nhanh
Anh ấy nói dùng tmux trên Windows, nhưng tôi không rõ thực tế là dùng kiểu gì. Nếu ai giải thích được thì tốt
Tôi rất thích cách chia sẻ workflow kiểu này. Rất đúng với đối tượng độc giả. Tôi chỉ ước video có âm thanh, nhưng đọc danh sách thao tác sau đó cũng ổn. Tôi cũng học được vài thứ có thể tham khảo cho workflow của mình. Bài có nhắc đến các phím tắt tmux khá khó nhớ; ở đây có ai dùng byobu không? byobu là wrapper cho tmux, gán hầu hết lệnh vào các phím F#. Tôi biết đến nó từ 10 năm trước và dùng liên tục từ đó. Trước đó tôi đã dùng tmux thuần vài năm
ctrl-klà prefix, cònhkhông phải mặc định là “chọn panel bên trái”. Tôi chưa dùng byobu bao giờ, nhưng nghe mô tả thì có vẻ chỉ là làm các phím mặc định dễ dùng hơn một chút nên tôi không quá muốn chồng thêm lớp đó lênTheo hướng này thì bạn cũng có thể mở rộng copy mode và các tính năng khác bằng plugin tmux mà không cần tự viết regex khổng lồ. Có tmux-fpp, tmux-copycat, tmux-fingers, tmux-urlview. Cũng nên lưu ý rằng phụ thuộc tối đa vào tính năng tích hợp sẵn có thể có lợi về tốc độ. Tôi đặc biệt thích tmux-resurrect (lưu/khôi phục session), tmux-continuum (tự động hóa) và tmux-zen cho Oh-My-Fish. Giới thiệu thêm tmux-resurrect, tmux-continuum, tmux-zen. Tôi muốn nhấn mạnh rằng việc dựng một môi trường tmux ngầu thật ra dễ hơn nhiều người nghĩ
:không tốt, và b) copycat dùng lớp trừu tượng viewer riêng nên mỗi lần tìm kiếm chỉ làm được đúng một hành động. Cách của tôi tái sử dụng search tích hợp của tmux, nhờ vậy có thể bind tùy ý các hành động lên những file đang được highlight. Phần lớn plugin chỉ hỗ trợ copy/paste hoặc dựng mode riêng của chúng, vì tmux gần như chỉ cho điều khiển highlight thông qua search tích hợpKiểu setup này thật sự rất đẹp. Nhưng vẫn là điều bí ẩn khi chưa có AI typeahead thực sự tử tế nào xuất hiện trong terminal. Cursor tab có vẻ cực kỳ hợp, nhưng lại bị chặn không áp dụng cho terminal. Tôi còn muốn tự ráp nhanh một sản phẩm tạm thời kiểu pipe output của terminal sang một file giả rồi đẩy vào cursor
Tiêu đề bài viết thực ra là "How I use my terminal"