from talon.voice import Context, Key from ..misc.switcher import switch_app ctx = Context("outlook") ctx.keymap( { "reply to e-mail": Key("cmd-r"), "send e-mail": Key("cmd-enter"), "clear flag": None, "next pain": Key("shift-ctrl-["), "preev pain": Key("shift-ctrl-]"), "dismiss outlook": [lambda m: switch_app(name="outlook"), Key("cmd-w")], } ) """ pack = Packages.register name: "custom outlook" applications: ["com.microsoft.Outlook"] description: "custom commands for outlook" pack.commands "reply-to-email": spoken: "reply to e-mail" misspoken: 'reply email' description: "reply to email" enabled: true action: (input) -> @key 'r', 'command'
from talon.voice import Key, press, Str, Context # Move and resize windows with Spectacle.app ctx = Context('spectacle') keymap = { 'windy center': Key('cmd-alt-f'), 'windy max': Key('cmd-alt-f'), 'windy left': Key('cmd-alt-left'), 'windy right': Key('cmd-alt-right'), 'windy up': Key('cmd-alt-up'), 'windy down': Key('cmd-alt-down'), 'windy upper left': Key('cmd-ctrl-left'), 'windy lower left': Key('cmd-ctrl-shift-left'), 'windy upper right': Key('cmd-ctrl-right'), 'windy lower right': Key('cmd-ctrl-shift-right'), 'windy next display': Key('cmd-ctrl-alt-right'), 'windy previous display': Key('cmd-ctrl-alt-left'), 'windy next third': Key('ctrl-alt-right'), 'windy previous third': Key('ctrl-alt-left'), 'windy larger': Key('shift-ctrl-alt-right'), 'windy smaller': Key('shift-ctrl-alt-left'), 'windy undo': Key('cmd-alt-z'),
""" """ from talon.voice import Context, Key, press from ..utils import text, numeral_list, extract_num_from_m import time ctx = Context("general_lang") ctx.set_list("n", numeral_list) def back_n(m): n = extract_num_from_m(m, 1) if n > 10: n = 10 for i in range(0, n): press("backspace") time.sleep(0.025) ctx.keymap({ # Vim-like Editor # "debug line": ["Idbg!(", Key("esc"), "$i)", Key("esc"), "0e"], "fix me [<dgndictation>]": ["// FIXME: ", text], "to do [<dgndictation>]": ["// TODO: ", text], "line down": "o", "line up": "O", "jump up":
def press_keys(m): mods = get_modifiers(m) keys = get_keys(m) if mods == ["shift"] and all(key in alphabet.values() for key in keys): return uppercase_letters(m) if mods: press("-".join(mods + [keys[0]])) keys = keys[1:] for k in keys: press(k) ctx = Context("basic_keys") ctx.keymap( { "(uppercase | ship | sky) {basic_keys.alphabet}+ [(lowercase | lower | sunk)]": uppercase_letters, "{basic_keys.modifiers}* {basic_keys.alphabet}+": press_keys, "{basic_keys.modifiers}* {basic_keys.digits}+": press_keys, "{basic_keys.modifiers}* {basic_keys.keys}+": press_keys, "(go | {basic_keys.modifiers}+) {basic_keys.arrows}+": press_keys, "number {basic_keys.digits}+ [over]": press_keys, "tarsh": Key("shift-tab"), "tarpy": [Key("tab"), Key("tab")], } ) ctx.set_list("alphabet", alphabet.keys()) ctx.set_list("digits", digits.keys()) ctx.set_list("keys", keys.keys())
from talon.voice import Context, Key from ..utils import text # Note that there are no application or window filters on this context because # git may need to be used outside of the terminal, such as in a browser # terminal, or you may need to send git commands to your friends to help them # out with their git troubles. ctx = Context("git") ctx.keymap({ # TODO: remove duplication between the two groups of commands as we really # only need one set of commands (eg by completing github issue #40 (use a # more comprehensive git grammar)) # git commands originally from std.py "run get": "git ", "run get (R M | remove)": "git rm ", "run get add": "git add ", "run get bisect": "git bisect ", "run get branch": "git branch ", "run get checkout": "git checkout ", "run get clone": "git clone ", "run get commit": "git commit ",
# From https://github.com/talonvoice/examples from talon_plugins import eye_mouse from talon.voice import Context ctx = Context('eye_control') ctx.keymap({ 'debug overlay': lambda m: eye_mouse.debug_overlay.toggle(), 'control mouse': lambda m: eye_mouse.control_mouse.toggle(), 'camera overlay': lambda m: eye_mouse.camera_overlay.toggle(), 'run calibration': lambda m: eye_mouse.calib_start(), })
from talon.voice import Key, press, Str, Context # Commands for annotating pdfs. ctx = Context('pomodoro') keymap = { 'pomodoro': Key('cmd-shift-r'), } ctx.keymap(keymap)
######################################################################## # global settings ######################################################################## # a list of homophones where each line is a comma separated list # e.g. where,wear,ware # a suitable one can be found here: # https://github.com/pimentel/homophones cwd = os.path.dirname(os.path.realpath(__file__)) homophones_file = os.path.join(cwd, "homophones.csv") # if quick_replace, then when a word is selected and only one homophone exists, # replace it without bringing up the options quick_replace = True ######################################################################## context = Context("homophones") pick_context = Context("pick") phones = {} canonical = [] with resource.open(homophones_file, "r") as f: for h in f: h = h.rstrip() h = h.split(",") canonical.append(max(h, key=len)) for w in h: w = w.lower() others = phones.get(w, None) if others is None: phones[w] = sorted(h) else:
import time import talon.clip as clip from talon.voice import Key, press, Str, Context from ..utils import ( parse_words, join_words, is_not_terminal, numeral_list, extract_num_from_m, optional_numerals, repeat_function, ) ctx = Context("generic_editor", func=is_not_terminal) # ctx.set_list("n", numeral_list) def find_next(m): press("cmd-f") Str(str(m.dgndictation[0]._words[0]))(None) press("escape") def find_previous(m): press("left") press("cmd-f") Str(str(m.dgndictation[0]._words[0]))(None) press("cmd-shift-g") press("escape")
# app.notify('Function name:', body=name) path = launch.get(name) if path: ui.launch(path=path) # def launch_rstudio(): # press('cmd-space') # Key('r s t u') # press('enter') def launch_rstudio(*unneeded): path = launch.get('RStudio') ui.launch(path=path) ctx = Context('switcher') ctx.keymap({ 'fox {switcher.running}': switch_app, 'launch {switcher.launch}': launch_app, ## open RStudio with an Australian accent 'asked judy': launch_rstudio, }) def update_lists(): global running global launch new = {} for app in ui.apps(): if app.background and not app.windows():
def build_text_action_keymap(): keymap = {} for verb, verb_actions in select_verbs.items(): # Dict comprehension? for obj, obj_actions in select_objects.items(): keymap[f"{verb} {obj}"] = obj_actions + verb_actions for verb, verb_actions in movement_verbs.items(): # Dict comprehension? for obj, obj_actions in movement_objects.items(): keymap[f"{verb} {obj}"] = obj_actions + verb_actions return keymap keymap = build_text_action_keymap() # group = ContextGroup("jetbrains") ctx = Context("jetbrains", func=is_real_jetbrains_editor) # , group=group) keymap.update({ # Misc verbs "complete": [idea("action CodeCompletion")], "perfect": [idea("action CodeCompletion", "action CodeCompletion")], # perfect == extra complete "smart": [idea("action SmartTypeCompletion")], # Variants which take text? Replaced mostly with "call" formatter. # "complete <dgndictation> [over]": [idea("action CodeCompletion"), text], # "smart <dgndictation> [over]": [idea("action SmartTypeCompletion"), text], "finish": idea("action EditorCompleteStatement"), "done": idea("action EditorCompleteStatement"), "toggle tools": idea("action HideAllWindows"),
from talon.voice import Context, Key, Str, press from talon import clip ctx = Context('clipboard') def get_selection(): with clip.capture() as s: press('cmd-c', wait=0) return s.get() def apply_to_line(fn): def wrap(m): press('shift-alt-left') sel = get_selection() Str(fn(sel))(None) return wrap ctx.keymap({ 'run caps': apply_to_line(lambda s: s.capitalize()), 'run yeller': apply_to_line(lambda s: s.upper()), })
from talon.voice import Context, Key ctx = Context('trello', bundle='com.atlassian.trello') keymap = { '(quick add | add)': Key('ctrl-alt-space'), 'boards': Key('b'), 'search': Key('/'), 'archive': Key('c'), 'due date': Key('d'), 'edit': Key('e'), 'cancel': Key('esc'), 'save': Key('cmd-enter'), 'open card': Key('enter'), 'create open': Key('shift-enter'), 'filter': Key('f'), 'toggle label': Key(';'), '(add | remove) members': Key('m'), 'new card': Key('n'), 'move card left': Key(','), 'move card right': Key('.'), 'my cards': Key('q'), '(watch | unwatch) card': Key('s'), '(assign | unassign) me': Key('space'), 'edit title': Key('t'), 'vote': Key('v'), '[| toggle] board menu': Key('w'), 'clear filters': Key('x'), 'shortcuts': Key('?'), 'member': Key('@'), 'tag label': Key('#'),
from talon.voice import Context, Key, press from talon import ctrl ctx = Context( "google_slides", func=lambda app, win: win.title.endswith("- Google Slides") or "- Google Slides -" in win.title, ) ctx.keymap( { "new slide": Key("ctrl+m"), "dup slide": Key("cmd+d"), "copy format": Key("cmd+alt+c"), "paste format": Key("cmd+alt+v"), "(insert | edit) link": Key("cmd+k"), "open link": Key("alt+enter"), "select all": Key("cmd+a"), "select none": Key("cmd+shift+a"), "find": Key("cmd+f"), "find and replace": Key("cmd+shift+h"), "find again": Key("cmd+g"), "find previous": Key("cmd+shift+g"), "open": Key("cmd+o"), "print": Key("cmd+p"), "save": Key("cmd+s"), "[keyboard] shortcuts": Key("cmd+/"), "slides menu [help]": Key("alt+/"), "menus ": Key("ctrl+shift+f"), "(previous | last) slide": Key("up"), "next slide": Key("down"), "first slide": Key("home"),
from talon import ui from talon.voice import Key, Context single_digits = "0123456789" NAMED_DESKTOPS = {digit: int(digit) for digit in single_digits} NAMED_DESKTOPS.update({ # "gmail": 1, # "slack": 2, }) ctx = Context( "amethyst", func=lambda app, win: bool(ui.apps(bundle="com.amethyst.Amethyst"))) keymap = { # 'desk <dgndictation>': desk, "window next screen": Key("ctrl-alt-shift-l"), "window (previous|prev) screen": Key("ctrl-alt-shift-h"), "window next": Key("alt-shift-j"), "window previous": Key("alt-shift-k"), "window move desk": Key("ctrl-alt-shift-h"), "window full": Key("alt-shift-d"), "window tall": Key("alt-shift-a"), "window middle": Key("alt-shift-`"), "window move main": Key("alt-shift-enter"), "window grow": Key("alt-shift-l"), "window shrink": Key("alt-shift-h"), } keymap.update({ "desk %s" % name: Key("ctrl-%s" % NAMED_DESKTOPS[name])
overrides = {"from": "Google Chrome"} def switch_app(m): name = str(m[1]) full = apps.get(name) if not full: return for app in ui.apps(): if app.name == full: app.focus() break ctx = Context("switcher") keymap = {"(focus | folk) {switcher.apps}": switch_app} ctx.keymap(keymap) def update_lists(): global apps new = {} for app in ui.apps(): words = app.name.split(" ") for word in words: if word and not word in new: new[word] = app.name new[app.name] = app.name for override in overrides: new[override] = overrides[override]
# Assuming https://addons.mozilla.org/en-US/firefox/addon/tab_search/?src=search # Ctrl + Shift + F - Toggle extension (Windows/Linux) # Cmd + Shift + L - Toggle extension (macOS) # Ctrl + Backspace - Delete tab # Enter - Open selected tab or first in list if not selected # Up/Left - Select previous tab # Down/Right - Select next tab # Alt + R - Refresh tab # Alt + P - Pin tab # Ctrl + C - Copy Tab URL # Alt + Shift + D - Delete all duplicate tabs # Alt + M - Mute (only if tab is audible) # # ctx = Context("firefox", func=is_firefox) ctx.keymap({ "(follow | go link)": Key("ctrl-,"), "go tab": Key("ctrl-."), "go back": Key("cmd-["), "go forward": Key("cmd-]"), "clear tab": Key("cmd-w"), "restore tab": Key("cmd-shift-t"), "jump [<dgndictation>] [over]": [ Key("cmd-shift-l"),
from talon.voice import Key, Context ctx = Context("sublime", bundle="com.sublimetext.3") keymap = { "(trundle | comment) super": Key("cmd-alt-/"), # general "sidebar": [Key("cmd-k"), Key("cmd-b")], "(subl | sublime) (focus | folk) sidebar": Key("ctrl-0"), "console": Key("ctrl-`"), "[command] pallet": Key("cmd-shift-p"), "(column | row) one": Key("alt-cmd-1"), "column two": Key("alt-cmd-2"), "column three": Key("alt-cmd-3"), "row two": Key("shift-alt-cmd-2"), "row three": Key("shift-alt-cmd-3"), "grid": Key("alt-cmd-5"), # window "(subl | sublime) new window": Key("shift-cmd-n"), # close window # file "(save | safe) all": Key("cmd-alt-s"), "revert": Key("ctrl-alt-r"), # requires adding key binding "go file": Key("cmd-t"), # selection "(select line | shackle)": Key("cmd-l"), "(select | cell) word": Key("cmd-d"), "all word": Key("cmd-ctrl-g"), # expand currently selected word to all "(select | cell) current": Key("ctrl-cmd-g"), # select all occurrences of current selection "(select | cell) scope": Key("shift-cmd-space"),
from talon.voice import Key, press, Str, Context ctx = Context('generic_editor') # , bundle='com.microsoft.VSCode') numeral_map = dict((str(n), n) for n in range(0, 20)) for n in [20, 30, 40, 50, 60, 70, 80, 90]: numeral_map[str(n)] = n numeral_map["oh"] = 0 # synonym for zero numerals = ' (' + ' | '.join(sorted(numeral_map.keys())) + ')+' optional_numerals = ' (' + ' | '.join(sorted(numeral_map.keys())) + ')*' def text_to_number(m): tmp = [str(s).lower() for s in m.dgndictation[0]._words] words = [parse_word(word) for word in tmp] result = 0 factor = 1 for word in reversed(words): if word not in numerals: raise Exception('not a number') result = result + factor * int(numeral_map[word]) factor = 10 * factor return result def parse_word(word):
# Talon voice commands for interacting with Postbox mail # James Turnbull [email protected] from talon.voice import Key, Context ctx = Context("postbox", bundle="com.postbox-inc.postbox") ctx.keymap({ "new mail": Key("cmd-n"), "send mail": Key("cmd-shift-d"), "reply mail": Key("cmd-r"), "reply all": Key("shift-cmd-r"), "forward mail": Key("cmd-l"), "mark unread": Key("m"), "mark read": Key("r"), "star": Key("s"), "delete mail": Key("backspace"), "archive mail": Key("a"), "next mail": Key("f"), "previous mail": Key("b"), "next unread": Key("n"), "previous unread": Key("p"), "top list": Key("fn-left"), "bottom list": Key("fn-right"), })
from talon.voice import Context, Key ctx = Context("random") # this is a mapping for scrolling and other mouse utilities # # keymap = { # # scrolling # "scroll down": [Key("down")] * 30, # "scroll up": [Key("up")] * 30, # # NB home and end do not work in all apps # "(scroll way down | doomway)": Key("cmd-down"), # "(scroll way up | jeepway)": Key("cmd-up"), # "page up": [Key("pageup")], # "page down": [Key("pagedown")], # # searching # "(search | marco)": Key("cmd-f"), # "marneck": Key("cmd-g"), # "marpreev": Key("cmd-shift-g"), # "marthis": [Key("alt-right"), Key("shift-alt-left"), Key("cmd-f"), Key("enter")], # } keymap = {"2pull": ["tuple"]} ctx.keymap(keymap)
def uppercase_letters(m): insert(''.join(get_keys(m)).upper()) def press_keys(m): mods = get_modifiers(m) keys = get_keys(m) if mods: press('-'.join(mods + [keys[0]])) keys = keys[1:] for k in keys: press(k) ctx = Context('basic_keys') ctx.keymap({ '(uppercase | ship | sky | yeller | yellsmash) {basic_keys.alphabet}+ [(lowercase | sunk | squash | lower | smash)]': uppercase_letters, '{basic_keys.modifiers}* {basic_keys.alphabet}+': press_keys, '{basic_keys.modifiers}* {basic_keys.digits}+': press_keys, '{basic_keys.modifiers}* {basic_keys.keys}+': press_keys, '(go | {basic_keys.modifiers}) {basic_keys.arrows}+': press_keys, }) ctx.set_list('alphabet', alphabet.keys()) ctx.set_list('arrows', arrows.keys()) ctx.set_list('digits', digits.keys())
""" This module contains generic repeat commands that can be used following any other command, e.g. "go down" or "delete" x many times. The repeat commands are the ordinal representation of the total number of times to execute the command, so "go down 4th" will go down 4 times. A few reasons to use ordinals: - Regular numbers are already heavily used - Made up words are difficult to learn and remember - Ordinals don't need to be memorized - Ordinals are not likely to collide with other commands """ from talon.voice import Context, Rep, talon ctx = Context("repeater") ordinals = {} def ordinal(n): """ Convert an integer into its ordinal representation:: ordinal(0) => '0th' ordinal(3) => '3rd' ordinal(122) => '122nd' ordinal(213) => '213th' """ n = int(n) suffix = ["th", "st", "nd", "rd", "th"][min(n % 10, 4)] if 11 <= (n % 100) <= 13: suffix = "th"
try: words = normalize(s.get()).split() except clip.NoChange: words = [] if not words: words = [""] return fmt, words def sponge_format(m): _, words = extract_formatter_and_words(m) dictation = " ".join(words) result = [] caps = True for c in dictation: if c == " ": result.append(c) continue result.append(c.upper() if caps else c.lower()) caps = not caps insert("".join(result)) ctx = Context("formatters") # ctx.vocab = vocab + list(jargon_substitutions.keys()) ctx.keymap( { "this" + f"({' | '.join(formatters)})+": format_text, f"({' | '.join(formatters)})+ <dgndictation>+ [over]": format_text, "sponge [<dgndictation>] [over]": sponge_format, } )
from talon.voice import Key, Context ctx = Context("iterm", bundle="com.googlecode.iterm2") keymap = { "preferences": Key("cmd-,"), "[toggle] full-screen": Key("cmd-shift-enter"), "exit session": [Key("ctrl-c"), "exit\n"], "broadcaster": Key("cmd-alt-i"), "clear session": [Key("ctrl-c"), "clear\n"], "clean": Key("cmd-k"), "split horizontal": Key("cmd-shift-d"), "split vertical": Key("cmd-d"), "next (split | pane)": Key("cmd-]"), "last (split | pane)": Key("cmd-["), "max (split | pane)": Key("shift-cmd-enter"), "move tab left": Key("shift-cmd-left"), "move tab right": Key("shift-cmd-right"), "(subble | subtle)": "subl ", "(scratch | scrap)": Key("ctrl-u"), "(shell | i term )search": Key("cmd-f"), "jump back": Key("ctrl-[ b"), "jump [forward]": Key("ctrl-] f"), "rerun": [Key("up"), Key("enter")], "sky": Key("cmd-ctrl-pageup"), "floor": Key("cmd-ctrl-pagedown"), "paste history": Key("shift-cmd-h"), # these require some changes to preferences: # https://coderwall.com/p/h6yfda/use-and-to-jump-forwards-backwards-words-in-iterm-2-on-os-x "(shall | shell) (stone | jack)": Key("alt-b"),
# from https://github.com/talonvoice/examples # jsc added shift-click, command-click, and voice code compatibility # import eye import time from talon import ctrl, tap, ui from talon.voice import Context ctx = Context("mouse") x, y = ctrl.mouse_pos() mouse_history = [(x, y, time.time())] force_move = None def on_move(typ, e): mouse_history.append((e.x, e.y, time.time())) if force_move: e.x, e.y = force_move return True tap.register(tap.MMOVE, on_move) def click_pos(m): word = m._words[0] start = (word.start + min((word.end - word.start) / 2, 0.100)) / 1000.0 diff, pos = min([(abs(start - pos[2]), pos) for pos in mouse_history]) return pos[:2]
from talon.voice import Context, Key ctx = Context('slack', bundle='com.tinyspeck.slackmacgap') keymap = { 'channel': Key('cmd-k'), 'channel last': Key('alt-up'), 'channel next': Key('alt-down'), 'tools command': ['``', Key('left')], 'tools code': ['``````', Key('left left left return return up')], } ctx.keymap(keymap)
######################################################################## # global settings ######################################################################## # a list of homophones where each line is a comma separated list # e.g. where,wear,ware # a suitable one can be found here: # https://github.com/pimentel/homophones cwd = os.path.dirname(os.path.realpath(__file__)) homophones_file = os.path.join(cwd, "homophones.csv") # if quick_replace, then when a word is selected and only one homophone exists, # replace it without bringing up the options quick_replace = True ######################################################################## context = Context("fast_homophones") phones = {} canonical = [] with resource.open(homophones_file, "r") as f: for h in f: h = h.rstrip() h = h.split(",") canonical.append(max(h, key=len)) for w in h: w = w.lower() others = phones.get(w, None) if others is None: phones[w] = sorted(h) else: # if there are multiple hits, collapse them into one list
# Talon voice commands for Xcode # John S. Cooper [email protected] from talon.voice import Key, Context ctx = Context('xcode', bundle='com.apple.dt.Xcode') ctx.keymap({ '(build it | chom brov)': Key('cmd-b'), '(stop it | chom peer)': Key('cmd-.'), '(run it | chom rosh)': Key('cmd-r'), 'go back': Key('cmd-ctrl-left'), 'go fore': Key('cmd-ctrl-right'), 'find in proj': Key('cmd-shift-f'), '(sell find in proj | find selection in project)': Key('cmd-e cmd-shift-f enter'), '(sell find ace in proj | replace selection in project)': Key('cmd-e cmd-shift-alt-f'), 'split window': Key('cmd-alt-enter'), 'show editor': Key('cmd-enter'), '(show | hide) debug': Key('cmd-shift-y'), '(show | hide) navigator':
for i, word in enumerate(words): word = parse_word(word) for name in reversed(fmt): smash, func = formatters[name] word = func(i, word, i == len(words) - 1) spaces = spaces and not smash tmp.append(word) words = tmp sep = ' ' if not spaces: sep = '' Str(sep.join(words))(None) ctx = Context('input') keymap = {} keymap.update(alpha) keymap.update({ 'phrase <dgndictation> [over]': text, # 'go <dgndictation> [over]': text, # 'word <dgnwords>': word, # 'sentence <dgndictation> [over]': sentence_text, # 'sent <dgndictation> [over]': sentence_text, 'champ <dgndictation> [over]': sentence_text, 'comma <dgndictation> [over]': [', ', text], 'period <dgndictation> [over]': ['. ', sentence_text], 'more <dgndictation> [over]': [' ', text],