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


15

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

在vim中,键序列可提供我正在寻找的行为"+p。但是,此特定的键序列在启用vi的shell提示中无法按预期工作。有什么方法可以仅通过键盘启用此功能或类似的行为,而在zsh或bash shell提示中保留类似vi的键绑定吗?

-编辑-

用例:我经常在带有Pentadactyl插件,终端仿真器和vim本身的Firefox之间导航-使用带有自定义键的Xmonad窗口管理器来移动。这三个程序都具有类似vi的键绑定,这非常有效(用于“手指存储”),因此仅使用vim语法(或非常相似的语法)在它们之间传递文本是理想的选择。

Answers:


9

据我所知,Zsh除了内部寄存器外什么都不支持,bash根本不支持寄存器。总的来说,shell支持vi命令,而不支持vim命令。

在zsh中,这是从命令模式访问X选择的概念证明。对于实际使用,您需要详细说明这些技术。我使用该xsel程序,可以xclip改为使用;请参见如何使用寄存器从一个vim实例复制到另一个。您会在zle手册中找到我使用的功能。

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命令模式设置绑定。


在安装xsel并复制了建议的代码后,对我的.zshrc进行了少许修改(在我选择了'^ P'而不是'^ X',并覆盖了'^ P'的原始行为之后),此方法非常有效
Dalker

4

这是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

这就像魔咒中的魅力xterm-termite
Rotareti '18

3

选择和剪贴板是X窗口下的不同事物,恕我直言,“桌面环境”往往使问题比以前更加模糊。

移位插入对您有用吗?在裸X应用程序上,绑定时必须绑定选择。


选择和剪贴板的不同在这里并没有真正的关系,一种适用于一个解决方案的解决方案很容易适应另一个。桌面环境不会改变任何事情。它们的传播伴随着力量平衡的变化,从选择转向剪贴板。
吉尔(Gilles)“所以,别再邪恶了”,

shift-insert确实可以在我的环境中工作,并且知道在其他系统中使用时一定很高兴。但是我正在寻找更接近实际vim绑定的东西,用于在终端,vim本身和其他程序之间进行拉扯和/或粘贴
Dalker

1

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

吉尔xselzle基础的解决方案并没有为我工作。但是,由于我已将vim配置为默认使用系统剪贴板(set clipboard=unnamedplus在中~/.vimrc),因此我只需v在终端普通模式下键入以打开当前命令vim,然后可以使用任何vimyank命令将其复制到X剪贴板。


这与ZSH有什么关系?您是在谈论:termNeovim和Vim新版本中的嵌入式功能吗?
多伦·比哈

@DoronBehar如果在zsh中启用了vi模式,则可以v在普通模式下键入以在vim中而不是在终端提示符下编辑当前键入的命令。
joelostblom

您应该:term在回答中提及您正在谈论Neovim和Vim的功能这一事实,否则并不清楚。
多伦·比哈

@DoronBehar我不是在说:term。但是,我确实发现我所指功能实际上是由提供的oh-my-zsh。我已经相应地更新了答案。
joelostblom
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.