【问题标题】:How to add entry to fish shell history?如何在鱼壳历史中添加条目?
【发布时间】:2015-06-12 23:31:34
【问题描述】:

在我的 fish 函数中,我正在评估构造的命令行 eval (commandline),特别是 - 我正在从 fzf 中寻找一些文件名,然后分析命令行是否以 vim 开头。如果是 - 而不是返回 vim filename 之后按回车,我只是评估它,就像我之前展示的那样。

问题是,如果我评估它,而不是手动按 Enter,它不会进入历史记录 - 例如按向上看,我看不到它是以前的命令。

我在评估后尝试了set -x history (commandline) $history,但它显示错误set: Tried to change the read-only variable “history”

有没有办法手动将自定义字符串(在我的例子中是命令行缓冲区)添加到历史记录中?谢谢。

【问题讨论】:

    标签: fish


    【解决方案1】:

    history --merge 不按时间顺序合并历史记录#2312。因此,即使我们手动将命令添加到~/.config/fish/fish_history,我们也无法简单地按下来查看它(尽管如果按下得足够多,您最终会看到它)。

    为了解决这个问题,我们可以复制fish_history,然后调用builtin history --clear,这将清除fish 的内部历史和历史文件。然后我们从我们的副本中恢复历史文件,附加我们的命令并调用history --merge 以将历史文件与现在为空的内部历史合并。

    function evalh
        eval $argv
    
        # backup history file
        cp ~/.config/fish/fish_history /tmp/fish_history.tmp
    
        # clear internal history and history file (using builtin means we don't get a prompt)
        builtin history --clear
    
        # restore history file
        cp /tmp/fish_history.tmp ~/.config/fish/fish_history
    
        # append our command 
        echo "- cmd:" $argv >> ~/.config/fish/fish_history
        echo "  when:" (date "+%s") >> ~/.config/fish/fish_history
    
        # merge history file with (empty) internal history
        history --merge
    end
    

    【讨论】:

    • 我确信有更好的方法可以做到这一点,因此我在问题中添加了赏金
    【解决方案2】:

    您可以使用commandline 上的-f 选项而不是使用eval 来注入readline 函数——特别是execute。

    例如,我编写了一个函数substitute,它执行与 bash 的 ^foo^bar 语法类似的操作:

    function substitute
        set -l last $history[1]
        switch (count $argv)
            case 3
                if test $argv[3] = 'g'
                    commandline (echo $last | sed "s/$argv[1]/$argv[2]/g")
                    commandline -f execute
                else
                    echo "Syntax: substitute <find> <replace> [g]"
                end
            case 2
                commandline (echo $last | sed "s/$argv[1]/$argv[2]/")
                commandline -f execute
            case '*'
                echo "Syntax: substitute <find> <replace> [g]"
        end
    end
    

    在我的config.fish 中别名为s:

    alias s substitute
    

    用法如下(手动按下 Enter 键被替换为 ⏎ 字符):

    ~> echo hi hi hi⏎
    hi hi hi
    ~> s hi bye⏎
    ~> echo bye hi hi
    bye hi hi
    ~> s hi bye g⏎
    ~> echo bye bye bye
    bye bye bye
    

    请注意,虽然这里不能显示,但substitute 以这种方式创建的命令行没有语法高亮显示。

    s foo bar 行在此上下文中也会出现在您的历史记录中,这可能是一个错误或一个功能。我认为它是一个特性,所以没有费心去修复它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 2015-01-03
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      相关资源
      最近更新 更多