Pegar desde el portapapeles a zsh o bash shell habilitado para vi

15

Me gustaría poder pegar desde el portapapeles del sistema (o selección de texto) en mi indicador de shell "vi-like" usando el teclado. Normalmente uso zsh y algunas veces bash. En ambos casos, tengo el shell configurado con un comportamiento similar a vi ( bindkey -v/ set -o vi).

En vim, el comportamiento que estoy buscando está disponible con la secuencia de teclas "+p. Sin embargo, esta secuencia de teclas en particular no funciona como se esperaba en un indicador de shell habilitado para vi. ¿Hay alguna manera de habilitar esto o un comportamiento similar, usando solo el teclado, mientras se mantienen las combinaciones de teclas tipo vi en un indicador de shell zsh o bash?

- editar -

Caso de uso: a menudo navego entre Firefox con el complemento Pentadactyl , un emulador de terminal y vim, usando el administrador de ventanas Xmonad con teclas personalizadas para moverme. Los tres programas tienen combinaciones de teclas tipo vi, lo cual es muy eficiente (para "memoria de dedo"), por lo que sería ideal comunicar el texto entre ellos usando la sintaxis vim (o una sintaxis muy similar) solamente.

Dalker
fuente

Respuestas:

9

Zsh no admite nada más que registros internos, y bash no es compatible con el registro hasta donde yo sé. En general, los shells admiten comandos vi, no comandos vim.

En zsh, aquí hay una prueba de concepto para acceder a la selección X desde el modo comando. Para un uso real, desearía desarrollar estas técnicas. Yo uso el xselprograma, puedes usarlo xclipen su lugar; vea Cómo copiar de una instancia de vim a otra usando registros . Encontrarás las características que utilicé en el manual de 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

La función vi-append-x-selectioninserta la selección X actual después del cursor (similar a po P). La función vi-yank-x-selectioncopia el último texto eliminado o eliminado en la selección X. zle -Ndeclara las funciones como widgets zle (es decir, comandos de edición). bindkey -aestablece enlaces para el modo de comando vi.

Gilles 'SO- deja de ser malvado'
fuente
Esto funcionó perfectamente después de instalar xsely copiar su código sugerido con una ligera modificación en mi .zshrc (elegí '^ P' en lugar de '^ X', sobrescribiendo el comportamiento original de '^ P')
Dalker
4

Aquí hay una solución para zsh (modo vi) que envuelve los widgets originales para que el portapapeles siempre esté sincronizado

Reemplace xclipcon su herramienta de portapapeles preferida.

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
fuente
Esto funciona como un encanto en xterm-termite.
Rotareti
3

La selección y el portapapeles son cosas diferentes en X Window, y en mi opinión, los "entornos de escritorio" tienden a hacer que el problema sea aún más confuso de lo que era.

¿Funciona Shift-Insert para usted? En aplicaciones X desnudas, está obligado a pegar la selección cuando se realiza dicho enlace.

Un programador
fuente
La selección y el portapapeles siendo diferentes no es realmente relevante aquí, una solución que funcione con uno sería fácil de adaptar al otro. Los entornos de escritorio no cambian nada; su propagación ha acompañado un cambio en el equilibrio de poder lejos de la selección y hacia el portapapeles.
Gilles 'SO- deja de ser malvado'
shift-insert funciona en mi entorno, y definitivamente es bueno saberlo, para usarlo en un sistema diferente. Sin embargo, estoy buscando algo más cercano a las combinaciones de teclas vim reales para tirar y / o pegar entre terminales, vim y otros programas
Dalker
1

Esta solución funciona si ha instalado oh-my-zshy habilitado el vi-mode complemento.

Gilles xsely zlesolución basada no funcionó para mí. Sin embargo, dado que configuré vim para usar mi portapapeles del sistema de forma predeterminada ( set clipboard=unnamedplusen ~/.vimrc), simplemente escribo ven modo terminal normal para abrir el comando actual vimy luego puedo copiarlo al portapapeles X con cualquiera de los vimcomandos de tirar.

joelostblom
fuente
¿Cómo se relaciona esto con ZSH? ¿Estás hablando de los embebidos :termdisponibles en las nuevas versiones de Neovim y Vim?
Doron Behar
@DoronBehar Si tiene habilitado el modo vi en zsh, puede escribir ven modo normal para editar el comando actualmente escrito dentro de vim en lugar de en el indicador de terminal.
joelostblom
Debe mencionar el hecho de que está hablando de la función de Neovim y Vim :termen su respuesta, de lo contrario no está claro en absoluto.
Doron Behar
@DoronBehar no estoy hablando :term. Sin embargo, descubrí que la funcionalidad a la que me refiero es realmente proporcionada por oh-my-zsh. He actualizado la respuesta en consecuencia.
joelostblom