在我的鱼功能中,我正在评估构造的命令行
eval (commandline)
,具体来说 - 我正在寻找fzf中的一些文件名,然后分析命令行是否附加在vim
之前。如果是 - 而不是之后返回vim filename
按下输入,我只是评估它,正如我之前所示。
问题在于,如果我对它进行评估,而不是手动输入,则不会进入历史记录 - 例如按下按钮,我无法将其视为上一个命令。
我在评估后尝试set -x history (commandline) $history
,但它显示错误set: Tried to change the read-only variable “history”
有没有办法手动将自定义字符串(在我的情况下为命令行缓冲区)添加到历史记录中? THX。
答案 0 :(得分:6)
history --merge
不会按时间顺序#2312合并历史记录。因此,即使我们手动将命令添加到~/.config/fish/fish_history
,我们也无法简单地按下来查看它(尽管如果按下足够的话,最终会达到它)。
为了解决这个问题,我们可以制作fish_history
的副本,然后拨打builtin history --clear
,这将清除鱼的内部历史记录和历史记录文件。然后,我们从我们的副本中恢复历史文件,附加我们的命令并调用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
答案 1 :(得分:0)
您可以使用eval
上的-f
选项而不是使用commandline
来注入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
行也会出现在您的历史记录中,这是一个bug或一项功能。我认为它是一个功能,因此不必理会它。