可以让 zsh 向上箭头历史搜索检测别名吗?

可以让 zsh 向上箭头历史搜索检测别名吗?

我已经git别名为g.有时我使用g,有时不使用。

我可能会跑git add file1,稍后再跑g add file2

当我想再次添加 file1 时,我可能会g add在 zsh 提示符下键入,然后按向上箭头几次。我不会去git add file1。所以我必须尝试git add然后向上箭头。

同样,git add永远也找不到g add file2

这个感觉应该是可以解决的。有没有办法弥补箭头历史搜索检测别名?

答案1

这在反向搜索阶段实现起来会很复杂

alias g=grep
g foo /etc/passwd
alias g=git
g status

由于反向搜索需要知道别名已更改,因此如果通过配置文件编辑和 shell 重新启动来不可见地更改别名(对于历史搜索功能),则与上述示例不同的信息将不可用。

相反,将规范信息记录到 shell 历史记录中可能更合适(但仍然有些复杂),因此上述 shell 历史记录将根据命令执行时支持的别名扩展为 git 或 grep跑步。缺点:您需要自己管理历史记录,并且必须按命令名称而不是别名进行搜索:

function zshaddhistory() {
  local -a cmd
  local i
  # split using shell parse, see zshexpn(1)
  cmd=(${(z)1})
  if (( $#cmd )); then
    # alias expand or failing that the command
    # NOTE zsh is 1-indexed, not 0-indexed
    cmd[1]=${aliases[$cmd[1]]:-$cmd[1]}
    for (( i = 2 ; i < $#cmd ; i++ )); do
      # look for ; and try to alias expand word following
      if [[ $cmd[$((i-1))] == \; ]]; then
        cmd[$i]=${aliases[$cmd[$i]]:-$cmd[$i]}
      fi
    done
    # (z) adds a trailing ; remove that
    cmd[$#cmd]=()
    # write to usual history location
    print -sr -- $cmd
  fi
  # disable the usual history handling
  return 1
}
alias g='echo wait for godot'

加载后:

% exec zsh -l
% ls
...
% uptime
...
% g ; g
wait for godot
wait for godot
% history
    1  ls
    2  uptime
    3  echo wait for godot ; echo wait for godot
    4  history

这不支持全局别名,全局别名不仅可以出现在行的开头或之后;。该代码可能还有其他疏忽。

使用更多代码,您可以将原始代码包含为注释(可能带有选项INTERACTIVE_COMMENTS集),尽管这可能需要在历史搜索方面添加更多代码来删除这些注释:

    ...
    # (z) adds a trailing ; remove that
    cmd[$#cmd]=()
    cmd+=(\# ${1%%$'\n'})
    ...

这在某些时候可能需要您重写所有历史记录保存和历史记录搜索代码以满足您的特定需求。

相关内容