web-dev-qa-db-ja.com

クリップボードからvi対応のzshまたはbashシェルへの貼り付け

キーボードを使用して、システムのクリップボード(またはテキストの選択)から「viのような」シェルプロンプトに貼り付けられるようにしたいのですが。私は通常zshを使用し、時にはbashを使用します。どちらの場合も、シェルにviのような動作(bindkey -v/set -o vi)を設定しています。

Vimでは、私が探している動作は"+pというキーシーケンスで利用できます。ただし、この特定のキーシーケンスは、vi対応シェルプロンプトでは期待どおりに機能しません。 zshまたはbashシェルプロンプトでviのようなキーバインドを使用したまま、キーボードのみを使用してこれまたは同様の動作を有効にする方法はありますか?

-編集-

使用例:私はしばしば Pentadactylアドオン 、ターミナルエミュレーター、およびvim自体を使用してFirefox間を移動します-カスタムキーを持つ Xmonad ウィンドウマネージャーを使用して移動します。 3つすべてのプログラムには、viのようなキーバインディングがあります。これは非常に効率的(「フィンガーメモリ」の場合)なので、vim構文(または非常に類似した構文)のみを使用してそれらの間でテキストを通信するのが理想的です。

15
Dalker

Zshは内部レジスタ以外は何もサポートせず、bashは私の知る限りレジスタをまったくサポートしていません。概して、シェルはvimコマンドではなくviコマンドをサポートしています。

Zshで、コマンドモードからX選択にアクセスするための概念実証を以下に示します。実際に使用するには、これらのテクニックについて詳しく説明する必要があります。私はxselプログラムを使用していますが、代わりにxclipを使用できます。 レジスタを使用して1つのvimインスタンスから別の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選択を挿入します(pまたはPと同様)。関数 vi-yank-x-selectionは、最後にキルまたはヤンクしたテキストをX選択にコピーします。 zle -N関数をzleウィジェット(つまり、編集コマンド)として宣言します。 bindkey -a viコマンドモードのバインディングを設定します。

クリップボードが常に同期されるように元のウィジェットをラップする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
4
olejorgenb

選択とクリップボードはX Windowで異なるものであり、IMHOの「デスクトップ環境」は、問題を以前よりもさらに曖昧にする傾向があります。

シフト挿入はあなたのために働きますか?ベアXアプリケーションでは、そのようなバインディングが行われると、選択を貼り付けることにバインドされます。

3
AProgrammer

このソリューションは、oh-my-zshをインストールして vi-mode プラグインを有効にしている場合に機能します。

Gillesのxselおよびzleベースのソリューションではうまくいきませんでした。ただし、デフォルトでシステムクリップボード(set clipboard=unnamedplus~/.vimrc)を使用するようにvimを構成しているため、単純に次のように入力します。 v ターミナルの通常モードでvimで現在のコマンドを開き、vim yankコマンドのいずれかを使用してXクリップボードにコピーできます。

1
joelostblom