Das Utility Autokey automatisiert Abläufe, indem es bestimmte Aktionen auslöst, wenn der Anwender zugehörige Textabkürzungen eingibt oder Hotkey-Kombinationen drückt. Perl verwaltet die Helfer.
Online PLUS
In einem Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/Videos
Vor über fünf Jahren war die Welt noch in Ordnung, da konnte ich den Gnome-Windowmanager Metacity noch dazu überreden, einfach auf eine Tastenkombination hin eine Applikation zu starten, indem ich sie mit dem Utility »gconf-editor« eintrug [2]. Da ich im Laufe eines Tages bestimmt hundert Terminalfenster öffne, verbandelte ich, um Zeit zu sparen, die Kombination [Ctrl]+[Alt]+[n] kurzerhand mit einem Shellskript, das ein neues Terminal mit Spezialfont und Hintergrundfarbe öffnete, egal in welcher Applikation sich der Tastaturfokus gerade befand.
Mit dem Windowmanager Compiz des Unity-Desktops scheint das aber inzwischen ein Ding der Unmöglichkeit zu sein, außerdem erscheint es mir mittlerweile zu doof, meine Skripte andauernd den wechselnden Moden anzupassen, denen die Desktop-Hersteller folgen.
Keine Gnome-Sperenzchen
Stattdessen soll sich künftig ein Mittelsmann um die Schnittstelle zwischen der Tastatur, dem sich gerade in Mode befindlichen Windowmanager der Gnome-Welt und den einzuleitenden Aktionen kümmern.
Da kommt das etwa zwei Jahre alte Projekt Autokey [3] gerade recht. Als zusätzlichen Bonus unterstützt es neben dem GTK-3-Toolkit sogar Qt 4, das heißt, ich könnte – wenn ich wollte – damit sogar eines fernen Tages theoretisch auf einen KDE-Desktop umziehen! Man soll bekanntlich niemals nie sagen.
Unter Ubuntu installiert das Kommando
sudo apt-get install autokey-gtk
das Autokey-Utility, und wer es automatisch beim Systemstart hochfahren möchte, trägt es in der Ubuntu-Konfiguration unter »Startup Applications« ein (Abbildung 1).
Autokey unterscheidet zwischen reiner Textersetzung (Phrases) und Skripten, die Aktionen einleiten. Beides wirft es entweder an, wenn ich einen bestimmten Text getippt habe, oder beim Drücken vordefinierter Hotkey-Kombinationen. So könnte jemand unter »Phrases« zum Beispiel eintragen, dass Autokey die vollständige Postadresse rauslässt, sobald der User »myaddr« tippt, etwa in einem Textdokument in »gedit« oder im Inhaltsfeld einer E-Mail.
“Wir hoffen, es hilft”
Abbildung 2 zeigt die Definition des Kürzels »hth« , das per Autokey zu der Floskel “Hope that helps, let me know …” mutiert. Um die Aktion auszulösen, tippt der User in einer Applikation, die ihre Tastatureingaben über den Gnome-Desktop erhält, den Text »hth« und drückt anschließend auf die Return-Taste.
Achtung: Das funktioniert zum Beispiel nicht in einem Xterm-Terminal, es muss schon das Gnome-Terminal sein. Und noch mal aufgepasst: Kürzel, die als Wörter häufig in normalem Text vorkommen, eignen sich naturgemäß weniger als offensichtliche Kunstgebilde wie »hth« oder »afaik« . Unter »Set Abbreviations« trägt der User das Kürzel in eine Liste ein und kann in Zukunft viel Tipparbeit sparen (Abbildungen 3 und 4).
Heiße Tasten
Wer auch unabhängig von Applikationen mit offenen Texteingabefeldern Aktionen auslösen möchte, zum Beispiel direkt auf dem Desktop, definiert im Konfigurationsdialog statt einer Textabkürzung einfach einen Hotkey, also eine Kombination gleichzeitig zu drückender Tasten.
Ein Mausklick im Autokey-Dialog auf den »Set« -Button unter »Hotkeys« bringt das Formular in Abbildung 5 zum Vorschein. Eine sicherlich nicht anderweitig genutzte Kombination wie [Ctrl]+[Alt]+[n] wählt der User am einfachsten durch einen Klick auf den Button »Press to Set« aus, um anschließend die Tastenkombination selbst zu drücken, während Autokey die Ohren spitzt.
Mit Hotkeys leitet der Desktop-Automatisierer nicht nur Textersetzungen ein, sondern kann in Autokey mittels selbst gekochter Python-Skripte auch beliebige Aktionen einleiten. Hierzu erzeugt das Autokey-UI mit »New Script« ein neues Skript und legt es nicht wie vorher im Ordner »My Phrases« , sondern unter »Sample Scripts« ab.
Die Unterscheidung zwischen Ersetzungen und dynamischen Skripten ist wichtig, denn ist ein Skript nicht als solches gekennzeichnet, gäbe Autokey im Aktionsfall einfach den Python-Code aus, statt ihn auszuführen. Abbildung 5 zeigt eine Aktion, die dem Hotkey [Ctrl]+[Alt]+[n] zugewiesen ist und die erwähnten maßgeschneiderten Terminalfenster aufmacht, von denen ich täglich Dutzende brauche.
Verteilung automatisieren
Natürlich geht es nicht an, die Kürzel und Hotkey-Aktionen auf jeder neuen Linux-Kiste von Hand ins GUI von »autokey-gtk« einzutragen. Auch neu hinzukommende Produktivitätshelfer sollen nicht von Hand auf dem Desktop, sondern programmierbar gleich in die Autokey-Konfiguration einfließen.
Hierzu hilft es, Autokey über die Schulter zu schauen: Nachdem der User die entsprechenden Knöpfe zur Autokey-Konfiguration gedrückt, die Textfelder gefüllt und die Dialoge geschlossen hat (nicht vergessen den »Save« -Knopf in der Kopfzeile zu klicken), legt Autokey die Daten im Homeverzeichnis unter »~/config/autokey/…« ab.
Die Metadaten der definierten Tastenkombinationen liegen im Json-Format unter dem jeweiligen Ordner, »My Phrases« für Textsnippets und »Sample Scripts« für Skripte. Eine frische Autokey-Installation erzeugt beim ersten Aufruf von »autokey-gtk« eine Reihe von Beispiel-Phrasen und -Skripten, die einen Eindruck davon vermitteln, was mit dem Tool alles möglich ist (Abbildung 6).
Um den Vorgang zu automatisieren, kopiert im Folgenden ein Perl-Skript das von Autokey genutzte Metadatenformat aus den bereits vorhandenen Beispielen und fügt neue Einstellungen hinzu, gemäß einer relativ kompakten Yaml-Datei, die jeder nach seinem Gusto ohne viel Aufwand anpassen kann (Listing 1).
Listing 1
autokey.yaml
01 - 02 name: terminal 03 type: script 04 exec: /home/mschilli/bin/xt & 05 hotkey: ctrl-alt-n 06 - 07 name: hth 08 type: phrase 09 abbrv: hth 10 text: Hope that helps!
Geschwätziges Json
Die von Autokey genutzten Json-Dateien zum Speichern von Meta-Informationen sind relativ geschwätzig, wie in Abbildung 7 zu sehen. In der Datei ».name.json« stehen die mit dem Eintrag »name« verknüpften Informationen, während das zugehörige Python-Skript zum Auslösen der gewünschten Aktion in »name.py« im selben Ordner residiert.
Das Skript in Listing 2 schnappt sich beim Aufruf
Listing 2
autokeygen
01 #!/usr/local/bin/perl -w
02 use strict;
03 use Sysadm::Install qw(:all);
04 use Yaml qw( LoadFile );
05 use JSON qw( from_json to_json );
06
07 my $yaml_file = "autokey.yaml";
08 my( $base_dir ) =
09 glob "~/.config/autokey/data";
10 my $script_dir =
11 "$base_dir/Sample Scripts";
12 my $phrase_dir = "$base_dir/My Phrases";
13
14 for my $entry (
15 @{ LoadFile $yaml_file } ) {
16 my $func = "process_$entry->{type}";
17 no strict 'refs';
18 $func->( $entry );
19 }
20
21 ###########################################
22 sub process_script {
23 ###########################################
24 my( $entry ) = @_;
25
26 # get template script
27 my $data =
28 json_rw( "Insert Date", $script_dir );
29
30 $data->{ hotkey } = hotkey( $entry );
31 $data->{ description } = $entry->{ name };
32 $data->{ modes } = [ 3 ];
33
34 json_rw( $entry->{ name }, $script_dir,
35 $data );
36
37 blurt( "system.exec_command(" .
38 "'$entry->{exec}')\n",
39 "$script_dir/$entry->{ name }.pi" );
40
41 }
42
43 ###########################################
44 sub hotkey {
45 ###########################################
46 my( $entry ) = @_;
47
48 my @mods = split /-/, $entry->{ hotkey };
49 my $key = pop @mods;
50
51 return {
52 hotKey => $key,
53 modifiers => [ map { "<$_>" } @mods ],
54 };
55 }
56
57 ###########################################
58 sub process_phrase {
59 ###########################################
60 my( $entry ) = @_;
61
62 # get template phrase
63 my $data =
64 json_rw( "Second phrase", $phrase_dir );
65
66 $data->{ abbreviation }->
67 { abbreviations }->[ 0 ] =
68 $entry->{ abbrv };
69
70 $data->{ description }
71 = $entry->{ name };
72
73 $data->{ modes } = [ 1 ];
74
75 json_rw( $entry->{ name }, $phrase_dir,
76 $data );
77
78 blurt( "$entry->{ text }\n",
79 "$phrase_dir/$entry->{ name }.txt" );
80 }
81
82 ###########################################
83 sub json_rw {
84 ###########################################
85 my( $name, $dir, $data ) = @_;
86
87 my $path = "$dir/.$name.json";
88
89 if( defined $data ) {
90 return blurt to_json(
91 $data, { pretty => 1 } ), $path;
92 }
93
94 return from_json( slurp $path );
95 }
autokeygen autokey.yaml
die Yaml-Datei aus Listing 1 und formt aus den beiden dort stehenden Einträgen – einem zum Textersatz des Kürzels »hth« sowie einer Terminal-Aktion zur Tastenkombination [Ctrl]+[Alt]+[n] – insgesamt vier zusätzliche Einträge im Konfigurationsbaum von Autokey, wie aus Abbildung 8 ersichtlich.
Jeder Eintrag erzeugt eine Json-Datei und eine Text- beziehungsweise Python-Datei. Zu beachten ist, dass Autokey zu diesem Zeitpunkt nicht laufen darf, sonst bekäme es die Änderung seiner Konfiguration nicht mit und würde die neuen Daten später rücksichtslos wieder mit alten Einträgen überkleistern.
Zum Lesen von Yaml- und Json-Dateien zieht Listing 2 zunächst die Module »JSON« und »YAML« vom CPAN herein. Die Zeilen 7 bis 12 definieren, wo Autokey die Konfigurationsdateien ablegt, die For-Schleife ab Zeile 14 iteriert über die Einträge der Yaml-Datei in Listing 1, deren Daten als Array von Hash-Elementen vorliegen.
Je nach Typ des Eintrags springt der symbolische Funktionsaufruf in Zeile 18 entweder »process_script()« oder »process_phrase()« an. Damit Perl solche gewagten Konstrukte im Strict-Modus erlaubt, muss Zeile 17 die Strenge bei der Interpretation von symbolischen Referenzen temporär auf ein geringeres Maß zurückdrehen.
Beispielhaft
Damit das Skript nicht den ganzen Json-Wust nachimplementiert, orientiert es sich an den bereits von Autokey erstellten Beispieldateien und für jeden Eintrag der Yaml-Datei nur explizit benötigten Feldern. Die Funktion »json_rw()« greift dabei sowohl lesend als auch schreibend auf Json-Dateien der Autokey-Konfiguration zu. Zeile 28 etwa liest die Testkonfiguration zu »Insert Date« ein, einem Beispielskript zum dynamischen Einfügen des aktuellen Datums. Danach modifiziert es in den Zeilen 30 bis 32 nur die Einträge »hotkey« , »description« und »modes« , um sie den Anforderungen gemäß dem Yaml-Eintrag zum Öffnen des Terminalfensters mit der Tastenkombination [Ctrl]+[Alt]+[n] anzupassen.
Mit einer Referenz auf den Datenhash als zusätzlichem Argument erzeugt der Aufruf von »json_rw()« in Zeile 34 dann die Datei ».terminal.json« in der Autokey-Konfiguration. Das Python-Skript, das mit der Funktion »system.exec_command()« über die Shell ein Kommando aufruft, landet per »blurt()« in Zeile 37 in der Python-Datei »terminal.py« .
Da die Hotkey-Definition in der Yaml-Datei kompakt als »ctrl-alt-n« vorliegt, Autokey aber eine kompliziertere Datenstruktur bevorzugt, bereitet »hotkey()« in Zeile 44 die Rohdaten auf.
Die Funktion »process_phrase()« ab Zeile 58 formt das Kürzel »hth« in das von Autokey geforderte Format um. »slurp()« und »blurt()« aus dem CPAN-Modul Sysadm::Install leisten ganze Arbeit. Wer Probleme mit den Skripten hat, der sei auf die Datei »~/.config/autokey/autokey.log« verwiesen. Dort treten alle Systemfehler zutage und die Meldungen helfen meist weiter.
Infos
- Listings zu diesem Artikel ftp://www.linux-magazin.de/pub/listings/magazin/2015/03/Perl
- Michael Schilli “At your fingertips”:Linux-Magazin 06/2008, https://www.linux-magazin.de/Ausgaben/2008/06/Schnellstart
- Autokey-Projekt https://code.google.com/p/autokey














