如何使用已在 zsh 中的提示处输入的文本来搜索历史记录?

Sea*_*sey 81 command-history zsh search

在 zsh 中,我知道我可以使用Ctrl+搜索历史记录r。然而,我经常开始直接在提示符下键入命令,但随后意识到我应该搜索历史记录。当我点击Ctrl+ 时r,它会显示一个空白的历史搜索提示,如下所示:

历史搜索提示未预填

请注意我的提示中有文本,但历史搜索提示中没有。如何使用提示中已有的文本开始历史搜索,如下所示:

历史搜索提示预填

jas*_*yan 79

您可以使用zle 的history-search功能:

bindkey "^[[A" history-beginning-search-backward
bindkey "^[[B" history-beginning-search-forward
Run Code Online (Sandbox Code Playgroud)

这将绑定Up并Down(根据您自己的转义序列进行调整)到历史搜索,根据提示中已经输入的内容向后和向前。

因此,如果您要输入“vim”并点击Up,zsh 将仅针对以“vim”开头的那些命令向后遍历您的历史记录。

你还可以有光标放置在该行的结束,一旦你从zsh的历史通过选择您所需的命令历史记录的搜索端功能(通常位于/usr/share/zsh/functions/Zle/)和附加-end到每一行的末尾,就像这样:

autoload -U history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^[[A" history-beginning-search-backward-end
bindkey "^[[B" history-beginning-search-forward-end
Run Code Online (Sandbox Code Playgroud)

  • @hanielabed Oh-my-Zsh 是一个 clusterfsck;我一点也不惊讶它会破坏像历史搜索这样基本的东西...... (2认同)
  • 这在 macOS 上不起作用。我需要使用 `bindkey "$terminfo[kcuu1]" History-beginning-search-backward-end` 并使用下面 zzxyz 的建议。 (2认同)

Mic*_*ant 27

另一个有用的选择是 history | grep

分配一个别名,例如

alias hg='history | grep'
Run Code Online (Sandbox Code Playgroud)

然后您可以键入hg whatever以搜索您使用过的命令,例如

$ hg chmod                                                                                                       
 1309  chmod +x rotate_files.sh 
 1385  chmod +x rotate_files_270.sh 
 1512  chmod +x testy.sh 
 1528  chmod +x act_on_2_numbers.sh 
 2142  chmod +x ~/bin/display_tmux_pane_pwd.sh
 4532  chmod +x cat_files.rb 
Run Code Online (Sandbox Code Playgroud)

我把这个别名放在我的点文件中。

  • `hg` 让我想起了什么......哦,是的,Mercurial! (30认同)
  • 该别名可能应该更新为使用 zsh **full** 历史命令 `history 1` (否则它只会 grep 最近 15 个历史记录项) - 请参阅:/sf/ask/1879271691/ zsh 历史太短 (4认同)
  • `Hg` 提醒我什么?嗯,汞,原子序数为80的元素。也叫水银,让我想起了https://en.wikipedia.org/wiki/Quicksilver_(software) (3认同)

joe*_*lom 20

如果您正在使用oh-my-zsh,请添加history-substring-search到该plugins=(...)行。

然后加

bindkey "^[[A" history-substring-search-up
bindkey "^[[B" history-substring-search-down
Run Code Online (Sandbox Code Playgroud)

读source $ZSH/oh-my-zsh.sh. 保存并启动新终端或source ~/.zshrc在当前终端中运行。

注意: ^[[A是我使用的终端(kitty)和许多其他终端中向上箭头的转义序列。要签入您选择的终端,请输入showkey -a,然后按您要为其查找转义序列的键。

  • +1 了解“showkey”!这应该是一个常识。我是如何在没有它的情况下生存了 10 多年(包括在 vim 中度过的时间)? (3认同)
  • 子字符串搜索是最好的,它是命令的超集。为了在不是 oh-my-zsh 用户的情况下实现我做了`brew install zsh-history-substring-search`,检查了回购自述文件的说明,我会继续创建一个答案我对结果非常满意. (2认同)

小智 11

我强烈建议使用"$terminfo[kcuu1]"or"$key[Up]"而不是硬编码的东西,比如"^[[A"可能在任何特定系统上工作也可能不工作的东西。

查看/etc/zsh/zshrc更多密钥。这是它在我的系统上的样子。我认为terminfo键更有可能被定义。

key=(
    BackSpace  "${terminfo[kbs]}"
    Home       "${terminfo[khome]}"
    End        "${terminfo[kend]}"
    Insert     "${terminfo[kich1]}"
    Delete     "${terminfo[kdch1]}"
    Up         "${terminfo[kcuu1]}"
    Down       "${terminfo[kcud1]}"
    Left       "${terminfo[kcub1]}"
    Right      "${terminfo[kcuf1]}"
    PageUp     "${terminfo[kpp]}"
    PageDown   "${terminfo[knp]}"
)
Run Code Online (Sandbox Code Playgroud)

  • 有或没有并不重要。当有可读的定义或宏来消除猜测时,请使用它们。 (2认同)

num*_*er5 8

您可能想使用https://github.com/zsh-users/zsh-history-substring-search 上的脚本

您可以在其中键入任何先前输入的命令的任何部分,然后按Up和Down键循环显示匹配的命令。


Ser*_*ujo 7

怎么用zsh-autosuggestions?

问题是,对于您键入的每个命令,此插件都会向您显示一些可以接受或不接受的建议。尝试一下并给我们一些反馈。

在没有插件的情况下,我们可以按下Ctrlr对历史进行反向搜索,一旦您开始输入匹配的命令,就会显示为建议。


小智 6

现有的答案都不会像所提出的问题一样,开始对迄今为止输入的内容进行增量搜索。这实际上是可能的:

_history-incremental-search-backward () {
    zle .history-incremental-search-backward -- $BUFFER
}
zle -N history-incremental-search-backward _history-incremental-search-backward

# this line is actually not necessary since this is default.
bindkey '^R' history-incremental-search-backward
Run Code Online (Sandbox Code Playgroud)
  • 我们创建一个自定义 zle 小部件来包装history-incremental-search-backward并传递$BUFFER包含到目前为止输入的 zsh 提示内容的变量。然后,您可以继续在迷你缓冲区中输入内容以进一步缩小搜索范围。

在小部件之后命名函数可以让我们简化代码:

history-incremental-search-{back,for}ward() zle .$WIDGET -- $BUFFER
zle -N history-incremental-search-backward
zle -N history-incremental-search-forward
Run Code Online (Sandbox Code Playgroud)

(这里也扩展为前向搜索也这样做)

$BUFFER扩展到编辑缓冲区的全部内容,$LBUFFER如果您只想根据光标左侧的内容进行搜索,请替换为。

截图

  • 开始输入命令

    在此输入图像描述

  • 意识到您想要在历史记录中搜索,请按 Ctrl-R,打开一个迷你缓冲区并填充命令行的内容。因此,它首先匹配刚刚输入的命令行:

    在此输入图像描述

  • 再次按 Ctrl-R,它会匹配上一个命令,Tab 或 Ctrl-E 接受结果。

    在此输入图像描述

  • 或继续输入以进一步细化搜索

    在此输入图像描述

为了避免在当前缓冲区上第一次向后搜索匹配,我们可以在调用原始搜索小部件之前清空缓冲区,并在失败时恢复它:

history-incremental-search-{back,for}ward() {
  local saved_BUFFER=$BUFFER saved_CURSOR=$CURSOR error
  BUFFER=
  zle .$WIDGET -- $saved_BUFFER
  error=$?
  if (( error )) BUFFER=$saved_BUFFER CURSOR=$saved_CURSOR
  return error
}
zle -N history-incremental-search-backward
zle -N history-incremental-search-forward
Run Code Online (Sandbox Code Playgroud)