Ein Diktierkürzel, das weiß, wann es weiter zuhören soll
Wie ich Voxtype, Hyper+W und Hyprland-Submaps zu einem zuverlässigen Sprachablauf für Agenten-Chats kombiniert habe.
Omarchy ist ein Arch-Linux- und Hyprland-System mit klaren Designentscheidungen, das seine Konfiguration als lesbaren Quelltext mitliefert. Genau dort wird Open Source mit Agenten besonders interessant. Den alten Linux-Aufwand aus Fehlersuche, Forenrecherche und zusammengesetzter Konfiguration kann man jetzt delegieren. Ich bekomme ein rasend schnelles Betriebssystem von jemandem, der den Stack kennt und liebt, samt Rezept. Ein Agent kann dieses Rezept untersuchen und an mich anpassen. Dieses Kürzel ist ein Beispiel für das Verhalten, das ich wollte.
Aktuelle Modelle greifen auf Funktionen des Compositors wie Submaps zurück. Opus 4.5 schien diesen Schritt bei mir nicht zu machen. OmarchySTT deckte einfaches Diktieren ab. Seine Grenzen erreichte ich, als eine Taste eine Haltefunktion, eine dauerhafte Schleife und eigene Steuerungen je Modus unterstützen sollte.
Ich wollte ein Voxtype-Kürzel mit zwei Modi: zum normalen Diktieren halten oder kurz antippen, um eine freihändige Schleife mit einem Agenten-Chat zu starten.
Das Ergebnis nutzt Hyper+W, ein kleines Steuerungsskript und zwei Hyprland-Submaps.
Die Einrichtung
| Eingabe | Ergebnis |
|---|---|
| Hyper+W eine Sekunde halten | Aufnehmen, beim Loslassen transkribieren und einfügen |
| Hyper+W antippen | Fortlaufendes Diktieren im Agenten-Chat starten |
| Enter | Transkribieren, einfügen, absenden und erneut aufnehmen |
| Super antippen | Transkribieren, einfügen, absenden und stoppen |
| Erneut Hyper+W | Transkribieren und ohne Absenden einfügen, dann stoppen |
| Escape | Abbrechen |
| F12 | Den Ausgangszustand wiederherstellen |
Hyper bedeutet Super+Shift+Control+Alt. Vier physische Tasten sind dafür unhandlich. Tastaturfans legen diese Kombination deshalb meist auf eine sonst kaum genutzte Taste, häufig Caps Lock. Unter Linux ist Kanata ein verbreitetes Werkzeug dafür. Karabiner-Elements übernimmt diese Rolle unter macOS.
Die physische Umbelegung ist optional. Hyprland sieht nur die resultierende Kombination der Modifikatortasten.
Warum Submaps
Eine Hyprland-Submap ist ein vorübergehender Tastaturmodus, ähnlich einem Vim-Modus auf Ebene des Compositors.
Voxtype kann Audio transkribieren, sollte aber nicht global die Enter-Taste einer beliebigen Wayland-Anwendung abfangen. Hyprland steuert ohnehin die Tastatureingaben. Deshalb lasse ich es während der Aufnahme die Steuerungstasten abfangen:
Standard
Hyper+W
↓
voxtype_recording
Enter / Escape / Super / Hyper+W sind Steuerungstasten
↓ Transkription abgeschlossen
voxtype_suppress
gehaltene Modifikatortasten stören das Einfügen nicht
↓
Standard
Damit wird der klassische Wettlauf verhindert, bei dem Enter ein leeres Eingabefeld absendet, bevor die Transkription fertig ist.
Minimale Konfiguration
Ich habe Voxtypes eigenes Tastenkürzel deaktiviert und Einfügen über die Zwischenablage statt simulierter Texteingabe verwendet:
# ~/.config/voxtype/config.toml
[hotkey]
enabled = false
[output]
mode = "paste"
paste_keys = "shift+insert"
restore_clipboard = false
pre_type_delay_ms = 100
auto_submit = false
pre_recording_command = "/home/USER/.local/bin/voxtype-paradict submap voxtype_recording"
pre_output_command = "/home/USER/.local/bin/voxtype-paradict submap voxtype_suppress"
post_output_command = "/home/USER/.local/bin/voxtype-paradict submap reset"
wl-copy verwaltet die Zwischenablage; wtype sendet Shift+Insert. Das Absenden bleibt im Steuerungsskript, sodass normales Diktieren durch Halten niemals Enter sendet.
Die Hyprland-Seite liegt in ~/.config/hypr/bindings.lua. Entscheidend ist nicht der genaue Lua-Wrapper, sondern das Trennen von Drücken und Loslassen und das Erhalten der Loslass-Bindung über Submaps hinweg:
local HYPER = "SUPER + SHIFT + CTRL + ALT"
local controller = "/home/USER/.local/bin/voxtype-paradict"
hl.bind(HYPER, "W", "exec", controller .. " press")
hl.bindr(HYPER, "W", "exec", controller .. " release", {
submap_universal = true,
})
hl.define_submap("voxtype_recording", function()
-- Hyprland 0.56.2 silently omits symbolic RETURN in this named submap.
hl.bind(
"code:36",
hl.dsp.exec_cmd(controller .. " submit-continue")
)
end)
Unter Hyprland 0.56.2 wurde eine symbolische RETURN-Bindung innerhalb der benannten Aufnahme-Submap stillschweigend ausgelassen. hyprctl configerrors blieb leer, die Konfigurationsprüfung erkannte das also nicht. code:36 bindet die physische Haupt-Enter-Taste. Die Enter-Taste des Ziffernblocks braucht eine separate Bindung. Nach jedem Neuladen sollte man hyprctl binds prüfen und sicherstellen, dass die Bindung unter voxtype_recording vorhanden ist.
Das Steuerungsskript unterscheidet Antippen und Halten anhand monotoner Zeit, serialisiert Übergänge mit flock, wartet auf Voxtype-Zustandsänderungen und setzt Hyprland bei jedem Fehler zurück.
Fehler durch die Reihenfolge beim Loslassen
Eine Submap löst die Weiterleitung, aber nicht jeden Sonderfall mit Modifikatortasten. Ich brauchte drei zusätzliche Schutzmechanismen:
- Universelles Loslassen: Die Aufnahme ändert die aktive Submap, bevor W losgelassen wird.
- Verzögerte Super-Aktivierung: Das Loslassen der Hyper-Kombination darf nicht wie eine absichtliche Beendigung durch Super aussehen. Nach einem Antippen ignoriere ich Super-Loslassereignisse für 400 ms.
- Ausgabeunterdrückung: Die Transkription kann fertig sein, während eine Modifikatortaste noch gedrückt ist. Die Unterdrückungs-Submap fängt diese Tasten während Einfügen und Absenden ab.
Die festhängende Aktivierung
Eine Reihenfolge störte die Schleife weiterhin. Wenn ich Hyper vor W losließ, betrachtete Hyprland das spätere Loslassen von W nicht mehr als Hyper+W-Ereignis. Das Steuerungsskript behielt seine Aktivierungsmarkierung, sodass Super und Enter festzuhängen schienen.
Die Lösung: Beide Loslassereignisse dürfen die Aktivierung abschließen. Wenn Super losgelassen wird, während die Hyper+W-Markierung noch existiert, übernimmt das Steuerungsskript diese Markierung und führt denselben Übergang für Antippen oder Halten aus wie beim Loslassen von W. Bei diesem Ereignis sendet es noch nichts ab. Ein späteres einzelnes Super oder Enter behält dadurch seine vorgesehene Bedeutung.
Zusammen machen diese Schutzmechanismen die Reihenfolge beim Loslassen der Modifikatortasten irrelevant. Genau diesen Teil machen die meisten Diktierkürzel falsch.
Die Wiederherstellung ist bewusst einfach:
~/.local/bin/voxtype-paradict recover
systemctl --user restart voxtype.service
Agentenanweisungen zum Kopieren
Richte Voxtype auf meinem Omarchy-System wie folgt ein:
- Nutze die installierten Omarchy-/Hyprland-Konventionen. Prüfe vor Änderungen
das laufende System, aktuelle Bindungen, Voxtype-Version und -Konfiguration
sowie die passende Befehlshilfe. Bearbeite niemals /usr/share/omarchy,
sondern nur die Konfiguration des Benutzers.
- Sichere jede geänderte Datei. Erhalte unabhängige Tastenkürzel. Prüfe aktuelle
Bindungen mit `omarchy menu keybindings --print` und entferne ausdrücklich
widersprüchliche Hyper+W- oder Standard-Voxtype-Bindungen vor dem Ersetzen.
- Hyper bedeutet Super+Shift+Control+Alt. Binde Drücken und Loslassen von
Hyper+W in ~/.config/hypr/bindings.lua. Ändere meine physische Hyper-/Caps-
Lock-Umbelegung nur auf Wunsch; möglicherweise übernimmt Kanata sie bereits.
- Hyper+W mindestens eine Sekunde halten: währenddessen aufnehmen, beim
Loslassen transkribieren und ohne Absenden einfügen.
- Hyper+W antippen: weiter aufnehmen. Enter muss in diesem Modus transkribieren,
einfügen, einmal absenden und sofort erneut aufnehmen. Einzelnes linkes oder
rechtes Super muss transkribieren, einfügen, absenden und stoppen. Erneutes
Hyper+W muss transkribieren, ohne Absenden einfügen und stoppen. Escape
bricht ab. F12 stellt den Ausgangszustand wieder her.
- Deaktiviere Voxtypes eigenes Tastenkürzel. Konfiguriere die Ausgabe über die
Zwischenablage mit mode="paste", paste_keys="shift+insert",
restore_clipboard=false, pre_type_delay_ms=100 und auto_submit=false.
Prüfe, dass wl-copy und wtype vorhanden sind.
- Implementiere ein kleines Steuerungsskript unter
~/.local/bin/voxtype-paradict und zwei Hyprland-Submaps:
voxtype_recording für Steuerungstasten und voxtype_suppress für sicheres
Einfügen bei noch gehaltenen Modifikatortasten.
- Binde unter Hyprland 0.56.2 die physische Haupt-Enter-Taste in
voxtype_recording als code:36 statt als symbolisches RETURN. Ergänze die
Enter-Taste des Ziffernblocks nur bei Bedarf.
- Mache die Hyper+W-Loslass-Bindung universell über Submaps hinweg. Füge nach
dem Antippen eine Aktivierungsverzögerung von 400 ms hinzu, damit das
Loslassen der auslösenden Hyper-Kombination nicht die Super-Stoppfunktion
auslöst. Serialisiere Übergänge mit flock, nutze monotone Zeit, warte auf
Voxtype-/Hyprland-Zustandsänderungen und setze beides bei Fehlern zurück.
- Prüfe mit `hyprctl reload` und `hyprctl configerrors`. Prüfe danach
`hyprctl binds` und bestätige code:36 in voxtype_recording. Starte den
Voxtype-Benutzerdienst neu und berichte über die endgültigen Bindungen,
Dateien, Sicherungen und den Wiederherstellungsbefehl. Teste Einfügen und
Absenden nicht im aktiven Agententerminal, sondern in einem entbehrlichen
Textfeld, oder überlasse mir diesen abschließenden interaktiven Test.
Die nützliche Aufgabenteilung ist einfach: Voxtype steuert Audio, Hyprland steuert Tasten und das Steuerungsskript steuert den Zustand.
Ergänze die Notizen
Kommentare werden erst geladen, wenn du sie anzeigen lässt. Der Kommentardienst nutzt Browser-Speicher für Einstellungen und Entwürfe sowie Cookies bei einer Anmeldung. Keine Werbung oder Analyse. Mit „Kommentare anzeigen“ erlaubst du diesen Speicher für die Kommentarfunktion.Datenschutzdetails.