題 為什麼“tag-order”樣式中的值' - '(連字符)會阻止匹配“executables”標記,即使明確指定了該標記?


使用下面的代碼,一切都按預期工作:

  • 當我寫作 c 然後打了 TAB 鍵,我按正確的順序得到適當的完成。

    Image 

  • 當我寫作 ./ 然後打了 TAB 關鍵,我完成了 executables 標籤。

    Image


# Always use menu selection when using unambiguous completions.
zstyle ':completion:*:*:*:*:*' menu 'select'

# Show only completions.
zstyle ':completion:*:*:*:*:*' completer _complete

# Group name becomes the name of the matching tag.
zstyle ':completion:*:*:*:*:*' group-name ''

# Configure the order of tag matching as well as their descriptions.
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            functions:Functions:Functions
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords"
          )
'

# Configure the order in which completion groups will be shown.
zstyle ':completion:*:*:-command-:*:*' group-order 'Executables' 'Builtins' 'Commands' 'Aliases' 'Functions' 'Variables' 'Keywords'

# Configure the format for each group/tag description.
zstyle ':completion:*:*:*:*:descriptions' format $'%{\e[0;38;2;0;0;0;48;2;200;150;0m%} %d %{\e[0;38;2;200;150;0;48;2;0;0;0m%}%{\e[0m%}'

# Initialize completion system.
autoload -Uz compinit && compinit

但是,如果我指定的標籤沒有產生任何完成,那麼也會嘗試其他標籤。

證明這一點的最簡單方法是排除 functions 標籤來自 tag-order 樣式:

zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords"
          )
'

然後創建具有唯一前綴的2個函數:

function unique_prefix_A() { }
function unique_prefix_B() { }

現在我寫的時候 unique_prefix_ 然後打了 TAB 關鍵,我不希望看到任何事情 functions 標籤已被刪除 tag-order
但是,因為 ExecutablesBuiltinsCommandsAliasesVariables 和 Keywords 沒有提供任何完成, zsh 默認情況下會嘗試匹配其他標記,即排除 functions 標籤,試圖給任何完成。

正因為如此,功能 unique_prefix_A 和 unique_prefix_B 將被建議:

Image

我不喜歡這種行為,並且只想將搜索限制為我明確指定的標籤。

手冊為 標籤階 style提出了一個簡單的解決方

- 如果任何值僅由連字符組成,則僅生成在其他值中指定的標記。通常,如果指定的標記無法生成任何匹配項,則最後會嘗試所有未明確選擇的標記。這意味著僅由單個連字符組成的單個值將關閉完成。

應用解決方案:

# Configure the order of tag matching as well as their descriptions.
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            functions:Functions:Functions
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords"
           "-"
          )
'

目前的行為是:

  • 當我寫作 c 然後打了 TAB 鍵,我按正確的順序得到適當的完成。

    Image

  • 當我寫作 ./ 然後打了 TAB 關鍵,我一無所獲。

    Image


為什麼現在只 executables 標籤不工作?

我該如何解決它並獲得所需的行為?


4
2018-05-05 04:56


起源


更新了我的答案,希望這是你想要的。 - Miguel Ortiz


答案:


executable 標籤調用 _files -g '*(-*) 在這種情況下。然後 _files 打電話更多 _tags,所以有必要指定這些 完成函數中隱式指定的標記也是。

zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            functions:Functions:Functions
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords
            globbed-files directories"
           "-"
          )
'

添加會很有用 globbed-files 和 directories 在這種情況下:

% ls -al
total 80
drwxr-xr-x  3 t    t     4096 May 18 08:27 .
drwxrwxrwt 16 root root 69632 May 18 15:27 ..
drwxr-xr-x  2 t    t     4096 May 18 08:27 directory
-rwxr-xr-x  1 t    t        0 May 18 08:27 executable-file
-rw-r--r--  1 t    t        0 May 18 08:27 test
% ./<TAB>
Executables
directory/        executable-file*

但是在上面的設置中,目錄和本地可執行文件將進入相同的“可執行”組。如果我們想讓“目錄”進入其他組,我們可以指定 file-patterns 直接使用它:

zstyle ':completion:*:*:-command-:*:*' file-patterns \
 '*(#q-*):executables:Executables *(-/):directories:Directories'

zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            functions:Functions:Functions
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords
            directories:Directories"
            -
          )
'

在下面的示例中,“directory”和“executable-file”位於分隔的組中:

% ls -al
total 80
drwxr-xr-x  3 t    t     4096 May 18 08:27 .
drwxrwxrwt 15 root root 69632 May 18 15:24 ..
drwxr-xr-x  2 t    t     4096 May 18 08:27 directory
-rwxr-xr-x  1 t    t        0 May 18 08:27 executable-file
-rw-r--r--  1 t    t        0 May 18 08:27 test
% ./<TAB>
Executables
executable-file*
Directories
directory/

下面是最小的.zshrc示例:

autoload -Uz compinit && compinit
zstyle ':completion:*:*:*:*:*' group-name ''
zstyle ':completion:*:descriptions' format '%B%F{black}%d%f%b'
zstyle ':completion:*:*:*:*:*' menu 'select'

# This comment out block is just for a reminder of my answer's first half.
# zstyle -e ':completion:*:*:-command-:*:*' tag-order '
#       reply=(
#                    "executables:Executables:Executables
#                       builtins:Builtins:Builtins
#                       commands:Commands:Commands
#                       aliases:Aliases:Aliases
#                       functions:Functions:Functions
#                       parameters:Variables:Variables
#                       reserved-words:Keywords:Keywords
#                       globbed-files directories"
#                    "-"
#                   )
# '

zstyle ':completion:*:*:-command-:*:*' file-patterns \
 '*(#q-*):executables:Executables *(-/):directories:Directories'

zstyle -e ':completion:*:*:-command-:*:*' tag-order '
    reply=(
           "executables:Executables:Executables
            builtins:Builtins:Builtins
            commands:Commands:Commands
            aliases:Aliases:Aliases
            functions:Functions:Functions
            parameters:Variables:Variables
            reserved-words:Keywords:Keywords
            directories:Directories"
            -
          )
'

更新:註釋掉不必要的塊。


2
2018-05-18 04:12



感謝您提供的鏈接!我把這個答案複製給了他們。 - hchbaw
你能不能試著解釋一下 .zshrc 更詳細一點?當然,尚不清楚的部分是為什麼我們需要有2個 tag-order 定義。為什麼它不能只用1 file-patterns 和1 tag-order 定義? - Iskustvo
實際上,我已經設法讓它只用一個 tag-order: zstyle -e ':completion:*:*:-command-:*:*' tag-order 'reply=("executables:Executables:Executables builtins:Builtins:Builtins commands:Commands:Commands aliases:Aliases:Aliases functions:Functions:Functions parameters:Variables:Variables reserved-words:Keywords:Keywords directories:Directories:Directories" "-")' 然後 zstyle ':completion:*:*:-command-:*:*' file-patterns '*(#q-*):executables:Executables:Executables *(-/):directories:Directories:Directories'。據我所知,這很好,你看到有什麼問題嗎? - Iskustvo
沒問題!我已經更新了;在我的回答中註釋掉不必要的塊。我想現在,由於你的建議,現在會更清楚了! - hchbaw


我認為問題不僅在於(連字符),而在於您對自動完成規則的具體了解。

我運行了一些測試,例如,刪除 '變量' 來自訂單標籤並在shell中創建(TEST,LOLO)。

在那之後,我嘗試了自動完成,期望看不到任何東西,但是在“變量”中列出它們,它們顯示為“參數”。

這種行為讓我想到了UDEV以及某些系統如何針對某些行為需要非常具體的規則。

您的標記匹配組是正常的並且按預期工作(在./方案中),但有一件事是執行:

./<TAB>

完全不同的是自動完成類似的東西:

unique_prefix<TAB>

因此,無論您在這些組中添加多少個連字符,它都無效,因為它是一個不同的規則執行。

而不是處理那個我已經搜索了一個例子,以避免具體的功能,這個片段工作得很好(檢查來源):

這些功能的一個用途是不止一次嘗試一個標籤,設置   其他款式在每次嘗試時都有所不同,但仍然要使用全部   其他標籤,而不必重複所有。例如,要做   在命令位置完成函數名稱忽略所有   第一次以下劃線開頭的完成函數   嘗試完成:

(我改變了這個以匹配所有功能):

ignored-patterns ’_*’   

為了這:

ignored-patterns ’*’

在這條規則中:

zstyle ’:completion:*:*:-command-:*:*’ tag-order \
    ’functions:-non-comp *’ functions
zstyle ’:completion:*:functions-non-comp’ \
    ignored-patterns ’*’

當我嘗試自動完成時:unique_prefix(沒有任何反應)和./執行效果很好。

因此,答案是:您將需要針對每個不同場景的特定規則,記住根據您定義的規則,任何模式都可以被解釋為不同。


1
2018-05-17 16:51



首先,謝謝你的努力。第一張圖片的鏈接無效,但我認為這與此無關。您使用的代碼和您描述的行為與我原來的情況完全一樣,或者我錯了?我之前沒有停下來的原因是因為如果我指定的標籤沒有匹配,那麼列表中會提供其他一些完成。我不希望這樣。因此,我需要找到一種方法在標記順序列表中添加“ - ”以刪除其他完成並僅保留顯示的指定標記。 - Iskustvo
我已經更新了這個問題,希望它會對你有所幫助。 - Iskustvo
對不起,這不是真正的答案,只是建議(我很欣賞)。關於 Variables 和 parameters,我覺得這跟我的例子一樣 Functions。完成與指定的任何內容都不匹配,沒有 - 阻止它嘗試匹配任何東西,以便它匹配變量。唯一的區別是該標籤的默認描述是 paramters 的人 Variables 我重新定義了。 - Iskustvo
因此,您需要針對所有情況的分組規則,例如每次完成的通用規則,而不考慮shell中的模式,對吧?因此,通過這種方式,您將在一個規則中準確定義您想要的內容而不是其他內容。 - Miguel Ortiz
沒關係,看到了答案,我正在尋找如何定義它! :)很高興你得到了答案。 - Miguel Ortiz