如何讓 zsh globbing 忽略 .DS_Store 之類的文件
大多數時候,我喜歡(一方面)在 iTerm 的 BSD 變體上執行 zsh 的組合,但(另一方面)讓 macOS 體驗可用於不執行或不生產的應用程序感覺在終端中執行。
但讓我發瘋的一件事是
.DS_Store
macOS 到處轉儲的可怕文件。我可以配置 zsh 以便如果我鍵入(例如)
nvim *``tab
,*
擴展 而不包括我希望避免的任何文件?(這可能包括.DS_Store
,Icon?
以及我現在想不到的其他可能。)我不是在問如何在現場建構一個排除某些文件的模式(範例here、here和here),而是如何讓所有 glob 始終排除某些文件。
dot_glob
除了選項之外,您不能自定義 globbing 本身。這是 ATT ksh 和 bash 中存在但 zsh 中不存在的少數功能之一。所以echo *
會一直顯示Icon1
。您可以忽略完成中的模式,但是當涉及萬用字元時它會變得複雜。讓我們從簡單的事情開始:不涉及萬用字元的補全。使用以下
.zshrc
, 文件喜歡.DS_Store
並且Icon1
除非沒有其他匹配項,否則不會提供完成。autoload -zU compinit compinit zstyle ':completion::complete:*:*:files' ignored-patterns '.DS_Store' 'Icon?' zstyle ':completion::complete:*:*:globbed-files' ignored-patterns '.DS_Store' 'Icon?' zstyle ':completion::complete:rm:*:globbed-files' ignored-patterns
說明:我定義完成樣式:
- 他們在完成時適用。
- 它們適用於“功能”為空的情況(這不包括一些特殊的小元件)。
- 它們適用於進行普通補全 (
_complete
),而不是例如更正或_ingore
。- 它們適用於除
rm
. 對於該rm
命令,上面的程式碼片段定義了一個空的忽略列表,它會覆蓋預設值。- 它們適用於命令行上的任何位置。
- 它們適用於收集文件名(通過 tag
_files
或 tag_globbed-files
)。這些樣式不適用於萬用字元擴展。預設情況下,萬用字元擴展
Tab
會繞過完成程式碼。要使其使用完成程式碼,特別是_expand
完成者,您需要綁定Tab
並complete-word
使用_expand
使用expansions
標籤的完成者。autoload -zU compinit compinit bindkey '^I' complete-word zstyle ':completion:::::' completer _expand _complete _ignored zstyle ':completion::expand:*:*:expansions' ignored-patterns '.DS_Store' 'Icon?' zstyle ':completion::expand:*:*:all-expansions' ignored-patterns '.DS_Store' 'Icon?'
這樣,在包含和的
.zshrc
目錄中,.DOH
循環通過、和。由於標籤上的樣式,在循環瀏覽單個擴展時會被忽略。當擴展到匹配列表時,有一個標籤適用,但不幸的是它不支持. (實際上,它確實如此,但以一種無用的方式:它可用於刪除整個匹配列表,而不是從中刪除單個元素。).DS_Store``.zshrc``echo .*``Tab``.DOH``.zshrc``.DOH .DS_Store .zshrc``.*``ignored-patterns``expansions``.DS_Store``all-expansions``ignored-patterns
我發現從所有擴展列表中過濾掉匹配項的唯一方法是修補
_expand
函式。diff --git a/Completion/Base/Completer/_expand b/Completion/Base/Completer/_expand index e5e4f9b39..df6f55a7d 100644 --- a/Completion/Base/Completer/_expand +++ b/Completion/Base/Completer/_expand @@ -107,7 +107,13 @@ subd=("$exp[@]") integer done_quote local -a orig_exp=( $exp ) if [[ "$force" = *g* ]] || zstyle -T ":completion:${curcontext}:" glob; then - eval 'exp=( ${~exp//(#b)\\([ \"'"\'"' + local -a exps igns + exps=($~exp) + zstyle -a ":completion:${curcontext}:all-expansions" ignored-patterns igns + if (($#igns)); then + eval "exps=(\${exps:#(${(j:|:)igns})})" + fi + eval 'exp=( ${exps//(#b)\\([ \"'"\'"' ])/$match[1]} ); exp=( ${(q)exp} )' 2>/dev/null && (( $#exp )) && done_quote=1 fi # If the globbing failed, or we didn't try globbing, we'll do
有了這個更新檔和
.zshrc
上面的更新檔,all-expansions
標籤確實會.DS_Store
被echo .*
Tab
.請注意,我只對這個更新檔進行了最低限度的測試。它可能會破壞其他東西。它可能不適用於某些配置。它可能無法正確引用文件名。