Einfügen aus der Zwischenablage in die vi-fähige zsh- oder bash-Shell

15

Ich möchte in der Lage sein, aus der System-Zwischenablage (oder Textauswahl) über die Tastatur in meine "vi-like" Shell-Eingabeaufforderung einzufügen. Ich benutze normalerweise zsh und manchmal bash. In beiden Fällen habe ich die Shell mit vi-ähnlichem Verhalten ( bindkey -v/ set -o vi) eingerichtet.

In vim ist das gesuchte Verhalten mit der Tastenfolge verfügbar "+p. Diese spezielle Tastenfolge funktioniert jedoch in einer Eingabeaufforderung für eine vi-fähige Shell nicht wie erwartet. Gibt es eine Möglichkeit, dieses oder ein ähnliches Verhalten nur mit der Tastatur zu aktivieren, während vi-ähnliche Tastenkombinationen in einer zsh- oder bash-Shell-Eingabeaufforderung beibehalten werden?

- bearbeiten -

Anwendungsfall: Ich navigiere häufig zwischen Firefox mit dem Pentadactyl-Addon , einem Terminal-Emulator und vim selbst - wobei ich den Xmonad- Fenstermanager mit benutzerdefinierten Tasten verwende, um mich zu bewegen. Alle drei Programme haben vi-ähnliche Tastenkombinationen, was sehr effizient ist (für "Fingerspeicher"), so dass es ideal wäre, Text zwischen ihnen nur unter Verwendung der vim-Syntax (oder einer sehr ähnlichen Syntax) zu kommunizieren.

Dalker
quelle

Antworten:

9

Zsh unterstützt nur interne Register, und bash unterstützt meines Wissens nach überhaupt keine Register. Im Großen und Ganzen unterstützen Shells vi-Befehle, keine vim-Befehle.

In zsh ist hier ein Proof-of-Concept für den Zugriff auf die X-Auswahl aus dem Befehlsmodus. In der Praxis möchten Sie diese Techniken näher erläutern. Ich benutze das xselProgramm, Sie können xclipstattdessen verwenden; Siehe So kopieren Sie mithilfe von Registern von einer vim-Instanz in eine andere . Die Funktionen, die ich verwendet habe, finden Sie im zle-Handbuch .

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

Die Funktion vi-append-x-selectionfügt die aktuelle X-Auswahl nach dem Cursor ein (ähnlich wie poder P). Die Funktion vi-yank-x-selectionkopiert den zuletzt getöteten oder gezerrten Text in die X-Auswahl. zle -Ndeklariert die Funktionen als zle-Widgets (dh Editionsbefehle). bindkey -aLegt Bindungen für den vi-Befehlsmodus fest.

Gilles 'SO - hör auf böse zu sein'
quelle
Dies hat nach der Installation xselund dem Kopieren des vorgeschlagenen Codes mit einer geringfügigen Änderung an meiner .zshrc-Datei einwandfrei funktioniert (ich habe '^ P' anstelle von '^ X' gewählt und das ursprüngliche Verhalten von '^ P' überschrieben)
Dalker
4

Hier ist eine Lösung für zsh (vi-Modus), die die ursprünglichen Widgets umschließt, damit die Zwischenablage immer synchronisiert ist

Ersetzen Sie xclipmit Ihrem bevorzugten Zwischenablage-Tool.

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
quelle
Das funktioniert wie ein Zauber in xterm-termite.
Rotareti
3

Auswahl und Zwischenablage sind verschiedene Dinge unter X Window, und IMHO "Desktop-Umgebungen" neigen dazu, das Problem noch trüber zu machen, als es war.

Funktioniert Shift-Insert für Sie? In Bare-X-Anwendungen muss die Auswahl beim Herstellen einer solchen Bindung eingefügt werden.

Ein Programmierer
quelle
Auswahl und Zwischenablage sind hier nicht wirklich relevant, eine Lösung, die mit der einen zusammenarbeitet, lässt sich leicht an die andere anpassen. Desktop-Umgebungen ändern nichts. Ihre Verbreitung hat eine Verschiebung des Kräfteverhältnisses von der Auswahl zur Zwischenablage begleitet.
Gilles 'SO- hör auf, böse zu sein'
shift-insert funktioniert in meiner Umgebung und es ist auf jeden Fall gut zu wissen, ob es in einem anderen System verwendet wird. Ich bin jedoch auf der Suche nach etwas näher an tatsächlichen Vim-Tastenkombinationen für das Ziehen und / oder Einfügen zwischen Terminals, Vim selbst und anderen Programmen
Dalker
1

Diese Lösung funktioniert, wenn Sie oh-my-zshdas vi-mode Plugin installiert und aktiviert haben .

Gilles' xselund zlebasierte Lösung nicht für mich arbeiten. Da ich vim jedoch so konfiguriert habe, dass meine Systemzwischenablage standardmäßig ( set clipboard=unnamedplusin ~/.vimrc) verwendet wird, gebe ich einfach den vnormalen Terminalmodus ein, um den aktuellen Befehl zu öffnen, vimund kann ihn dann mit einem der vimyank-Befehle in die X-Zwischenablage kopieren.

joelostblom
quelle
Wie hängt das mit ZSH zusammen? Sprechen Sie über das Embedded :termin den neuen Versionen von Neovim und Vim?
Doron Behar
@DoronBehar Wenn Sie den vi-Modus in zsh aktiviert haben, können Sie vim normalen Modus den aktuell eingegebenen Befehl in vim anstatt an der Eingabeaufforderung des Terminals bearbeiten.
Joelostblom
Sie sollten :termin Ihrer Antwort die Tatsache erwähnen, dass Sie über die Funktionen von Neovim und Vim sprechen , da dies sonst überhaupt nicht klar ist.
Doron Behar
@ DoronBehar Ich spreche nicht :term. Ich habe jedoch festgestellt, dass die Funktionalität, auf die ich mich beziehe, tatsächlich von bereitgestellt wird oh-my-zsh. Ich habe die Antwort entsprechend aktualisiert.
Joelostblom