Zsh

如何讓 zsh globbing 忽略 .DS_Store 之類的文件

  • March 7, 2022

大多數時候,我喜歡(一方面)在 iTerm 的 BSD 變體上執行 zsh 的組合,但(另一方面)讓 macOS 體驗可用於不執行或不生產的應用程序感覺在終端中執行。

但讓我發瘋的一件事是.DS_StoremacOS 到處轉儲的可怕文件。

我可以配置 zsh 以便如果我鍵入(例如)nvim *``tab*擴展 而不包括我希望避免的任何文件?(這可能包括.DS_Store,Icon?以及我現在想不到的其他可能。)

我不是在問如何在現場建構一個排除某些文件的模式(範例hereherehere),而是如何讓所有 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完成者,您需要綁定Tabcomplete-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_Storeecho .* Tab.

請注意,我只對這個更新檔進行了最低限度的測試。它可能會破壞其他東西。它可能不適用於某些配置。它可能無法正確引用文件名。

引用自:https://unix.stackexchange.com/questions/693084