Hintergrund: Warum die Tastatur?
Ich bin schon lange ein Freund der Tastaturbedienung und meide eher die Maus bzw. das Touchpad, weil ich mit der Tastatur schneller eine größere Vielzahl an Funktionen erreichen kann. Für viele Programme habe ich daher immer versucht eine Variante zu finden, die sich so gut wie möglich über die Tastatur bedienen lässt: Window-Manager (früher IceWM, heute Awesome, mit Wayland 🤔), Mailprogramm (Neomutt), Schreibprogramm (früher Jed, jetzt Emacs).
Für den Browser ist dies etwas schwieriger, da viele Elemente nur über die Maus erreichbar sind, obwohl ich überwiegend lese und seltener mit den Seiten interaggiere. Früher habe ich Conkeror verwendet, der Firefox als Unterbau verwendet hat und darauf eine tastaturfreundliche Oberfläche gebaut hat sogar mit einem Minibuffer wie im Emacs, mit dem man leicht Funktionen über ihren Namen aufrufen konnte. Das praktische an Conkeror war auch, dass er mit einer Javascript-Datei konfiguriert werden konnte, was damals schon die Nutzung mehrerer Profile sehr vereinfacht hat, weil ich entsprechende Abfragen und Verzweigungen einbauen konnte.
Leider kam irgendwann das Ende, weil Firefox den Zugriff auf den Unterbau XULrunner nicht mehr ermöglicht hat. Ich bin dann zum richtigen Firefox gewechselt und habe mit der Erweiterung Keysnail weitergemacht. Dieser fehlte zwar der Minibuffer, aber die wichtigsten Tastenkürzel von Emacs waren umgesetzt, sodass ich nicht viel darüber nachdenken musste, in welchem Programm ich war. Und Keysnail hatte ebenfalls eine Konfigurationsdatei, die es ermöglicht hat, neue Funktionen zu schreiben.
Die Erweiterbarkeit ist eine der wichtigsten Eigenschaften von Programmen für mich. Sei es mit Emacs, Awesome, Keysnail oder der Zsh – wenn ich merke, dass ich irgendwelche Schritte wiederholt durchführe oder mir Ideen kommen, wie ich etwas angenehmer gestalten könnte, dann möchte ich etwas tun und meine Ideen umsetzen können – alles andere ist auf die Dauer frustrierend. Daher achte ich bei der Wahl essentieller Programme darauf, dass ich eine Möglichkeit zum Anpassen und Erweitern habe. – Das als kleiner Einschub.
Leider kam mit Firefox 57 auch für Keysnail das Ende, denn Firefox hat die Schnittstelle für die Add-ons gewechselt, womit viele Add-ons nicht mehr funktioniert und viele Entwickler die Entwicklung eingestellt haben. Ich habe mich dann noch drei Jahre mit dem Nicht-Aktualisieren meines Firefox 56 dahingerettet, aber über die Zeit hin haben diverse Seiten wie Element, Zeit-Online, WhatsApp, YouTube, Crates.io Stück für Stück nicht mehr funktioniert. Parallel zu dem veralteten Hauptbrowser hatte ich schon lange in anderen Profilen Fiefox-Nightly, Firefox-Developer und die aktuelle Version genutzt. Aber die meisten Seiten habe ich weiterhin mit meinem Hauptbrowser besucht.
Mir war klar, dass dies nicht ewig geht, nur leider fehlte mir lange der Ersatz. Ich hatte zwar irgendwann schon einmal Surfingkeys (Firefox-Add-on, Chrome-Add-on) ausprobiert, aber irgendwie kam ich damit nicht zurecht. Heute habe ich mich noch einmal daran probiert und muss sagen, mein erster Eindruck war eine völlige Fehleinschätzung. Surfingkeys ist absolut klasse.
Eigene Funktionen für Tastenkürzel definieren
Eine Funktion, die ich mir für Keysnail gebastelt hatte und die ich sehr häufig nutze, ist das Kopieren des Titels und der URL einer Seite als Markdown-Link. Damit kann ich sehr leicht für eine Webseite einen Link zum Einfügen in ein Markdown-Dokument erstellen. Dies war also die Bewährungsprobe für Surfingkeys und nach längerem Suchen habe ich auch die Stelle zum Eintragen gefunden.
Für eigene Funktionen muss man in den Settings von Surfingkeys den Advanced
mode aktivieren. Damit bekommt man einen kleinen Editor unterhalb des Hakens
angezeigt, mit dem man seine Erweiterungen programmieren kann. Die Funktion für
den Markdown-Link ist einfach und ich habe sie der Tastenfolge c m
zugewiesen:
mapkey('cm', 'Copy markdown link of current page', function() {
Clipboard.write(
'['
+ document.title.replace('[', '\\[').replace(']', '\\]')
+ '](' + window.location.href + ')'
);
})
Damit war das Wichtigste gezeigt: die Konfigurier- und Erweiterbarkeit. Dann ging es ans Entdecken der Funktionen von Surfingkeys.
Grundsätzliches zu den Tastenbelegungen
Der Entwickler von Surfingkeys ist (leider) ein vi/vim-Liebhaber, weshalb sich
die Bedienung an vi anlehnt. Das heißt, es gibt einen Command-Modus, indem
eine andere Tastenbelegung gilt als im Visual-Modus und im Eingabe-Modus.
Ich selbst bin mit dieser Denkweise nie warm geworden, aber grundsätzlich gilt:
mit v
aktiviert man den Visual-Modus und mit Esc
geht man wieder zurück
zum Command-Modus. Jede Funktion im Visual-Modus lässt sich also auch als
Folge von Tastendrücken verstehen, womit ich als Emacs-Liebhaber wiederum kein
Problem1 habe.
-
“Hey dad! Do you see how this man can twist his fingers? Amazing, isn't it?” “No son, not really. He's been using Emacs for ten years.” ↩
Ob man sich gerade im Visual-Modus befindet, kann man an einer kleinen Markierung am unteren, linken Fensterrand sehen. Dort erscheinen auch andere Meldungen, sodass man immer mal wieder in diese Ecke blicken sollte.
So ganz allgemein erachte ich die Verwendung von einfachen Tasten als sinnvoll,
da man beim normalen Lesen keine Eingaben tätigt. Daher ist die Anlehnung an vi
bzw. auch less treffender als die permanente Nutzung der Strg
wie im Emacs
– ein Browser ist eben kein Editor.
Die Liste alle Tastenbelegungen kann man sich mit ?
anzeigen lassen. Mit p
kann man für kurze Zeit die Tastenbelegungen von Surfingkeys deaktivieren und
mit Alt-p
1 bis zum Drücken von Esc
. Dies ist auf einigen Seiten wie YouTube
oder GitHub nützlich, weil die Seiten (der Player) selbst eine Tastaturbedienung
mit ähnlichen Tasten vorsieht, wie sie auch Surfingkeys nutzt.
-
Diese Tastenkombination habe ich gewählt. Im Original ist es
Alt‑i
. ↩
Grenzen von Surfingkeys
Gleich zu Anfang muss ich sagen, dass Surfingkeys leider nicht unter allen
Umständen funktioniert. Während Keysnail zum Beispiel auch in der Adresszeile
funktionierte, gibt es für Surfingkeys Beschränkungen, die Anpassungen nicht
überall erlauben. Zum einen sind Anpassungen auf den Spezialseiten about:…
und
Fehlerseiten nicht möglich, dann erlaubt Firefox keine Veränderung auf Seiten
von addons.mozilla.org und zum anderen wird
Surfingkeys in jedem Tab erst nach dem Laden aktiv, weshalb während des Ladens
die Tastaturanpassung (z. B. Schließen oder Wechsel des Tabs) nicht
funktioniert.
Weiterhin habe ich Zustände beobachtet, in denen Surfingkeys wie abgestürzt erschien, also nicht mehr reagierte. Erklären kann ich den Zustand nicht, aber es funktionierte die Tastaturanpassung nicht mehr. Wobei dies auch selten vorkommt.
Man muss sich also auch weiterhin die gängigen Tastenkombinationen wie Strg-w
zum Schließen oder Strg-l
für die Adresszeile merken. Da auch nicht immer
erkennbar ist, ob Surfingkeys aktiv ist, habe ich es tunlichst vermieden
Strg-w
oder gar Strg-q
zu belegen, obwohl dies überraschender Weise möglich
ist. Dafür habe ich aber Strg-s
belegt, weil dies die Tastenkombination ist,
die sich mir am stärksten eingebrannt hat und die mich immer wieder beim Firefox
aufschreien lässt.
Meine Tastaturbelegung
Die Tastaturbelegung von
Surfingkeys
ist sehr umfangreich, aber ich empfinde sie als nicht sehr einprägsam, weshalb
ich mir meine eigene Tastenbelegung erstellt habe. Diese weicht in Teilen stark
von der Originalbelegung ab, aber ich habe auch Belegungen beibehalten, sodass
es eine Mischung geworden ist. Zusätzlich dazu gelten auch noch einige
Standardbelegungen wie Strg-Tab
zum Tabwechseln oder Strg-c
zum Kopieren.
Ich bin es auch von Emacs gewöhnt, dass man die Funktion einer Taste durch ein
Prefix-Argument verändern kann. Im Emacs kann man dieses mit Alt-1…9
angeben, aber bei Surfingkeys braucht man nur die Ziffern 1…9
nutzen. Zu 100 %
funktioniert es zwar nicht, denn man muss mindestens eine 2
angeben, aber
vielleicht finde ich dafür noch eine Lösung. Als kleines Beispiel habe ich mit
Umschalt-f
das öffnen eines Links in einem neuen Tab, mit 2 Umschalt-f
lassen sich mehrere Links wählen.
Grundsätzlich habe ich auch immer versucht die einfache Taste für den aktuellen
und die Kombination mit der Umschalttaste für einen neuen Tab zu verwenden; f
folgt einem Link im aktuellen Tab, Umschalt-f
folgt in einem neuen Tab.
Nutzung meiner Konfiguration
Wer meine Konfiguration nutzen möchte, muss in den Settings des Surfingkeys-Menüs den Advanced mode aktivieren und in die Eingabezeile Load settings from die Adresse https://jo-so.de/2021-01/Surfingkeys.js eintragen und auf Save klicken.
Navigation innerhalb der Seite
Neben den üblichen Tasten zur Navigation gibt es noch w
und d
um jeweils
eine halbe Bildschirmseite nach oben bzw. unten (down) zu gehen. Beim Lesen von
Texten finde ich das wesentlich angenehmer als eine komplette Bildschirmseite zu
springen, ähnlich wie es auf der Kommandozeile auch less bietet.
Das Scrollen der
Seite
erfolgt dabei von Haus aus gleitend, was ich als nicht angenehm entfinde. Daher
habe ich in den Einstellungen settings.smoothScroll = false;
hinzugefügt,
damit der Wechsel sprunghaft passiert. Es lässt sich wohl auch noch die
Schrittweite der Bewegungen mit settings.scrollStepSize = …;
festlegen, aber
dies habe ich nicht angepasst.
Weiterhin nutze ich oft den Sprung zum Seitenanfang mit <
und >
zum
Seitenende. Eine komplette Seite weiter kann man mit der Leertaste springen und
eine Seite zurück mit b
.
Navigation zwischen den Tabs
Da ich häufig zwischen linkem und rechtem Tab wechsle, habe ich mir diese
Funktionen auf die Tasten e
und r
(right) gelegt. Mit t
kann man der Liste
aller Tabs anhand des Titels oder der URL einen auswählen.
Aktionen für Tabs
Den aktuellen Tab kann man mit x
schließen und mit Umschalt-x
den zuletzt
geschlossenen Tab wieder öffnen. Mit Umschalt-r
lässt sich der Tab neu laden
(engl. reload) und mit Umschalt-d
duplizieren. Der neue Tab öffnet sich dann
im Hintergrund, aber mit einem Prefix (z. B. 2 D
) öffnet sich der neue
Tab im Vordergrund.
Mit dem Anfang Umschalt-t
gibt es Aktionen für andere Tabs. Mit T x
lassen
sich Tabs schließen: T x e
der linke, T x r
der rechte, T x x
der
aktuelle, T x E
alle linken und T x R
alle rechten.
Im Menü von uBlock origin gibt es den Blitz zum Löschen von Teilen aus der
Webseite. Bereits von Conkeror kenne ich diese Funktion und daher habe ich sie
mir mit Surfingkeys jetzt nachgebaut. Mit Strg-d
kann man ein Element
auswählen, das aus der Seite entfernt wird. Mit einem Prefix-Argument
(z. B. 2 Strg-d
) lassen sich mehrere Elemente hintereinander löschen.
Links anwählen
Um einen Link »anzuklicken«, ihm also zu folgen, kann man mit f
über
eingeblendete Kürzel den gewünschten Link auswählen. Sollte es nur einen Link
auf der Seite geben, wird dieser sofort angesprungen. Mit Umschalt-f
wird der
Link in einem neuen Tab geöffnet oder – auf der Ergebnisseite von Suchanfragen
nutze ich dies gern – mit einem Prefix-Argument 2 Umschalt-f
kann man mehrere
Links im Hintergrund öffnen.
Eine Adresse ansteuern
Unter dem Anfang g
(engl. go-to) habe ich Adresswechsel für den aktuellen Tab
und unter Umschalt-g
für einen neuen Tag angeordnet. Will man eine neue
Adresse öffnen, so geht dies mit g g
bzw. G G
für einen neuen Tab. Mit g #
geht man zur aktuellen Adresse ohne das Fragment, mit g ?
ohne die aktuellen
Parameter, mit g ^
geht man eine Verzeichnisebene nach oben und mir g /
zum
Hauptverzeichnis.
Mit g c
bzw. G c
lässt sich die URL in der Zwischenablage (engl. clipboard)
ansteuern. Mit g b
(engl. go back) und Umschalt-b
kann man in der Historie
zurück gehen und mit g f
(engl. go forward) kann man sich in der Historie
vorwärts bewegen.
Sprungmarken
Ebenfalls von less kenne ich Sprungmarken, die wie Lesezeichen für Positionen
innerhalb der Seiten sind. Mit m
und einer weiteren selbstgewählten Taste kann
man sich an der aktuellen Position eine Markierung setzen. Mit '
und eben
dieser Taste kann man zu der Position zurück. Mit der Folge g m
bekommt man
die Liste der definierten Marken und kann sie ebenfalls ansteuern.
Kopieren
Wie eingangs angesprochen, kopiere ich auch häufe einen Verweis auf die aktuelle
Seite. Solche Kopierfunktionen beginnen mit c
(engl. copy). Für die Adresse
des aktuellen Tabs ist es c c
, mit c h
nur der Servername und mit c m
die
Adresse und der Titel als Markdown-Link. Mit c t
lässt sich der Titel der
Seite kopieren.
Mit c e
lässt sich der Text eines Elementes kopieren und mit c i
der Verweis
auf ein Element mit einer ID. Vor allem die letzte Funktion ist nützlich, weil
nicht immer entsprechende Verweise existieren, die sich kopieren lassen. Bisher
verwende ich immer die Erweiterung Webdeveloper, um diese Verweise einblenden
zu lassen, aber mit dieser Funktion von Surfingkeys geht es mit der Tastatur nun
schneller.
Mit c l
lässt sich die Adresse eines Verweises kopieren und mit c Umschalt-l
der Text und die Adresse als Markdown-Link.
Ein Textabschnitt einer Seite lässt sich wie folgt kopieren: Mit v
(engl. visual caret) wechselt man in den Cursor-Modus und kann eine Stelle
auswählen. Dort wird dann ein Cursor angezeigt und man kann mit w
und b
ein
Wort vorwärts bzw. rückwärts springen. Dies bestimmt den Anfang der Markierung
und durch ein weiteres Mal v
kann man in den Markierungsmodus (engl. visual
range) wechseln. Dort kann wieder mit w
, b
und anderen Tasten hin- und
herspringen und den Bereich vergrößern. Am Ende kann man den Text mit y
(engl. yank) kopieren. Zum Schluss kann man den Markierungsmodus mit Esc
und
den Cursor-Modus mit einem weiteren Esc
verlassen.
Dies ist genau die Bedienung von Vim, mit der ich nie warm geworden bin, aber ich brauche diese Funktion so selten, dass ich es dann immer irgendwie schaffe.
Suche
Surfingkeys kommt mit einer eigenen Suchfunktion, die an das Verhalten von Vim
angelehnt ist. Mit /
(und zusätzlich Strg-s
😀) öffnet sich rechts unten ein
kleines Feld, in das man seinen Begriff eingeben kann. Mit Enter
beginnt die
Suche und man kann mit n
und Umschalt-n
vorwärts bzw. rückwärts durch die
Treffen springen. Dies finde ich wesentlich angenehmer als Umschalt-Strg-g
bei
der Firefox-Suche.
Übersetzungen mit Linuguee
Eine sehr interessante Funktion ist die Übersetzung innerhalb der Seite. Mit Q
öffnet sich ein Eingabefeld, in das man ein Wort eingeben kann, wobei die Liste
der Vervollständigungen die Wörter der Seite sind. Aber man kann auch jedes
andere Wort eingeben. Für die Eingabe schlägt Surfingkeys dann die Übersetzung
nach. Natürlich muss man dafür einen Übersetzer
einrichten.
Ich habe mir eine entsprechende Funktion für Linguee gebastelt und den Code
bei Advanced mode in den Settings eingefügt.
Weiterhin lässt sich die Übersetzung eines Wortes vom Cursor-Modus (visual
caret) mit v
und der Taste q
aufrufen. Danach lässt sich die Übersetzung
wieder mit Esc
ausblenden.
Front.registerInlineQuery({
url: "https://www.linguee.de/deutsch-englisch/search?il=DE&tool=opensearch&query=",
parseResult: function(res) {
const doc = new DOMParser().parseFromString(res.text, "text/html");
const dict = doc.querySelector('#dictionary');
// translation_group: less common translations
// example_lines: example usage snippets
// openTriangle: triangle open buttons for the head lines
// a.audio: link for audio example
// a.expand_i: link for more examples
dict.querySelectorAll('.translation_group, .example_lines, .openTriangle, a.audio, a.expand_i')
.forEach(e => e.remove());
dict.querySelectorAll('a')
.forEach(e => e.replaceWith.apply(e, e.childNodes));
const nodesToDrop = [];
dict.childNodes.forEach(el => {
if (el.nodeName === 'H1' && el.id !== 'wikipedia-header') {
const new_el = doc.createElement('span');
new_el.innerText = el.innerText.replaceAll(/^.*\(|\)$/g, '');
el.replaceWith(new_el);
} else if (
el.classList && (
el.classList.contains('isForeignTerm')
|| el.classList.contains('isMainTerm'))
) {
const ul = doc.createElement('ul');
el.querySelectorAll('.lemma').forEach(lem => {
const li = doc.createElement('li');
li.append.apply(li, lem.querySelector('h2').childNodes);
lem.querySelectorAll('.tag_trans')
.forEach(trans => li.append(trans, ','));
ul.append(li);
});
el.replaceWith(ul);
} else {
nodesToDrop.push(el);
}
});
nodesToDrop.forEach(el => el.remove());
dict.querySelectorAll('*').forEach(el => {
el.getAttributeNames().forEach(at => {
if (at !== 'class')
el.attributes.removeNamedItem(at);
});
});
return dict.innerHTML;
}
});
Javascript-Code in der Seite ausführen
Da Surfingkeys richtig Javascript-Code im Kontext der Webseite ausführt, kann man dies auch für andere Anpassungen nutzen. Zum Beispiel stört mich immer, dass bei den Xing-Meldungen die eigentliche Seite in einem iFrame geöffnet wird. Mit Surfingkeys kann ich – in guter, alter Conkeror-Manier – ein wenig nachhelfen und das gewünschte Verhalten erzeugen:
if (window.origin === "https://www.xing-news.com") {
const art = document.getElementById('article');
if (art && art.src) {
// load the iframe in the whole tab
window.location.href = art.src;
}
}
Weitere Informationsquellen
- Eine gute Übersicht liefert das ReadMe von Surfingkeys
- Wiki von Surfingkeys insb. die FAQ
- Browse the Web With a Keyboard - A Comparison of Vim-like Browser Plugins
- Add Keyboard Shortcuts to Chrome, Edge and Firefox with Surfingkeys