Text auf dem Desktop mittels Cut&Paste ablegen – das gehört selbst bei Kommandozeilen-Liebhabern zum Standardrepertoire. Dabei unterstützt der Windowmanager auf dem Linux-Desktop zwei Puffermechanismen: die primäre Selektion und das Clipboard [2]. Wer mit der Maus Text markiert, lässt den Inhalt dieser primären Selektion über die mittlere Maustaste wieder herauspurzeln. Das Clipboard dagegen verlangt, nach der Auswahl den Copy-Mechanismus in Gang zu setzen, etwa mit [Strg]+[C], und am Ziel die Paste-Funktion aufzurufen.
Verwirrte User
Applikationen steht es frei, eines oder beide Verfahren zu implementieren, deshalb kommt es auf der freien Wildbahn oft zu Verwirrung und frustrierten Anwendern: Während zum Beispiel ein einfaches Xterm nur die primäre Selektion kennt, bietet der Adobe Flashplayer nur den Clipboard-Mechanismus an. Wer Text aus Xterm in ein Flashplayer-Formular übertragen möchte, schaut mit dem Ofenrohr ins Gebirge. Googles Chrome-Browser beherrscht zwar sowohl die primäre als auch die Clipboard-Selektion, läuft in Chrome aber die Webapplikation von Evernote, funktioniert die primäre Selektion nicht.
Wer eine URL aus einem Textfenster kopiert und sie an einen Browser überreichen möchte, steht oft vor dem Problem, dass die URL im Text umbrochen wurde und der Browser dann nur den ersten Teil aufschnappt. Als bekennendes Unix-Urgestein lese ich Mails in Pine in einem Screen-Fenster. Damit die Übertragung derartiger URLs klappt, habe ich in Firefox unter »about:config« die Option »editor.singleLine.pasteNewlines« auf den Wert 3 gesetzt.
Nachhilfe für Chrome
Chrome beherrscht dies allerdings nicht, daher befindet sich in meinem Gnome-Panel am oberen Bildschirmrand ein Propellerhut (Abbildung 1), hinter dem das Skript in Listing 1 Dienst tut. Es schnappt sich die URL in der primären Selektion, entfernt Leerzeichen und Zeilenumbrüche und überreicht die gesäuberte URL dem Chrome-Browser.
Listing 1
chrome-select
01 #!/usr/local/bin/perl -w 02 use strict; 03 use local::lib; 04 use Clipboard; 05 06 my $browser = "/usr/bin/google-chrome"; 07 my $url = Clipboard->paste; 08 09 $url =~ s/\s+//g; 10 11 system( $browser, $url );
Zum Zugriff auf die primäre Desktop-Selektion nutzt Listing 1 das CPAN-Modul Clipboard [3], das auf X-Window unter der Haube das Programm »xclip« verwendet. Letzteres lässt sich auf Ubuntu mit »sudo apt-get install xclip« installieren.

Abbildung 1: Das hinter der Propellermütze steckende Perl-Skript schnappt sich die URL aus der primären Textselektion und startet Chrome.
Das CPAN-Modul hat gegenüber der direkten Verwendung von »xclip« den Vorteil, dass es auch auf einem Mac oder sogar einem Windows-Rechner funktioniert, da es auf diesen Plattformen automatisch auf die nativen Clipboard-Mechanismen umschwenkt.
Propellermütze hebt ab
Da das Clipboard-Modul unter meiner User-ID in meinem Homeverzeichnis und nicht unter »/usr/lib« installiert ist, weist »local::lib« den Perl-Interpreter auf das lokale Verzeichnis hin. Die Methode »paste()« der Klasse »Clipboard« holt den Inhalt der aktuellen primären Selektion ein, Zeile 9 entfernt mittels eines regulären Ausdrucks unerwünschte Umbrüche, und das Kommando »system()« ruft den Chrome-Browser mit der URL als Argument auf.

Abbildung 2: Der Chrome-Launcher, der den Chrome-Browser mit der in X-Window selektierten URL startet.
Trage ich das Skript in einen “Custom Application Launcher” über den Kontext-Menüpunkt »Add to Panel« im Panel mit einem leicht erkennbaren Icon ein (Abbildung 2), reicht nach Selektion der URL (ohne Copy-Kommando) ein Klick auf die Propellermütze, damit Chrome mit der gesäuberten URL hochfährt und der Mail lesende paranoide Dinosaurier zähneknirschend einem Link folgen kann.
Copy per Desktop-Button
Um das erwähnte Kommunikationsproblem zwischen Xterm und dem Flashplayer zu lösen, greift sich Listing 2 die primäre Selektion und schiebt sie aufs Clipboard. Damit der User dieses Kommando auch aus einer Applikation ausführen kann, die den Clipboard-Mechanismus nicht kennt, definiert das Programm »gconf-editor« in Abbildung 3 ein globales Key-Mapping in Gnomes Windowmanager Metacity. Drückt der User nach dem Selektieren eines Textabschnitts die Tastenkombination [Strg]+[Alt]+[C] (definiert im Abschnitt »global_keybindings« ), löst Metacity das konfigurierbare Kommando »run_command_2« aus, das im Abschnitt »keybinding_commands« (Abbildung 4) auf das Skript in Listing 2 gesetzt ist.
Listing 2
primary-to-clipboard
1 #!/usr/local/bin/perl 2 use local::lib; 3 use Clipboard::Xclip; 4 5 my $primary = Clipboard::Xclip-> 6 paste_from_selection( "primary" ); 7 8 Clipboard::Xclip->copy_to_selection( 9 "clipboard", $primary );
Dies ermöglicht es dem User, in einer Applikation, die kein Clipboard kennt, einen Text aufs Clipboard zu befördern. In der Zielapplikation, die die primäre Selektion nicht unterstützt, ist dann nur noch [Strg]+[V] zu drücken, um den gewünschten Text herunterzurasseln. Das Skript nutzt die undokumentierten Methoden »paste_from_selection()« und »copy_to_selection()« der abgeleiteten Klasse »Clipboard::Xclip« , da die Basisklasse »Clipboard« kein Unterscheiden der Puffer zulässt.
Cut&Paste auf Doping
Wer hat sich nicht schon mal gewünscht, über mehrere Cut&Paste-Puffer zu verfügen, um diverse Abschnitte zu selektieren und sie dann alle zusammen in einem anderen Fenster abzulegen? Auf einem Gnome-Desktop muss der User dazu zwischen Quelle und Ziel hin- und herspringen. Listing 3 implementiert daher einen persistenten Stack, auf den der User den Inhalt der primären Selektion schieben kann, um mit »clipboard-stack push« Platz im Puffer für weitere Selektionen freizuräumen. Will er eine ausgediente Selektion wieder durch die kürzlich im Stack abgelegte ersetzen, ruft der User »clipboard-stack pop« auf. Das Skript legt die im Stack befindlichen Werte im Array »@$stack« ab, dessen Inhalt es mit Hilfe des CPAN-Moduls »YAML« persistent in die Datei ».clipboard« im Homeverzeichnis schreibt.
Listing 3
clipboard-stack
01 #!/usr/local/bin/perl -w
02 use strict;
03 use local::lib;
04 use Clipboard;
05 use YAML qw(DumpFile LoadFile);
06
07 my($home) = glob "~";
08 my $clipboard = "$home/.clipboard";
09
10 my $stack = [];
11 $stack = LoadFile( $clipboard ) if
12 -f $clipboard;
13
14 my( $command ) = @ARGV;
15
16 die "usage: $0 [push|pop]" if
17 !defined $command;
18
19 {
20 no strict 'refs';
21 &$command( $stack );
22 }
23
24 DumpFile( $clipboard, $stack );
25
26 ###########################################
27 sub push {
28 ###########################################
29 my($stack) = @_;
30
31 push @$stack, Clipboard->paste;
32 }
33
34 ###########################################
35 sub pop {
36 ###########################################
37 my($stack) = @_;
38
39 Clipboard->copy( pop @$stack );
40 }
Beim erneuten Skript-Aufruf liest die Funktion »LoadFile()« des YAML-Moduls die abgelegten Daten wieder ein. Je nachdem, ob das Skript mit dem Argument »push« oder mit »pop« gestartet ist, springt der Aufruf »&$command( $stack )« in Zeile 21 eine der weiter unten definierten Funktionen an. Da das Skript im »strict« -Modus keine als Textstring vorgegebenen Funktionsaufrufe erlaubt, lockert das Pragma »no strict ‘refs’« in Zeile 20 vorübergehend diese Einschränkung.
Die ab Zeile 27 definierte Funktion »push()« holt mit der Methode »paste()« der Klasse »Clipboard« den selektierten Text ein und schiebt ihn auf den Stack. Die in Zeile 35 definierte Funktion »pop()« kopiert den archivierten Inhalt mit der Methode »copy()« in die primäre Selektion. Klickt der User anschließend auf die mittlere Maustaste, fließt der archivierte Inhalt heraus.
Um zum Jonglieren mit den Selektions-Inhalten nicht erst ein Perl-Skript aufzurufen, erhält das Gnome-Panel für den Selektions-Stack zwei Einträge, die mit zwei Icons in Pfeilform (gefunden unter »/usr/share/icons/Human/48×48/actions« als »edit-redo.png« und »edit-undo.png« ) zum Klicken einladen (Abbildung 5). Zu beachten ist, dass eine aufeinanderfolgende Kombination von Push und Pop nichts bewirkt. Eine Selektion im Puffer kann der User sofort irgendwo ablegen, soll sie aber ins Archiv, weil eine weitere ansteht, bietet der Stack mit »push« die erforderliche Funktionalität. Wird die aktuelle Selektion nicht mehr gebraucht, holt der User mit »pop« die archivierte aus dem Archiv zurück (Abbildung 6).

Abbildung 6: Der grüne Pfeil schiebt die aktuelle Selektion auf den Stack, der orange Pfeil holt sie wieder.
Klick-Klick-Klick
Statt nach jedem Paste im Clipboard-Archiv aufgereihte Daten per Knopfdruck ins Clipboard nachzufüllen, wäre es doch geradezu revolutionär, den User einfach n-mal klicken zu lassen und zwischendurch automatisch den nächsten Puffer nachzuschieben. Das hilft zum Beispiel beim Ausfüllen von Web- oder PDF-Formularen, wenn der User die Reihenfolge der Felder kennt und die Daten entsprechend im erweiterten Clipboard-Puffer vorab aufgereiht hat. Er muss dann nur noch von Feld zu Feld springen und jeweils den Paste-Befehl absetzen.
Listing 4 implementiert das Verfahren, indem es »xclip« direkt aufruft. Statt der primären Selektion nutzt es anders als die zuvor vorgestellten Skripte den Clipboard-Puffer, den [Strg]+[C] (»Edit | Copy« ) auffüllt und [Strg]+[V] (»Edit | Paste« ) leert. Lässt man »-selection CLIPBOARD« weg, greift es stattdessen auf die primäre Selektion zu – der User muss statt mehrmaligem [Strg]+[V] nur auf die mittlere Maustaste hämmern.
Listing 4
multipaste
01 #!/usr/local/bin/perl -w
02 use strict;
03
04 my @words = qw(yes no maybe so);
05
06 for my $word ( @words ) {
07
08 open my $pipe, "|-",
09 qw(xclip -verbose
10 -selection CLIPBOARD -loops 2);
11
12 print $pipe $word;
13 close $pipe or die;
14 }
Das Skript iteriert über eine Reihe von Wörtern (»yes« , »no« , »maybe« , »so« ), schiebt sie eins nach dem anderen aufs Clipboard und wartet mit »-loops 2« , bis der User den Inhalt via Paste-Kommando freigibt. Daraufhin kehrt das bis dahin blockierende »xclip« zurück, die Schleife des Skripts geht in die nächste Runde und der folgende Aufruf von »xclip« bekommt über die mit »open« geöffnete Pipeline das nächste Wort nachgeschoben.
In Abbildung 7 ist der User, nach dem Aufruf von »multipaste« in einem anderen Fenster, in die Felder des Registrierungsformulars gesprungen und hat mit [Strg]+[V] jeweils ein Wort aus dem zuvor eingetüteten Fundus eingefügt.
Wer oft die gleichen Webformulare ausfüllt, die sich nicht einfach durch Verwendung von APIs oder Screenscrapern automatisieren lassen, kann sich mit einem Skript wie »multipaste« die Werte vorab aufbereiten, um später zwar immer noch von Hand, aber blitzschnell von Feld zu Feld zu springen und ohne nachzudenken die richtigen Werte tippfehlerfrei einzufügen.
Online PLUS
In einem Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/plus/2012/03
Infos
- Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2012/03/Perl
- Jamie Zawinski “X Selections, Cut Buffers, and Kill Rings”: http://www.jwz.org/doc/x-cut-and-paste.html
- CPAN-Modul Clipboard: http://search.cpan.org/~king/Clipboard-0.13/










