Menempel dari clipboard ke zsh atau bash shell yang diaktifkan

15

Saya ingin dapat menempelkan dari clipboard sistem (atau pemilihan teks) ke dalam shell prompt "vi-like" saya menggunakan keyboard. Saya biasanya menggunakan zsh dan terkadang bash. Dalam kedua kasus, saya memiliki shell yang diatur dengan perilaku vi-like ( bindkey -v/ set -o vi).

Dalam vim, perilaku yang saya cari tersedia dengan urutan kunci "+p. Namun, urutan kunci khusus ini tidak berfungsi seperti yang diharapkan dalam prompt shell yang diaktifkan vi. Apakah ada cara untuk mengaktifkan ini atau perilaku serupa, hanya menggunakan keyboard, sementara tetap dengan keybindings mirip-vi dalam prompt zsh atau bash shell?

- edit -

Kasus penggunaan: Saya sering menavigasi antara Firefox dengan addon Pentadactyl , emulator terminal dan vim itu sendiri - menggunakan window manager Xmonad dengan tombol kustom untuk bergerak. Ketiga program memiliki keybindings mirip vi, yang sangat efisien (untuk "memori jari") sehingga akan ideal untuk mengkomunikasikan teks di antara mereka menggunakan sintaks vim (atau sintaks yang sangat mirip) saja.

Dalker
sumber

Jawaban:

9

Zsh tidak mendukung apa pun kecuali register internal, dan bash tidak mendukung register sama sekali sejauh yang saya tahu. Pada umumnya, shell mendukung perintah vi, bukan perintah vim.

Di zsh, inilah bukti konsep untuk mengakses pemilihan X dari mode perintah. Untuk penggunaan nyata Anda ingin menguraikan teknik ini. Saya menggunakan xselprogram ini, Anda bisa menggunakan xclip; lihat Cara menyalin dari satu contoh vim ke yang lain menggunakan register . Anda akan menemukan fitur yang saya gunakan di manual 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

Fungsi vi-append-x-selectionmenyisipkan pemilihan X saat ini setelah kursor (mirip dengan patau P). Fungsi vi-yank-x-selectionmenyalin teks yang terakhir dibunuh atau disentak ke pilihan X. zle -Nmendeklarasikan fungsinya sebagai widget zle (mis. perintah edisi). bindkey -amengatur binding untuk mode perintah vi.

Gilles 'SO- berhenti menjadi jahat'
sumber
Ini bekerja dengan sempurna setelah menginstal xseldan menyalin kode yang Anda sarankan dengan sedikit modifikasi pada .zshrc saya (saya memilih '^ P' alih-alih '^ X', menimpa perilaku asli '^ P')
Dalker
4

Berikut adalah solusi untuk zsh (mode vi) yang membungkus widget asli sehingga clipboard selalu disinkronkan

Ganti xclipdengan alat clipboard pilihan Anda.

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
olejorgenb
sumber
Ini bekerja seperti pesona xterm-termite.
Rotareti
3

Pilihan dan clipboard adalah hal-hal yang berbeda di bawah X Window, dan "lingkungan desktop" IMHO cenderung membuat masalah lebih suram daripada sebelumnya.

Apakah shift-insert berfungsi untuk Anda? Pada aplikasi bare X, itu pasti akan menempel seleksi ketika mengikat seperti itu dibuat.

Pemrogram
sumber
Pemilihan dan clipboard yang berbeda tidak benar-benar relevan di sini, solusi yang bekerja dengan satu akan mudah untuk beradaptasi dengan yang lain. Lingkungan desktop tidak mengubah apa pun; penyebaran mereka telah menyertai pergeseran keseimbangan kekuatan dari seleksi dan menuju clipboard.
Gilles 'SANGAT berhenti menjadi jahat'
shift-insert memang berfungsi di lingkungan saya, dan itu pasti baik untuk diketahui, untuk digunakan ketika dalam sistem yang berbeda. Namun saya sedang mencari sesuatu yang lebih dekat dengan keybindings vim aktual untuk menyentak dan / atau menempel di antara terminal, vim itu sendiri dan program lainnya
Dalker
1

Solusi ini berfungsi jika Anda telah menginstal oh-my-zshdan mengaktifkan vi-mode plugin.

Solusi berbasis Gilles xseldan zletidak berhasil untuk saya. Namun, karena saya telah mengkonfigurasi vim untuk menggunakan clipboard sistem saya secara default ( set clipboard=unnamedplusin ~/.vimrc), saya cukup mengetikkan vmode normal terminal untuk membuka perintah saat ini vimdan kemudian saya dapat menyalinnya ke clipboard X dengan salah satu dari vimperintah yank.

joelostblom
sumber
Bagaimana ini terkait dengan ZSH? Apakah Anda berbicara tentang tertanam yang :termtersedia di versi baru Neovim dan Vim?
Doron Behar
@DoronBehar Jika Anda memiliki mode-vi diaktifkan di zsh, Anda dapat mengetik vdalam mode normal untuk mengedit perintah yang saat ini diketik di dalam vim alih-alih pada terminal prompt.
joelostblom
Anda harus menyebutkan fakta bahwa Anda berbicara tentang fitur Neovim dan Vim :termdalam jawaban Anda, jika tidak sama sekali tidak jelas.
Doron Behar
@ DoronBehar saya tidak berbicara tentang :term. Namun, saya menemukan bahwa fungsi yang saya maksud sebenarnya disediakan oleh oh-my-zsh. Saya telah memperbarui jawabannya.
joelostblom