สามารถใช้สคริปต์การเติมแท็บ Bash ใน zsh ได้หรือไม่


87

ฉันมีสคริปต์การเติมแท็บ Bash สำหรับ Hadoop ของ Apache โดยปกติฉันใช้ zsh เป็นเชลล์แบบวันต่อวัน มันมีแนวโน้มที่จะค่อนข้างทุบตีเมื่อฉันต้องการให้เป็น แต่ดูเหมือนว่าระบบการเติมแท็บจะแตกต่างกันอย่างสิ้นเชิง มีวิธีง่ายๆในการ "แปลง" คำจำกัดความ bash-tab-complete ที่มีอยู่ให้ทำงานใน zsh หรือไม่ ฉันไม่ต้องการเสียเวลามากมายในเรื่องนี้ แต่ถ้ามันง่ายฉันก็จะประหยัดแรงได้พอสมควร

คำตอบ:


39

จากหน้านี้ (ลงวันที่ 2010/01/05):

Zsh สามารถจัดการกับฟังก์ชัน bash ที่สมบูรณ์ได้ เวอร์ชันพัฒนาล่าสุดของ zsh มีฟังก์ชัน bashcompinit ซึ่งเมื่อเรียกใช้จะอนุญาตให้ zsh อ่านข้อกำหนดและฟังก์ชั่นการเติม bash เอกสารนี้อยู่ในเพจ zshcompsys man ในการใช้งานสิ่งที่คุณต้องทำคือเรียกใช้ bashcompinit ได้ตลอดเวลาหลังจากคอมบินิ มันจะกำหนดฟังก์ชันที่สมบูรณ์และสอดคล้องกับ bash builtins


ข่าวดี: ฉันคิดว่าสิ่งนี้ควรได้ผลดังนั้นขอบคุณมาก ข่าวร้าย: ด้วยเหตุผลบางประการระบบที่ฉันพยายามดำเนินการนี้ดูเหมือนจะไม่โหลด / etc / zshrc เมื่อฉันล็อกอินผ่าน SSH ฉันไม่รู้เกี่ยวกับขั้นตอนการเข้าสู่ระบบมากพอที่จะบอกได้ว่าทำไมจึงเป็นเช่นนั้น อาจถึงเวลาถามคำถามอื่น ...
Coderer

1
@Coderer: ก่อนอื่นคุณพูดว่า "/ etc / zshrc" /etc/zsh/zshrcในระบบของฉันมันเป็น นอกจากนี้ตรวจสอบไฟล์ต่อไปนี้เพื่อย้อนกลับ (อยู่ในลำดับที่พวกเขามีที่มาระหว่างการเริ่มต้น zsh): /etc/zsh/zshenv, $ZDOTDIR/.zshenv, /etc/zsh/zprofileและ$ZDOTDIR/.zprofile(อาจจะ~/.zprofile) เพื่อดูว่าRCSตัวแปรคือไม่มีการตั้งค่า ถ้าเป็นเช่นนั้นจะป้องกันไม่ให้ไฟล์ที่ตามมาหลังจากไฟล์ที่ไม่ได้ตั้งค่ามาจากแหล่งที่มา สุดท้ายตรวจสอบเชลล์สำหรับผู้ใช้ใน/etc/passwdและตรวจสอบให้แน่ใจzshและตรวจสอบให้แน่ใจว่าไม่มี-fข้อโต้แย้ง
Dennis Williamson

ขอบคุณสำหรับคำติชมทั้งหมด - ฉันใช้แฮ็คโปรแกรมเมอร์คลาสสิกอันดับ 1 "stdout debugging" (ข้อความสะท้อนในสคริปต์เริ่มต้นแต่ละรายการ) และพบปัญหา ด้วยเหตุผลบางประการ / etc / zprofile ของเรากำลังจัดหาสคริปต์ /etc/profile.d ต่างๆซึ่งจากนั้นได้รับที่มาอีกครั้งใน / etc / zshrc เพียงแค่ย้ายคำสั่ง autoload ไปที่ด้านบนของ / etc / zprofile ก็แก้ไขปัญหาได้
Coderer

158
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file

10
นี่คือคำตอบที่ดีกว่าเนื่องจากจะบอกวิธีใช้ bashcompinit งานที่ดี.
pyrospade

5
ขอบคุณคำตอบที่ดีน่าเสียดายที่สิ่งนี้ใช้ไม่ได้หากสคริปต์ใช้คำสั่ง _init_completion bash
0 ครั้ง

6
สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันยังคงได้รับcomplete:13: command not found: compdefข้อผิดพลาด
Jatin Kumar

หากไม่ได้ผลให้ตรวจสอบสคริปต์ (ทำ :)) - อาจมีการif is-bashตรวจสอบที่ด้านบน
olejorgenb

สิ่งนี้ใช้ไม่ได้กับบางสคริปต์ที่ใช้_get_comp_words_by_refซึ่งไม่ได้กำหนดโดยbashcompinit. ความสำเร็จส่วนใหญ่ไม่ได้ใช้ฟังก์ชันนี้
Franklin Yu

41
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script

ฉันใช้ zsh zsh 5.0.2 (x86_64-apple-darwin13.0) โดยไม่มี ~ / .zshrcและลำดับข้างต้นทำงานใน zsh shell ที่เกิดใหม่

ขอบคุณสคริปต์ git-complete.bash สำหรับคำใบ้: D


อ่านรายละเอียดเพิ่มเติมเกี่ยวกับ 3 บรรทัดด้านบน:

ทุบตีมีที่น่ากลัวในการสนับสนุนสร้างเสร็จอัตโนมัติ แต่สคริปต์ทุบตีเติมข้อความอัตโนมัติไม่ทำงานโดยตรง zsh สิ่งแวดล้อม zsh ไม่ได้มีการเติมข้อความอัตโนมัติทุบตีที่สำคัญฟังก์ชั่นช่วยที่ชอบcompgen,complete ,เพื่อให้เซสชัน zsh รวดเร็ว

วันนี้ zsh มาพร้อมกับสคริปต์การทำให้สมบูรณ์ที่เหมาะสมเช่นcompinitและbashcompinitซึ่งมีฟังก์ชั่นที่จำเป็นเพื่อรองรับสคริปต์การเติมข้อความอัตโนมัติ bash

autoload <func_name>: โปรดทราบว่า autoload ถูกกำหนดใน zsh และไม่ใช่ bash autoloadค้นหาไฟล์ที่ตั้งชื่อในพา ธ ไดเร็กทอรีที่ส่งคืนโดยfpathคำสั่งและทำเครื่องหมายฟังก์ชันเพื่อโหลดไฟล์เดียวกันเมื่อเรียกใช้ครั้งแรก

  • -U:ละเว้นนามแฝงใด ๆ เมื่อโหลดฟังก์ชันเช่น compinit หรือ bashcompinit
  • + X:เพียงแค่โหลดฟังก์ชั่นที่มีชื่อตอนนี้และไม่ต้องดำเนินการ

ตัวอย่างเช่นในระบบของฉันecho $fpathส่งคืน/usr/share/zsh/site-functionsและ/usr/share/zsh/5.0.5/functionsและcompinitและbashcompinitมีอยู่ที่/usr/share/zsh/5.0.5/functionsมีให้บริการที่

นอกจากนี้สำหรับคนส่วนใหญ่อาจจำเป็นเท่านั้นautoload -U +X bashcompinit && bashcompinitเนื่องจากสคริปต์อื่น ๆ เช่นการเติมข้อความอัตโนมัติของคอมไพล์หรือของพวกเขาเอง~/.zshrcอาจกำลังทำอยู่autoload -U +X compinit && compinitแต่ก็ปลอดภัยที่จะเรียกใช้ทั้งสองอย่าง


คืออะไร-Uและ+Xเพื่ออะไร?
jmk

คำตอบที่อัปเดตพร้อมรายละเอียดเพิ่มเติม
Jatin Kumar

6
สิ่งนี้ยังไม่ค่อยสมเหตุสมผล manpage อธิบายถึงจุด+X fooที่ทำการโหลดอัตโนมัติแบบเดียวกับที่เรียกใช้fooแต่ไม่ได้ดำเนินการทันที ... autoload +X foo && fooดูเหมือนจะซ้ำซ้อนโดยสิ้นเชิง คุณอธิบายได้ไหมว่าทำไมคุณถึงเลือกรูปแบบนี้?
ELLIOTTCABLE

2
@ELLIOTTCABLE ประเด็นของการทำautoload -U +X bashcompinit && bashcompinitคือ (เนื่องจาก&&) มันจะดำเนินการbashcompinitIFF โมดูลที่พบจริง Normal autoload fooจะคืนค่าจริงเสมอ ต่อมาเมื่อคุณพยายามที่จะเรียกใช้foo, แล้ว zsh ในที่สุดก็จะบอกคุณ "ไม่พบไฟล์การกำหนดฟังก์ชั่น" ด้วยautoload +Xคุณจะได้รับข้อผิดพลาดทันที
FeRD

1
หน้าคนยังคงเป็นที่ค่อนข้างชัดเจนในจุดที่มันดูเหมือนว่าฉัน: autoload +Xโหลดฟังก์ชั่นโดยไม่ต้องรันมัน - ซึ่งเป็นมากขึ้นกว่าไม่ได้โดยไม่ต้องautoload +Xหากไม่มีการ+Xโหลดอัตโนมัติจะไม่โหลดฟังก์ชัน เป็นเพียงการทำเครื่องหมายชื่อเป็นการอ้างถึงฟังก์ชันที่จะโหลดในภายหลัง จะไม่พยายามโหลดจริงจนกว่าจะมีการเรียกใช้ฟังก์ชันครั้งแรก หากคุณต้องการตรวจสอบว่าฟังก์ชันที่ตั้งชื่อโหลดสำเร็จหรือไม่คุณต้องใช้+Xเพื่อดำเนินการขั้นตอนการโหลดทันที
FeRD

4

สำหรับzshใช้:

  • compdef
  • compadd

ตัวอย่างของฉัน:

# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun)
_bxrun_methods() {
    grep "^\s*\(function\s\+\)\?__.\+()\s*{.*$" "${1}" | while read line ; do
        echo "$line" | sed "s/()\s*{.*//g" | sed "s/\s*\(function\s\+\)\?__//g"
    done
}
_bxrun_lst() {
    if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then
        for f in /home/ecuomo/projects/bashx/src/actions/* ; do
            if [ -f "${f}" ]; then
                basename "${f}" | sed 's/\..*$//g'
            fi
        done
    fi
    _bxrun_methods "/home/ecuomo/projects/bashx/bxrun"
    _bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh"
}
_bxrun() {
    local cur
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -W '$( _bxrun_lst )' -- $cur  ) )
}
_bxrun_zsh() {
    compadd `_bxrun_lst`
}
if type complete >/dev/null 2>/dev/null; then
    # bash
    complete -F _bxrun bxrun
else if type compdef >/dev/null 2>/dev/null; then
    # zsh
    compdef _bxrun_zsh bxrun
fi; fi

ที่มา: รหัสของฉันhttps://github.com/reduardo7/bashx


1
คุณควรเปิดเผยว่าคุณเป็นผู้เขียนกรอบ bashx ที่เชื่อมโยง
เบ็น

4

ฉันใช้Antigenในฐานะผู้จัดการปลั๊กอิน Oh-My-Zsh ฉันมีสคริปต์เสร็จสิ้น bash สองสามตัวที่เขียนโดยเพื่อนร่วมงานที่ฉันต้องการโหลดลงใน Zsh ด้วยไฟล์source /path/to/completion.

ฉันมีปัญหาเพราะดูเหมือนว่า Antigen หรือ OMZ (ยากที่จะบอก) เกี่ยวข้องกับการโหลดสคริปต์ที่สมบูรณ์จากปลั๊กอินเท่านั้น ในที่สุดฉันก็ทำได้โดยการโหลดอัตโนมัติbashcompinit และ compinitหลังจากantigen applyนั้น การโหลดอัตโนมัติเพียงอย่างเดียวbashcompinitนั้นไม่เพียงพอ

source ~/.antigen/antigen.zsh
antigen use oh-my-zsh
antigen apply

autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit

source /path/to/bash_completion

Antigen สร้าง.zcompdumpไฟล์ที่$ANTIGEN_COMPDUMPสำหรับฉัน~/.antigen/.zcompdump

การเรียกใช้ compinit และ bashcompinit ซ้ำจะสร้าง. zcompdump ที่สองที่ $HOME/.zcompdump

ที่ดูเหมือนว่าจะทำงานออกทั้งหมดเพราะผมสามารถที่จะใช้ความสำเร็จที่กำหนดขึ้นโดย/path/to/bash_completionจะทำงานออกทั้งหมดเพราะผมสามารถที่จะใช้ความสำเร็จที่กำหนดขึ้นโดยฉันได้ลบไฟล์. zcompdump ทั้งสองสองสามครั้งเพื่อให้แน่ใจว่าได้สร้างขึ้นใหม่และดูเหมือนจะใช้งานได้

ฉันต้อง rm ไฟล์. zcompdump สองสามครั้งหลังจากที่เครื่องรีบูตเนื่องจากมีข้อผิดพลาดเกิดขึ้นเมื่อพยายามแท็บเสร็จสมบูรณ์ แต่ฉันไม่แน่ใจว่าเกิดจากการตั้งค่านี้หรืออย่างอื่น rm ~/.zcompdump && rm $ANTIGEN_COMPDUMPและเชลล์ใหม่ก็แก้ไขให้ฉัน

เวอร์ชันที่ใช้ในขณะเขียน:

Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3

0

คำตอบของ @ JatinKumar ทำให้ฉันมาถูกทาง แต่ฉันต้องใช้completeแทนsource. ทั้งหมดเข้าด้วยกัน:

autoload -Uz compinit && compinit
autoload -U +X bashcompinit && bashcompinit

complete -C /usr/local/bin/terraform terraform
complete -C /usr/local/aws/bin/aws_completer aws
complete -C /usr/local/bin/az az
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.