23 điểm bởi GN⁺ 2025-06-24 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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ái copy-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
    Quảng cáo
  • 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 ...'  
    
    Quảng cáo

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:column thà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 vi
    • e: 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, emacsclient cũ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

 
GN⁺ 2025-06-24
Ý 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 quanmã 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ằng tmux saveb - | vim -c cb -

    • Cách đây 10 năm tôi đã bỏ bộ cấu hình vim khổng lồ cho nhiều file, nhiều package, và đang dần đơn giản hóa bằng một vimrc rấ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ãi
    • (Bạn nói vim -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 -ls | vim -c cb - nhưng chưa nhận ra khác biệt ngay)
    • Không biết nó có cùng mục đích với vim -q <(ripgrep --vimgrep restore_tool) không
  • Bộ 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

    • Làm lập trình viên không phải chỉ là setup môi trường phát triển. Có người rất giỏi vẫn thích ex editor, trong khi có người mới chỉ chăm chút IDE bóng bẩy nhưng thiếu hiểu biết nền tảng. Tất nhiên công cụ tốt có thể giúp, nhưng tác động của chúng đến thành công thực tế thường khá nhỏ. Có thể LLM sẽ thay đổi điều này. Ví dụ, dù đi đôi giày chạy không vừa khiến bạn chậm hơn 5%, thì ở startup, thành bại thường không do những khác biệt nhỏ như thế mà do các vấn đề lớn hơn như bất hòa đồng sáng lập, mất động lực, hay sản phẩm không khớp thị trường
    • Danh sách công cụ của bạn hay đấy, nhưng với người không biết các tên như atuin, dogdns hay btop thì phần lớn trong số đó có thể hơi xa lạ
    • Tôi rất thích danh sách lệnh này. Tôi nhất định sẽ thêm fd (tác giả: sharkdp) vào đây. Nó là bản thay thế cho find và rất tuyệt về mặt trải nghiệm sử dụng. Còn atuin là nâng cấp lớn nhất trong đời sống CLI của tôi. Nó giúp tôi dễ dàng tìm lại cả những lệnh hiếm đã gõ từ 6 tháng trước
    • Có vẻ bạn đang quá ám ảnh với việc chọn công cụ. Lập trình viên thực sự giỏi vẫn tạo ra kết quả nhanh ngay cả trong môi trường trần trụi. Tất nhiên công cụ tốt có thể giúp nhỉnh hơn một chút, nhưng phần lớn chỉ là chuyện vui cá nhân và sở thích. Nếu bạn thực sự cảm thấy năng suất của mình phụ thuộc mạnh vào IDE, thì có lẽ hành trình học hỏi và trưởng thành của bạn vẫn còn rất dài. Từ xưa đến nay, biết công cụ không đồng nghĩa với là lập trình viên. Những người giỏi nhất tôi từng thấy thường chỉ dùng more/grep/vi cộng thêm khả năng suy nghĩ mà vẫn tạo ra kết quả vượt trội. Giá trị rốt cuộc vẫn đến từ tư duy. Ngay cả trong thời đại LLM điều này cũng không đổi
  • 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

    • Tôi thậm chí còn làm cả một terminal emulator đổi prefix hai phím của tmux thành một phím duy nhất có modifier ctrl cho mọi lệnh. Liên kết dự án
    • Tôi thì dùng cả vim/tmux lẫn emacs (và trước đây dùng emacs thuần trong thời gian dài), nhưng môi trường emacs của tôi lại ngẫu hứng hơn, ít tài liệu hơn và nhiều lỗi hơn hẳn. Setup vim+tmux thì tương đối ổn định
    • Tôi đồng cảm sâu sắc với nhận xét đó. Hiện tại trong workflow của mình tôi chạy :Term ngay bên trong nvim
    • Môi trường vim+tmux phụ thuộc khá nhiều vào các primitive của hệ thống như pipe, file, signal và scrollback. Vì vậy toolchain hoạt động một cách tự nhiên và minh bạch trong nhiều môi trường khác nhau, kể cả qua ssh hay trong shell bị giới hạn. Đây là lợi thế lớn về tính di động và khả năng debug. Nói cách khác, workflow của tôi có cảm giác được chia nhỏ tự do dựa trên những đảm bảo nền tảng này, nên việc tự làm cấu hình vim trở thành lựa chọn rất tự nhiên
  • 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 đoán là remote vào hệ Unix rồi làm việc thật ở đó. Trên server Unix có thể chạy tmux hoàn hảo. Tôi cũng hay SSH vào VM VirtualBox để có một lớp tương thích gọn gàng hơn WSL. Đây cũng là một lý do khiến tmux mạnh hơn các cách khác: chỉ cần cài trên server là từ xa vẫn phát huy trọn vẹn vai trò của nó. Liên kết giải thích liên quan
  • 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

    • Rất vui vì bạn thấy nội dung thú vị :) Tôi đã cố làm sao cho nó vừa rõ ràng vừa dễ nắm bắt nhất có thể. Tôi remap hầu hết phím tắt tmux để dùng. ctrl-k là prefix, còn h khô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ên
  • Theo 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ĩ

    • Tôi cũng lấy regex gốc từ tmux-copycat. Nhưng a) regex đó bắt : 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ợp
  • Kiể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"

    • Tính năng tự động của HN hay cắt mất từ đầu nếu tiêu đề bắt đầu bằng How. Không có căn cứ gì rõ ràng, quản trị viên nói là để chống clickbait nhưng thực tế chỉ gây rối hơn
    • Ban đầu tôi còn tưởng bài này là một kiểu nhại phim 'There Will Be Blood' (vì tiêu đề hiện tại là 'I use my terminal')
    • Tôi cũng tưởng đây là bài kể về một terminal emulator do ai đó tự viết
    • Tôi cũng mới biết điều đó. Lướt qua bài thì tôi đoán tiêu đề đầy đủ chắc là "I use my terminal (and so should you )" gì đó. Tôi lúc nào cũng thích các bài về terminal, và với tư cách người dùng Chromebook thì chỉ cần trình duyệt với terminal là đủ. Chuyển sang Mac thì thấy quá dư thừa, nên bình thường tôi chỉ dùng terminal hoặc trình duyệt
    • Khi đăng tiêu đề trên HN, các tiền tố hay hậu tố quá phổ biến thường bị tự động cắt bỏ