总而言之: 有谁知道如何配置 vi-mode bash 使用哪个缓冲区进行拉取(复制)和粘贴?
长版:
我set editing-mode vi
在我的.inputrc
, 中使用该库的程序readline
(即 bash)使用类似 vi 的键绑定。与此无关,我已经设置了 vim 和 tmux 以使用系统剪贴板进行拉取和粘贴。我想对 bash 做同样的事情。这似乎没有必要,因为我主要通过 tmux 使用 bash,但即便如此,能够使用p
(在正常模式下)从剪贴板复制而不是C-a
P
或类似的东西(带有 tmux 前缀)也会很好。但是,我找不到任何有关如何配置 bash 这方面的信息,甚至找不到 bash 默认使用什么缓冲区进行拉取和粘贴的信息。当我在vim中执行时我没有看到它:registers
,所以它似乎不是vim看到的任何寄存器。
答案1
经过一些研究后,bash 似乎为此使用了一个内部变量,而不是任何现成的系统缓冲区。它在 bash 和 readline 的手册条目中被称为“杀环”,其实现可以阅读在 GitHub 上、以及其他地方。也许可以劫持这个机制来使用系统剪贴板,但这似乎对我来说有点太复杂了,目前无法解决。
相反,我选择了下面的简单解决方法,使用 bash 内置bind
命令,该命令记录在 bash 手册页中(搜索bind \[
)。它很好地涵盖了我的用例,但它没有涵盖使用 vim 动作进行更高级的杀戮和猛拉。如果您发现我的解决方案有问题,请告诉我,因为我不习惯编写 bash 脚本。
在~/.bashrc中:
# Macros to enable yanking, killing and putting to and from the system clipboard in vi-mode. Only supports yanking and killing the whole line.
paste_from_clipboard () {
local shift=$1
local head=${READLINE_LINE:0:READLINE_POINT+shift}
local tail=${READLINE_LINE:READLINE_POINT+shift}
local paste=$(xclip -out -selection clipboard)
local paste_len=${#paste}
READLINE_LINE=${head}${paste}${tail}
# Place caret before last char of paste (as in vi)
let READLINE_POINT+=$paste_len+$shift-1
}
yank_line_to_clipboard () {
echo $READLINE_LINE | xclip -in -selection clipboard
}
kill_line_to_clipboard () {
yank_line_to_clipboard
READLINE_LINE=""
}
bind -m vi-command -x '"P": paste_from_clipboard 0'
bind -m vi-command -x '"p": paste_from_clipboard 1'
bind -m vi-command -x '"yy": yank_line_to_clipboard'
bind -m vi-command -x '"dd": kill_line_to_clipboard'
编辑1:
使用两次连续按键的绑定“yy”和“dd”受keyseq-timeout
readline 设置的影响。默认值为 500 毫秒,这意味着您必须在第一个字符后 500 毫秒内键入第二个字符。因此,如果您设置keyseq-timeout
为低得多的值,则可能会遇到一些麻烦。
编辑2: 更新了粘贴以更精确地模拟 vim 行为。