สร้างสคริปต์เติมเต็ม bash ให้กับเส้นทางเติมข้อความอัตโนมัติหลังจากเครื่องหมายเท่ากับ?


11

ฉันต้องการที่จะสร้างสคริปต์ทุบตีเสร็จสิ้นซึ่งตระหนักถึงข้อโต้แย้งของรูปแบบและ--arg--some-arg=file

หลังจากอ่านบทช่วยสอนนี้และตัวอย่างบางส่วน/usr/share/bash_completion/completions/แล้วฉันได้เขียนสคริปต์ต่อไปนี้ (เพื่อประหยัดเวลาในการพิมพ์ค่าสถานะด้วย Chromium):

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=file
    if [[ ${cur} == "--"*"=" ]] ; then
        # Removed failures (is my logic OK?)
        return 0
    fi

    # Handle other options
    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _chromium chromium

ผมบันทึกไว้~/bash_completions/chromiumและสร้าง symlink sudo ln -s ~/bash_completions/chromium /usr/share/bash_completion/completions/chromiumโดยใช้ จากนั้นผมโหลดได้โดยใช้
. /usr/share/bash_completions/completions/chromium

ตอนนี้ฉันประสบปัญหาสองประการ:

  • chromium --u<TAB>ขยายออกไปchromium --user-data-dir=<SPACE>(ฉันไม่ต้องการพื้นที่)
  • เส้นทาง (ไดเรกทอรีและไฟล์) จะไม่สมบูรณ์อีกต่อไป

ฉันจะแก้ปัญหาเหล่านี้ได้อย่างไร


จะเปลี่ยนเป็นตัวเลือก zsh หรือไม่?
Gilles 'หยุดความชั่วร้าย'

คำตอบ:


11

ฉันพบวิธีแก้ไขปัญหาทั้งสองแล้ว!

  1. หากต้องการไม่เว้นวรรคให้ใช้nospaceตัวเลือก สามารถทำได้สองวิธี:

    • ผ่านมันไปที่complete:
      complete -o nospace -F _chromium chromium
    • ใช้compoptbuilt-in:
      compopt -o nospace(เพื่อเปิดใช้งานตัวเลือก)
      compopt +o nospace(เพื่อปิดการใช้งานตัวเลือก)

    ฉันพบมันในเอกสาร Bash ที่ gnu.org, 8.7 Builtins เสร็จสมบูรณ์ที่ตั้งโปรแกรมได้

  2. เสร็จสิ้นไฟล์
    • peterph ปัญหาการใช้ธง-f ผมทำตามคำแนะนำที่และดำเนินการเป็นcompgen COMPREPLY=( $(compgen -f "$cur") )สิ่งนี้ใช้ได้ดีจนกระทั่งฉันพยายามทำให้เส้นทางที่มีช่องว่างเสร็จสมบูรณ์
      ใน Stack Overflow ฉันพบคำตอบนี้ซึ่งแนะนำการสร้างรายการที่สมบูรณ์แบบแมนนวล (โดยไม่ต้องใช้compgen) วิธีนี้ใช้ได้ผลดี
    • ใช้filenamesตัวเลือกเพื่อบอก Readline ว่า compspec สร้างชื่อไฟล์ดังนั้นจึงสามารถ:
      • ดำเนินการประมวลผลเฉพาะชื่อไฟล์ใด ๆ (เช่นการเพิ่มเครื่องหมายสแลชไปยังชื่อไดเรกทอรีการอ้างอิงอักขระพิเศษหรือการเว้นวรรคที่ต่อท้าย)
      • ใช้สีที่ต่างกันเพื่อระบุประเภทไฟล์ (พร้อมcolored-statsเปิดใช้งาน)

ด้วยความช่วยเหลือของการจัดการสตริงของ Bash (เพื่อขยาย~และจัดการช่องว่าง) ฉันสร้างสคริปต์การเติมเต็มของ bash ซึ่งตรงตามเกณฑ์ทั้งหมดที่ระบุไว้ในคำถาม

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=
    if [[ ${prev} == "--"* && ${cur} == "=" ]] ; then
        compopt -o filenames
        COMPREPLY=(*)
        return 0
    fi
    # Handle --xxxxx=path
    if [[ ${prev} == '=' ]] ; then
        # Unescape space
        cur=${cur//\\ / }
        # Expand tilder to $HOME
        [[ ${cur} == "~/"* ]] && cur=${cur/\~/$HOME}
        # Show completion if path exist (and escape spaces)
        compopt -o filenames
        local files=("${cur}"*)
        [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]// /\ }" )
        return 0
    fi

    # Handle other options
    COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
    if [[ ${#COMPREPLY[@]} == 1 && ${COMPREPLY[0]} != "--"*"=" ]] ; then
        # If there's only one option, without =, then allow a space
        compopt +o nospace
    fi
    return 0
}
complete -o nospace -F _chromium chromium

คำตอบที่ยอดเยี่ยมขอบคุณมาก คุณประหยัดเวลาได้มาก ฉันใช้-fสวิตช์สำหรับการทำพา ธ ไฟล์ให้เสร็จ แต่มันไม่สมบูรณ์/ถ้าเป็นไดเร็กตอรี่ ... มันเป็นเรื่องเล็กน้อย
Jiri Kremser

1

เพื่อให้ชื่อไฟล์ที่สมบูรณ์พยายามผ่านไป-fcompgen

ฉันกลัวว่าคุณจะไม่สามารถกำจัดช่องว่างหลังจากตัวเลือกได้เนื่องจากเป็นวิธีการทำงานที่สมบูรณ์ - เมื่อพบการจับคู่ที่ไม่ซ้ำกันมันจะเสร็จสมบูรณ์โดยสมบูรณ์


-fขอบคุณสำหรับคำแนะนำของ ฉันพยายาม แต่มันไม่ถูกต้องจัดการกับช่องว่าง: เส้นทาง/tmp/foo barผลลัพธ์ในรายการที่สองเสร็จสิ้นและ/tmp/foo barเกี่ยวกับผู้ที่ไม่พึงประสงค์--arg=<SPACE>: ฉันได้พบวิธีการนั้นและโพสต์ไว้ในคำตอบดังต่อไปนี้
Rob W
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.