Die Utility "Autokey" automatisiert Desktopabläufe, in dem sie auf bestimmte Textabkürzungen oder Hotkey-Kombinationen hin programmierbare Aktionen einleitet.
Vor über fünf Jahren war die Welt noch in Ordnung, da konnte man den Gnome-Window-Manager "Metacity" noch dazu überreden, einfach auf eine Tastenkombination hin eine Applikation zu starten, in dem man sie mittels der Utilty "gconf-editor" eintrug ([2]). Da ich im Laufe des Tages bestimmt hundert Terminal-Fenster öffne, verbandelte ich, um Zeit zu sparen, die Kombination "Ctrl-Alt-n" kurzerhand mit einem Shell-Skript, das ein neues Terminal mit Spezialfont und Hintergrundfarbe aufpoppte, egal in welcher Applikation sich der Tastaturfokus gerade befand. Mit dem Unity-Desktop scheint das aber nun ein Ding der Unmöglichkeit zu sein, außerdem ist es mir mittlerweile zu doof, meine Skripts dauernd dem fragwürdigen Treiben der Gnome-Community anzupassen.
Statt dessen soll sich nun ein Mittelsmann um die Schnittstelle zwischen Tastatur, dem sich gerade dieses Jahr in Mode befindlichen Windows-Manager der Gnome-Welt und einzuleitenden Aktionen kümmern, und da kommt das etwa zwei Jahre alte Projekt Autokey [3] gerade recht. Als zusätzlichen Bonus unterstützt es neben dem GTK3-Toolkit gar QT4, und damit könnte ich damit sogar eines fernen Tages theoretisch auf einen KDE-Desktop umziehen! Man soll nie nie sagen. Unter Ubuntu installiert das Kommando
sudo apt-get install autokey-gtk
die Autokey-Utility und wer sie automatisch beim Systemstart hochfahren möchte, trägt sie in der Ubuntu-Konfiguration unter "Startup Applications" ein (Abbildung 1).
Abbildung 1: Damit Autokey automatisch startet, trägt der User die Utility auf Ubuntu unter "Start Applications" ein. |
Autokey unterscheidet zwischen reiner Textersetzung ("Phrases") und Skripts,
die Aktionen einleiten. Beide wirft es entweder bei getipptem Text oder
beim Pressen vordefinierter Hotkey-Kombinationen an.
So könnte man unter "Phrases" zum
Beispiel eintragen, dass Autokey die vollständige Postaddresse rauslässt,
sobald der User "myaddr" tippt, zum Beispiel in
einem Textdokument in gedit
oder im Inhaltsfeld einer Email eines
Webmail-Providers.
Abbildung 2: Einfache Textersetzung mit Autokey: Die Abkürzung "hth" expandiert zu einer länglichen Floskel. |
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: Es funktioniert zum Beispiel nicht in einem reinen xterm-Terminal, es muss schon das gnome-terminal sein. Und aufgepasst: Kürzel, die als Worte häufig in normalem Text vorkommen, eignen sich naturgemäß weniger als offensichtliche Kunstkonstrukte wie "hth" oder "afaik". Unter "Set Abbreviations" trägt der User das Kürzel in eine Liste zum zugehörigen Textersatz ein und kann in Zukunft mächtig Tipparbeit sparen (Abbildungen 3 und 4).
Abbildung 3: In einer Email-Applikation eines Webmail-Providers expandiert das Kürzel "hth" ... |
Abbildung 4: ... zu einer höflichen Floskel am Ende einer Sendung. |
Wer auch unabhängig von Applikationen mit offenen Texteingabefeldern Aktionen auslösen möchte, zum Beispiel direkt auf dem Desktop, definiert im Konfigurations-Dialog statt einer Textabkürzung einfach einen Hotkey, also eine Kombination gleichzeitig gedrückter Tasten auf dem Keyboard.
Abbildung 5: In dieser Einstellung poppt Autokey ein neues Terminalfenster auf, falls der User Ctrl-Alt-n drückt. |
Ein Mausklick im Autokey-Dialog auf den "Set"-Button unter "Hotkeys" bringt das Formular in Abbildung 5 zum Vorschein. Eine sicherlich nicht anderstweitig 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 selbstgekochter Python-Skripts auch beliebige Aktionen einleiten. Hierzu erzeugt die Autokey-UI mit "New Script" (im Gegensatz zum vorher genutzten "New Phrase") ein neues Skript und legt es nicht wie vorher im Ordner "My Phrases" sondern unter "Sample Scripts" ab. Die Unterscheidung zwischen Ersetzungen und dynamischen Skripts ist wichtig, denn ist ein Skript nicht als solches gekennzeichnet, würde Autokey im Aktionsfall einfach den Python-Code aus der Tastatur rauslassen, statt ihn auszuführen. Abbildung 5 zeigt eine Aktion, die dem Hotkey Ctrl-Alt-n zugewiesen ist und die eingangs erwähnten maßgeschneiderten Terminalfenster aufmacht, von denen ich am Tag ein viele Dutzend verbrauche.
Natürlich geht es nicht an, die Kürzel und Hotkey-Aktionen auf jeder
neuen Linux-Kiste von Hand in die GUI von autokey-gtk
einzutragen.
Auch neu hinzukommende Produktivitätshelfer sollen wenn möglich
nicht von Hand auf dem Desktop sondern programmatisch 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 Home-Verzeichnis unter ~/config/autokey/...
ab. Die
Meta-Daten der definierten Tastenkombinationen liegen im JSON-Format unter
dem jeweiligen Ordner, "My Phrases" für Textsnippets und "Sample Scripts" für
Skripts. Eine frische Autokey-Installation erzeugt beim ersten Aufruf
von autokey-gtk
eine Reihe von Beispielphrasen und -skripte, die
einen Eindruck davon vermitteln, was mit dem Tool alles möglich ist
(Abbildung 6).
Abbildung 6: Beim ersten Aufruf erzeugt autokey-gtk einige Beispielphrasen und -skripte. |
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).
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!
Die von Autokey genutzten JSON-Dateien zum Speichern von Metainformationen
geben sich relativ geschwätzig, wie aus Abbildung 7 ersichtlich. In der
Datei .name.json
stehen die mit dem Eintrag name
verknüpften
Informationen, während das zughörige Python-Skript zum Auslösen der
gewünschten Aktion in name.py
im selben Ordner residiert.
Abbildung 7: In der Datei .terminal.json speichert Autokey die Zuordnung des Hotkeys zum Python-Skript unter terminal.py. |
Schnappt sich das Skript in Listing 2 beim Aufruf
autokeygen autokey.yaml
die Yaml-Datei in Listing 1, formt es aus den zwei dort stehenden Einträgen, nämlich einem zum Textersatz des Kürzels "hth" und 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- bzw. 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.
Abbildung 8: Das Skript autokeygen erzeugt ordnungsgemäße Autokey-Einträge gemäß der YAML-Definition in Listing 1. |
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, und die for
-Schleife ab
Zeile 14 iteriert über die Einträgen 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()
auf. 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ückschrauben.
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 }.py" ); 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 }
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ötigte Felder.
Die Funktion json_rw()
greift dabei sowohl lesend ("r") als auch
schreibend ("w") auf Json-Dateien der Autokey-Konfiguration zu. Zeile 28
liest zum Beispiel die Test-Konfiguration zu Insert Date
ein, einem
Beispielskript zum dynamischen Einfügen des aktuellen Datums per
Python-Skript. Anschließend modifiziert es in den Zeilen 30 bis 32
nur die Einträge hotkey
, description
und modes
, um sie an die
Anforderungen gemäß dem Yaml-Eintrag zum Öffnen des Terminalfensters
zur Tastaturkombination Ctrl-Alt-n anzupassen. Mit einer Referenz auf den
Datenhash als zusätzliches Argument erzeugt der Aufruf von json_rw()
in
Zeile 34 dann die Datei .terminal.json
in der Autokey-Konfiguration.
Das einzeilige Python-Skript, das mit der Funktion system.exec_command()
über die Shell ein Kommando aufruft, landet mittels 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 die Funktion hotkey()
in Zeile 44
die Yaml-Rohdaten entsprechend auf.
Das Kürzel "hth" zum Textersatz formt die Funktion process_phrase()
ab Zeile 58 in das von Autokey geforderte Json-Format um. Wie auch schon
in process_script()
leisten die Funktionen slurp()
und blurt()
aus dem Fundus des CPAN-Moduls Sysadm::Install
zum Lesen und Zurückschreiben von Dateien ganze Arbeit.
Wer sich übrigens beim Experimentieren mit neuen Skripts
die Haare rauft, weil der Python-Code eines Skripts nicht
so will, wie eigentlich angedacht, der sei auf die Datei
~/.config/autokey/autokey.log
verwiesen. Dort treten alle
Systemfehler zutage, und die dort registrierten Meldungen helfen meist weiter,
eventuell auftretende Probleme einzukreisen. Wer einige Kürzel definiert,
weiß den gewonnenen Produktivitätsgewinn schnell zu schätzen, und sollte
die Yaml-Datei in einem Versionskontrollsystem wie Git pflegen.
Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2015/03/Perl
"At your fingertips", Michael Schilli, Linux-Magazin 06/2008, http://www.linux-magazin.de/Ausgaben/2008/06/Schnellstart
Autokey Projektseite, https://code.google.com/p/autokey