不要在製表符補全時展開通配符

不要在製表符補全時展開通配符

我想知道如何配置桀騁不是展開檔案名稱中的通配符。例如,我有一個包含數百個檔案的目錄,名稱如下:

a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo

我希望能夠執行製表符補全匹配通配符,所以

cat *.foo-< tab > => cat *.foo-bar

這就是我得到的:

$ 貓 *.foo-
=> 貓 a.foo-bar
   文件
   a.foo-bar b.foo-bar c.foo-bar

答案1

一種選擇是替換該TAB鍵的預設鍵綁定

bindkey "^I" expand-or-complete

bindkey "^I" complete-word

它不會將 a 擴展*到所有符合的文件,但不會影響星號。這樣你就擺脫了無盡的列表,但它仍然無法完成通配表達式。

要解決這個問題要棘手得多。你必須自己寫完成小部件(看man zshcompwid)。

  1. 讓我們從定義開始:

    zle -C complete-glob menu-complete compglob
    

    這引入了新的小部件完整的全局,其行為類似菜單完整並使用外殼函數 組合球產生匹配項。

    [注意:如果您不想完成選單,請使用更基本的選項完整的單字或者清單選擇]

  2. 將此新小部件綁定到方便的快捷方式,例如CTRL+K

    bindkey "^K" complete-glob
    

    不要將其綁定到TAB,因為當前形式的小部件僅完成文件!

  3. 定義外殼函數組合球如下,它執行實際工作:

    compglob () {
        setopt localoptions globsubst
        compset -P '*'
        files=(${IPREFIX}*) 
        display=(${files/${IPREFIX}/${(q)IPREFIX}}) 
        glob=(${files/${IPREFIX}/}) 
        compadd -d display -- $glob
    }
    
  4. 示範:

    $ touch a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo
    $ cat *.f<CTRL+K>
    $ cat *.foo
    \*.foo      \*.foo-bar
    

    我看到的唯一缺陷是\所提供清單中星星前面的。但這只是一個視覺缺陷,因為完成是正確的:*.foo*.foo-bar

答案2

我認為這是不可能的。您不僅要求 shell 找出您希望哪些檔案最終成為“根據通配符擴展有效”,而且還希望 shell 找出將擴展的“最佳”通配符表達式這邊走。我希望第二部分是 NP 完全的。

答案3

我還沒有看到一種方法可以讓你得到你想要的東西,但是你可以通過setopt GLOB_COMPLETE(這只會給你一個擴展,然後您可以通過選項卡瀏覽它們...或再次編輯該內容*,這至少可能是一個小小的改進)。

您也可以在man zshoptionsman zshcompctlman zshcompwid/或類似內容中進行挖掘。 zsh 的完成工作非常複雜,所以我猜很可能有一種方法可以做到這一點。

另請注意,一個有點相關的問題:

如何讓 zsh 的自動完成功能像 bash 一樣完成通配符?

相關內容