• แนะนำวิธีสร้างฟีเจอร์เติมคำอัตโนมัติด้วยแท็บใน Bash และ Zsh ที่แสดงคำอธิบายได้แม้กับคำที่เติมครบแล้ว
  • Bash และ Zsh ใช้ API สำหรับ tab completion คนละแบบ และมีเพียง Zsh ที่รองรับ การแสดงคำอธิบายในรายการเติมคำอัตโนมัติ มาให้โดยพื้นฐาน
  • ใช้ _generate_foo_completions เพื่อสร้างตัวเลือก และส่งกลับผ่าน COMPREPLY ใน Bash, และ compadd ใน Zsh
  • เพื่อให้ Bash แสดงคำอธิบายแบบเดียวกับ Zsh จึงใช้วิธี ใส่คำอธิบายไว้ในสตริงของตัวเลือก และลบคำอธิบายออกเฉพาะตอนที่มีตัวเลือกเดียว
  • แม้ในกรณีที่มีตัวเลือกเดียว ก็ยังปรับปรุงให้แสดงคำอธิบายเมื่อกด <TAB> ได้ โดย จงใจเพิ่มความกำกวม เข้าไป
  • สคริปต์สุดท้ายให้ประสบการณ์ใช้งานแบบเดียวกันในทั้งสองเชลล์ และรองรับครบทั้ง การเติมบางส่วน การเติมทั้งหมด และการแสดงคำอธิบายของตัวเลือก

ที่มาของปัญหา

  • การเติมคำอัตโนมัติด้วยแท็บ (tab-completion) มีประโยชน์มากเวลาไล่ดูคำสั่งหรือแฟล็ก โดยเฉพาะเมื่อเพิ่งเริ่มใช้ API หรือเครื่องมือ CLI
  • โดยปกติ Zsh จะแสดง คำอธิบายเมื่อมีหลายตัวเลือกเท่านั้น ส่วน Bash ต้องอาศัย การตั้งค่าเพิ่มเติม
  • แต่สำหรับ คำที่เติมครบอยู่แล้ว ทั้งสองเชลล์ จะไม่แสดงคำอธิบาย
  • ทำให้ผู้ใช้ต้องผ่านขั้นตอนที่ยุ่งยากดังนี้เพื่อดูคำอธิบาย
    • ลบตัวอักษรบางส่วนออกเพื่อให้ตรงกับหลายตัวเลือก
    • กดปุ่ม <TAB> เพื่อดูรายการตัวเลือก
    • มองหาและแยกคำอธิบายที่ต้องการด้วยสายตา
    • พิมพ์ตัวอักษรที่ลบไปกลับเข้าไปอีกครั้งเพื่อรันคำสั่ง

ภาพรวมของวิธีแก้

  • เมื่อมีตัวเลือกเดียว ก็ เพิ่มตัวเลือกหลอก (dummy completion) เข้าไปเพื่อทำให้เกิดความกำกวมในรายการตัวเลือก
  • วิธีนี้ทำให้ ทั้ง Bash และ Zsh แสดงรายการตัวเลือกพร้อมคำอธิบาย ได้
  • อย่างไรก็ตาม ต้องระวังไม่ให้ข้อความคำอธิบายถูกแทรกเข้าไปในคำสั่งจริง

แนวคิดพื้นฐาน

  • การเติมคำอัตโนมัติด้วยแท็บจะทำงานโดยรับคำปัจจุบันและตำแหน่งเคอร์เซอร์เมื่อกด <TAB> แล้วคืนรายการตัวเลือกที่เป็นไปได้
  • Bash: กำหนดตัวเลือกลงในอาร์เรย์ COMPREPLY
  • Zsh: ลงทะเบียนตัวเลือกด้วยคำสั่ง compadd
  • ฟังก์ชัน _generate_foo_completions จะพิมพ์สตริงของตัวเลือกออกมา และในการใช้งานจริงสามารถสร้างแบบไดนามิกตามสถานะของ CLI ได้

รองรับ Bash และ Zsh พร้อมกัน

  • แยกเขียนตามเชลล์ด้วยฟังก์ชัน _complete_foo_bash และ _complete_foo_zsh
  • ใช้ if [ -n "${ZSH_VERSION:-}" ]; then ... elif [ -n "${BASH_VERSION:-}" ]; then ... fi เพื่อแยกกรณี
  • ผู้ใช้สามารถนำสคริปต์ไปลงใน .bashrc หรือ .zshrc แล้วใช้งานได้

การแสดงคำอธิบายใน Zsh

  • ใช้รูปแบบ ชื่อ: คำอธิบาย กับสตริงของตัวเลือก
  • Zsh: ส่งชื่อและคำอธิบายด้วยอาร์เรย์ขนานผ่าน compadd -d raw -- $trimmed
  • Bash: ส่งเข้า COMPREPLY เฉพาะตัวเลือกที่ตัดส่วนคำอธิบายออกแล้วเท่านั้น (เพราะปกติไม่รองรับคำอธิบาย)

ทำให้ Bash แสดงคำอธิบาย

  • ถ้ามีหลายตัวเลือก ให้แสดงสตริงที่มีคำอธิบายติดมาด้วยตรง ๆ
  • ถ้ามีตัวเลือกเดียว ให้ตัดคำอธิบายออกเฉพาะกรณีนั้น
  • อาศัยพฤติกรรมของการเติมคำอัตโนมัติใน Bash ที่จะแทรกเฉพาะคำนำหน้าร่วมกัน เพื่อไม่ให้คำอธิบายถูกใส่ลงไปในอินพุตจริง

แสดงคำอธิบายได้แม้มีตัวเลือกเดียว

  • เพื่อให้กด <TAB> แล้วเห็นคำอธิบายได้แม้คำจะเติมครบแล้ว จึง เพิ่มตัวเลือกหลอก เพื่อสร้างความกำกวมโดยตั้งใจ
  • Zsh: เพิ่มตัวเลือกหลอกลงในทั้งสองอาร์เรย์ขนาน (raw, trimmed)
  • Bash: ถ้ามีตัวเลือกเดียว ให้เพิ่มเฉพาะชื่อเข้าไปใน trimmed

ผลลัพธ์สุดท้าย

  • เมื่อมีหลายตัวเลือก จะแสดงทั้งชื่อและคำอธิบาย
  • เมื่อมีตัวเลือกเดียว ก็ยังกด <TAB> เพื่อดูคำอธิบายได้
  • ทั้ง Bash และ Zsh ให้ประสบการณ์ใช้งานแบบเดียวกัน
  • ตัวอย่างการใช้งาน:
    $ foo <TAB>  
    apple: a common fruit banana: starchy and high in potassium  
    apricot: sour fruit... cherry: small and sweet...  
    

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น