如何使 zsh globbing 忽略 .DS_Store 等文件

如何使 zsh globbing 忽略 .DS_Store 等文件

大多数时候,我喜欢(一方面)在 iTerm 中的 BSD 变体上运行 zsh,但(另一方面)为那些不运行或赚得不多的应用程序提供 macOS 体验感觉在终端中运行。

但让我发疯的一件事是.DS_StoremacOS 到处转储的可怕文件。

我是否可以配置 zsh,以便如果我输入(例如)nvim *tab*则展开该 zsh 而不包含我希望避免的任何文件? (这可能包括.DS_StoreIcon?,以及我现在无法想到的其他可能的内容。)

我不是问如何当场构建排除某些文件的模式(示例这里,这里, 和这里)但是我如何使所有的全局对象始终排除某些文件。

答案1

除了该选项之外,您无法自定义通配符本身dot_glob。这是 ATT ksh 和 bash 中存在但 zsh 中没有的少数功能之一。所以echo *总会表现出来Icon1

您可以在完成时忽略模式,但当涉及通配符时,情况会变得复杂。让我们从简单的事情开始:不涉及通配符的完成。对于以下.zshrc文件,除非没有匹配项,否则不会提供完成信息.DS_StoreIcon1

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命令,上面的代码片段定义了一个空的忽略列表,该列表覆盖默认值。
  • 它们适用于命令行上的任何位置。
  • 它们在收集文件名时适用(通过标签_files或标签_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.zshrcecho .*Tab.DOH.zshrc.DOH .DS_Store .zshrc.*ignored-patternsexpansions.DS_Storeall-expansionsignored-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

请注意,我只对该补丁进行了最低限度的测试。它可能会破坏其他东西。它可能在某些配置下不起作用。它可能无法正确引用文件名。

相关内容