终端bash&zsh中实现基于前缀的历史命令搜索

背景

之前使用 zsh + oh-my-zsh 时,比较喜欢通过方向键,实现基于前缀的历史命令搜索,快速调取之前输入过的命令,还可以基于以前输入过的命令进行修改。原生的方向键只能按时间顺序调取历史命令,有时候要翻很久才行。

后来觉得 oh-my-zsh 装的插件多了每次打开新的shell变得很慢,就不想安装了,至于主题开始使用 starship ,那么对我来说剩下的就只有这个调用历史命令的功能了。

zsh 配置

前面提到我将以前的 zsh + oh-my-zsh 方案换成了 ,zsh + starship 。调用历史命令的功能之前是 oh-my-zsh 带进来的,现在需要自己在 .zshrc 中实现一下。方法很简单,.zshrc 中添加如下内容即可。

bash 复制代码
# 自动加载历史搜索功能
autoload -Uz history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "$terminfo[kcuu1]" history-beginning-search-backward-end
bindkey "$terminfo[kcud1]" history-beginning-search-forward-end

bash 配置

bash 这边配置麻烦点,主要是网上查找的资料如下:

  1. 创建 ~/.inputrc 文件,内容如下

    bash 复制代码
    # 保留系统级默认配置(Home/End/Delete、Ctrl+左右箭头移词等)
    $include /etc/inputrc
       
    # 上/下箭头:基于前缀历史搜索(readline 原生;无法连续翻/光标到行尾,仅作非 bash 程序兜底)
    "\e[A": history-search-backward
    "\e[B": history-search-forward

    如果只到这一步的话,虽然可以实现基于前缀历史搜索,但是搜索到历史命令后,光标位置不会自动到行尾,对于需要基于搜索到的历史命令进行修改的话,还需要手动执行 ctrl+e 跳转到行尾,不太方便。因此,本方案继续执行以下操作,可解决该问题

  2. 编辑 ~/.bashrc ,追加以下内容

    bash 复制代码
    # 上/下箭头:前缀历史搜索 + 光标自动到行尾(复刻 zsh 的 history-search-end)
    # 背景:readline 原生 history-search-backward 无法"记住前缀"连续翻动(光标到行尾后
    # 前缀就变成整条命令,只能匹配一次)。这里用 bind -x 自定义 widget,
    # 手动维护 {前缀, 历史游标} 状态,实现连续按 ↑/↓ 在以该前缀开头的历史间翻动。
    __hse_search() {
        local dir="$1" i target=""
        local HISTTIMEFORMAT=
        local -a cmds
        mapfile -t cmds < <(history | sed -E 's/^ *[0-9]+ +//')
        local n=${#cmds[@]}
    
        # 连续翻动(上次也是本搜索且行未改动)则沿用保存的前缀与游标,否则重新起始
        if [[ ${__hse_active:-0} == 1 && $READLINE_LINE == "${__hse_line:-}" ]]; then
            :
        else
            __hse_prefix="${READLINE_LINE:0:$READLINE_POINT}"
            [[ $dir == back ]] && __hse_idx=$n || __hse_idx=-1
        fi
    
        if [[ $dir == back ]]; then
            for ((i=__hse_idx-1; i>=0; i--)); do
                [[ ${cmds[i]} == "$__hse_prefix"* ]] && { target=${cmds[i]}; __hse_idx=$i; break; }
            done
        else
            for ((i=__hse_idx+1; i<n; i++)); do
                [[ ${cmds[i]} == "$__hse_prefix"* ]] && { target=${cmds[i]}; __hse_idx=$i; break; }
            done
        fi
    
        [[ -n $target ]] && READLINE_LINE="$target"
        READLINE_POINT=${#READLINE_LINE}     # 光标移到行尾,便于增删改
        __hse_line="$READLINE_LINE"
        __hse_active=1
    }
    __hse_up()   { __hse_search back; }
    __hse_down() { __hse_search fwd; }
    bind -x '"\e[A": __hse_up'
    bind -x '"\e[B": __hse_down'
相关推荐
2401_858286111 小时前
OS81.【Linux】基于环形队列的多生产者-多消费者模型
linux·运维·服务器·环形队列
行者-全栈开发2 小时前
【Linux内核】CVE-2026-46242:Bad Epoll Linux 内核 epoll UAF 漏洞修复指南(99%可靠root的云安全噩梦)
linux·运维·服务器·cve-2026-46242·linux内核漏洞·use-after-free·云多租户安全
信鸽爱好者3 小时前
一人多台电脑办公模式:windows 电脑A远程桌面操作ubuntu电脑B
linux·运维·ubuntu
木由里予3 小时前
TEE(Trusted Execution Environment)技术详解
java·linux·开发语言·网络·嵌入式硬件·android-studio
开开心心_Every3 小时前
电脑文件搜索软件支持内容和拼音搜索
linux·服务器·人工智能·r语言·pdf·音视频·symfony
国产化创客3 小时前
Kindle --FBInk绘图与zforce2 触摸应用开发
linux·物联网·智能家居·智能硬件
宵时待雨3 小时前
linux笔记归纳13:Socket编程UDP
linux·服务器·笔记·udp
bksczm3 小时前
Linux之应用层层协议认知(TCP协议编程模块化demo) —— 兼论守护进程机制
linux·运维·服务器
爱和冰阔落4 小时前
【Linux】从匿名管道到进程池:任务派发、fd 继承 Bug 与完整实现
android·linux·运维·c++