ใน zsh (รวมถึง bash) คุณสามารถใช้การขยายคำประวัติเพื่อแสดงถึงอาร์กิวเมนต์จากคำสั่งก่อนหน้า
ตัวอย่างนี้แสดงการรับพารามิเตอร์ที่ 2 จากคำสั่งก่อนหน้าในประวัติที่มี!:#
การขยาย:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
ฉันมักจะลืมสิ่งที่ # พารามิเตอร์อาร์กิวเมนต์เฉพาะคือและการพิมพ์!:#
ไม่เสมอว่ารวดเร็วเมื่อฉันจำได้ว่ามันขัดแย้ง ฉันรู้ว่าmeta-.
จะแทนที่อาร์กิวเมนต์สุดท้าย แต่บางครั้งก็ไม่ใช่อาร์กิวเมนต์สุดท้ายที่ฉันต้องการ
ฉันต้องการเพิ่มข้อโต้แย้งจากคำสั่งก่อนหน้าเป็นข้อเสนอแนะเพื่อดำเนินการคำสั่งใด ๆ ที่ฉันพิมพ์ใน zsh
ฉันสามารถหาวิธีสร้างฟังก์ชันเชลล์ที่สามารถสร้างอาร์เรย์ของอาร์กิวเมนต์ (0..N) จากคำสั่งสุดท้ายและผูกเข้ากับคำสั่งเฉพาะ
_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
}
# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo
นี่คือสิ่งที่ดูเหมือนว่าจะเสร็จสิ้นเพียงแค่ foo ที่ฉันกดปุ่มแท็บที่<TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
นี่ใช้งานได้ดีสำหรับการทำคำสั่ง "foo" ให้สมบูรณ์ แต่ฉันต้องการให้ตัวเลือกเหล่านี้เป็นตัวเลือกสำหรับการขยาย zsh ที่ฉันทำ ฉันคิดว่ามันมีบางอย่างที่เกี่ยวข้องกับสิ่งที่คอมไพล์เตอร์ของ zstyle แต่หลังจากผ่านไปสองสามชั่วโมงของการแฮ็ครอบ ๆ ฉันก็รู้ว่าฉันไม่ได้อยู่ลึก
ฉันจะรับอาร์กิวเมนต์จากคำสั่งก่อนหน้าของฉันเป็นความสมบูรณ์ที่แนะนำสำหรับคำสั่งใด ๆ ใน zsh ได้อย่างไร
ฉันมีไฟล์เต็มรูปแบบของzshrc ที่ฉันได้ติดตั้งร่วมกันบน bitbucket ถ้ามันช่วยได้ มันมีเปลมากมายจากแหล่งที่มาที่หลากหลายและบางส่วนที่ฉันได้แฮ็กด้วยกัน
UPDATE:
คำตอบของ @Julien Nicoulaud ทำให้ฉันสนิทฉันทำเครื่องหมายว่ายอมรับได้เพราะทำให้ฉันได้รับในที่ที่ฉันต้องการ
ด้วยการตั้งค่าเฉพาะของฉันโดยใช้สิ่งที่แนะนำ:
zstyle ':completion:*' completer _last_command_args _complete
ไม่ได้ผลสำหรับฉันเนื่องจากมันทำให้แท็บเสร็จสมบูรณ์เพื่อแสดงรายการอาร์กิวเมนต์จากคำสั่งสุดท้ายเท่านั้น (แม้ว่าจริง ๆ แล้วมันจะเสร็จสมบูรณ์ด้วยชื่อไฟล์เช่นกัน การเปลี่ยนคำสั่งซื้อ_complete _last_command_args
เป็นแบบย้อนกลับ มันจะแสดงชื่อไฟล์ปกติ แต่ไม่ใช่ last_command_args
ฉันคาดเดาว่าสิ่งนี้เกี่ยวข้องกับวิธีที่คอมไพเลอร์ทำงานได้ ฉันคิดว่ามันจะแสดงผลลัพธ์จากวิธีแรกที่กลับมาสำเร็จ แต่ฉันมีปัญหาในการแยกวิเคราะห์แหล่ง zsh เพื่อทำความเข้าใจอย่างสมบูรณ์ว่าเกิดอะไรขึ้น ฉันสามารถปรับแต่งวิธีการของฉันเพื่อรวมการเรียกไป_complete
เพื่อให้มันแสดงทั้งคำสั่งอาร์กิวเมนต์ล่าสุดเช่นเดียวกับสิ่งที่เติมข้อความอัตโนมัติปกติ ไม่ค่อยแยกกัน แต่ทำงานได้ดีพอสำหรับฉัน
นี่คือฟังก์ชั่นเต็มรูปแบบที่ฉันใช้พร้อมกับสิ่ง zstyle อื่น ๆ ที่ฉันมี:
# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
_complete
}
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1 # Because we didn't really complete anything
}
zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate
เส้น zstyle อื่น ๆ ที่ฉันมีไม่จำเป็นสำหรับการทำงาน แต่อาจส่งผลต่อสาเหตุที่ทำให้ฉัน:
zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
ตอนนี้ถ้าฉันอยู่ในไดเรกทอรีด้วยfile1.txt
และfile2.txt
และคำสั่งสุดท้ายของฉันคือecho foo bar baz
ฉันได้รับมันสำหรับการเติมข้อความอัตโนมัติซึ่งเป็นเพียงสิ่งที่ฉันต้องการ:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
( insert-last-word
) ผมชอบที่รอบระหว่างคำของเส้นเข้าถึงได้โดยcopy-earlier-word
insert-last-word
สำหรับคุณ.zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word