12 điểm bởi GN⁺ 2025-08-13 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • Giới thiệu cách triển khai tính năng tự động hoàn thành bằng phím Tab trong BashZsh, có thể hiển thị mô tả ngay cả với những từ đã hoàn thành sẵn
  • Bash và Zsh dùng hai API tự động hoàn thành khác nhau, và chỉ Zsh mặc định hỗ trợ hiển thị mô tả trong gợi ý hoàn thành
  • Triển khai cấu trúc tạo ứng viên bằng _generate_foo_completions, rồi trả về bằng COMPREPLY trong Bash và compadd trong Zsh
  • Để mang tính năng mô tả của Zsh sang Bash, xử lý bằng cách nhúng mô tả vào chuỗi ứng viên rồi chỉ bỏ phần mô tả khi chỉ có một ứng viên duy nhất
  • Ngay cả khi chỉ có một ứng viên, bài viết còn cải tiến bằng cách cố ý thêm tính mơ hồ để khi nhấn <TAB> vẫn hiện mô tả
  • Script cuối cùng mang lại trải nghiệm người dùng giống nhau trên cả hai shell, đồng thời hỗ trợ hoàn thành một phần, hoàn thành đầy đủ và hiển thị mô tả ứng viên

Bối cảnh vấn đề

  • Tự động hoàn thành bằng Tab (tab-completion) rất hữu ích khi khám phá lệnh hoặc cờ, đặc biệt khi mới làm quen với API hay công cụ CLI
  • Zsh mặc định chỉ hiển thị mô tả khi có nhiều ứng viên, còn Bash thì chỉ làm được thông qua cấu hình riêng
  • Nhưng với những từ đã hoàn thành sẵn, cả hai shell đều không hiển thị mô tả
  • Vì vậy, để xem mô tả, người dùng phải làm quy trình bất tiện như sau
    • Xóa bớt một vài ký tự để nhiều ứng viên cùng khớp
    • Nhấn phím <TAB> để xem danh sách ứng viên
    • Tìm mô tả mong muốn bằng mắt
    • Gõ lại các ký tự đã xóa để chạy lệnh

Tổng quan cách giải quyết

  • Ngay cả khi chỉ có một ứng viên, vẫn thêm một ứng viên giả (dummy completion) để tạo ra sự mơ hồ
  • Làm như vậy sẽ khiến cả Bash lẫn Zsh đều in ra danh sách ứng viên kèm mô tả
  • Tuy nhiên, cần cẩn thận để phần mô tả không bị chèn vào lệnh thực tế

Khái niệm cơ bản

  • Tự động hoàn thành bằng Tab hoạt động theo cách nhận từ hiện tại và vị trí con trỏ khi nhấn <TAB>, rồi trả về danh sách các ứng viên có thể dùng
  • Bash: gán các ứng viên vào mảng COMPREPLY
  • Zsh: đăng ký các ứng viên bằng lệnh compadd
  • Hàm _generate_foo_completions sẽ in ra các chuỗi ứng viên; trong thực tế có thể sinh động dựa trên trạng thái của CLI

Hỗ trợ đồng thời Bash và Zsh

  • Cài đặt riêng cho từng shell bằng hai hàm _complete_foo_bash_complete_foo_zsh
  • Phân nhánh bằng if [ -n "${ZSH_VERSION:-}" ]; then ... elif [ -n "${BASH_VERSION:-}" ]; then ... fi
  • Người dùng chỉ cần thêm script vào .bashrc hoặc .zshrc rồi áp dụng

Hiển thị mô tả trong Zsh

  • Dùng định dạng tên: mô tả cho chuỗi ứng viên
  • Zsh: truyền tên và mô tả dưới dạng hai mảng song song bằng compadd -d raw -- $trimmed
  • Bash: chỉ truyền phần ứng viên đã bỏ mô tả vào COMPREPLY (mặc định không hỗ trợ mô tả)

Triển khai mô tả trong Bash

  • Khi có nhiều ứng viên, hiển thị nguyên chuỗi có kèm mô tả
  • Khi chỉ có một ứng viên, mới loại bỏ phần mô tả
  • Tận dụng cách Bash chỉ chèn tiền tố chung khi tự động hoàn thành để phần mô tả không bị đưa vào nội dung đang nhập thực tế

Hiển thị mô tả ngay cả với một ứng viên duy nhất

  • Để vẫn hiện mô tả khi nhấn <TAB> trên một từ đã hoàn thành, thêm ứng viên giả để tạo sự nhập nhằng có chủ đích
  • Zsh: thêm ứng viên giả vào cả hai mảng song song (raw, trimmed)
  • Bash: khi chỉ có một ứng viên thì thêm riêng phần tên vào trimmed

Kết quả cuối cùng

  • Khi có nhiều ứng viên, hiển thị cả tên lẫn mô tả
  • Khi chỉ có một ứng viên, vẫn có thể xem mô tả bằng <TAB>
  • Bash và Zsh đều mang lại trải nghiệm giống nhau
  • Ví dụ áp dụng:
    $ foo <TAB>  
    apple: a common fruit banana: starchy and high in potassium  
    apricot: sour fruit... cherry: small and sweet...  
    

Chưa có bình luận nào.

Chưa có bình luận nào.