从剪贴板粘贴到启用 vi 的 zsh 或 bash shell

从剪贴板粘贴到启用 vi 的 zsh 或 bash shell

我希望能够使用键盘从系统剪贴板(或文本选择)粘贴到我的“类似 vi”的 shell 提示符中。我通常使用 zsh,有时使用 bash。在这两种情况下,我都使用类似 vi 的行为 ( bindkey -v/ )设置 shell set -o vi

在 vim 中,我正在寻找的行为可以通过按键序列获得"+p。不过,这个特定的按键序列在启用 vi 的 shell 提示符中无法按预期工作。有没有什么方法可以启用此或类似的行为,仅使用键盘,同时在 zsh 或 bash shell 提示符中保留类似 vi 的键绑定?

- 编辑 -

使用案例:我经常在 Firefox 之间导航五指插件、终端仿真器和 vim 本身 - 使用西莫纳德窗口管理器带有可移动的自定义键。所有三个程序都具有类似 vi 的键绑定,这是非常有效的(对于“手指记忆”),因此仅使用 vim 语法(或非常相似的语法)在它们之间传递文本将是理想的。

答案1

据我所知,Zsh 除了内部寄存器之外不支持任何东西,而 bash 根本不支持寄存器。总的来说,shell 支持 vi 命令,而不支持 vim 命令。

在 zsh 中,以下是从命令模式访问 X 选择的概念验证。为了真正使用,您需要详细说明这些技术。我用的xsel程序,你xclip也可以用;看如何使用寄存器从一个 vim 实例复制到另一个实例。您会发现我在中使用的功能零乐手册

vi-append-x-selection () { RBUFFER=$(xsel -o -p </dev/null)$RBUFFER; }
zle -N vi-append-x-selection
bindkey -a '^X' vi-append-x-selection
vi-yank-x-selection () { print -rn -- $CUTBUFFER | xsel -i -p; }
zle -N vi-yank-x-selection
bindkey -a '^Y' vi-yank-x-selection

该函数vi-append-x-selection在光标后插入当前的 X 选择(类似于pP)。该函数vi-yank-x-selection将最后删除或拉出的文本复制到 X 选择。zle -N将函数声明为 zle 小部件(即编辑命令)。bindkey -a设置 vi 命令模式的绑定。

答案2

这是 zsh(vi 模式)的解决方案,它包装原始小部件,以便剪贴板始终同步

替换xclip为您喜欢的剪贴板工具。

function x11-clip-wrap-widgets() {
    # NB: Assume we are the first wrapper and that we only wrap native widgets
    # See zsh-autosuggestions.zsh for a more generic and more robust wrapper
    local copy_or_paste=$1
    shift

    for widget in $@; do
        # Ugh, zsh doesn't have closures
        if [[ $copy_or_paste == "copy" ]]; then
            eval "
            function _x11-clip-wrapped-$widget() {
                zle .$widget
                xclip -in -selection clipboard <<<\$CUTBUFFER
            }
            "
        else
            eval "
            function _x11-clip-wrapped-$widget() {
                CUTBUFFER=\$(xclip -out -selection clipboard)
                zle .$widget
            }
            "
        fi

        zle -N $widget _x11-clip-wrapped-$widget
    done
}


local copy_widgets=(
    vi-yank vi-yank-eol vi-delete vi-backward-kill-word vi-change-whole-line
)
local paste_widgets=(
    vi-put-{before,after}
)

# NB: can atm. only wrap native widgets
x11-clip-wrap-widgets copy $copy_widgets
x11-clip-wrap-widgets paste  $paste_widgets

答案3

我推荐一个 ZSH 插件:https://github.com/kutsan/zsh-system-clipboard。到安装它,运行:

git clone https://github.com/kutsan/zsh-system-clipboard ~/.zsh/plugins/zsh-system-clipboard

然后将文件来源到您的.zshrc

source "$HOME/.zsh/plugins/zsh-system-clipboard/zsh-system-clipboard.zsh"

该插件支持使用 Tmux 缓冲区找到剪贴板的保存位置,您甚至可以配置替代键绑定用于剪切/粘贴/复制的功能。

该插件已经处理了一个小细节,而其他答案建议没有这样做,那就是区分系统剪贴板内容有和没有新行(参见公关)。对剪贴板输入的这种小检查应确保粘贴任何类型内容的体验与 Vim/Neovim 相同。

答案4

如果您已安装oh-my-zsh并启用了此解决方案,则此解决方案有效vi-mode 插入。

吉尔斯xselzle基于的解决方案对我不起作用。但是,由于我已将 vim 配置为默认使用系统剪贴板(set clipboard=unnamedplusin ~/.vimrc),因此我只需输入v终端正常模式即可打开当前命令,vim然后我可以使用任何 yank 命令将其复制到 X 剪贴板vim

相关内容