def code_set_language_mode(language: str): """Sets the active language mode, and disables extension matching""" global forced_language actions.user.code_clear_language_mode() actions.mode.enable("user.{}".format(language)) app.notify("Enabled {} mode".format(language)) forced_language = True
def save_last_played(self): """Save the last recording played""" if self.last_played_recording: self.save_file(self.last_played_recording) app.notify(f"{self.last_played_recording} saved") else: app.notify("No played recordings? Nothing saved")
def toggle_notify(m): global NOTIFY NOTIFY = not NOTIFY icon = "✅ Notifications on" if not NOTIFY: icon = "❌ Notifications off" app.notify(body=f"{icon}")
def screenshot(): """takes a screenshot of the entire screen and saves it to the desktop as screenshot.png""" img = screen.capture_rect(screen.main_screen().rect) path = get_screenshot_path() img.write_file(path) app.notify(subtitle="Screenshot: %s" % path)
def fn(d): if "parsed" not in d.keys(): return words = d["parsed"]._unmapped if words[-1] in ABORT_WORDS and actions.speech.enabled(): d["parsed"]._sequence = [] app.notify(subtitle=f"Command aborted due to one of {ABORT_WORDS}")
def wake(self): self.sleeping = False app.notify(subtitle="waking from eye sleep state") if self.settings["sleep_mode"]: actions.speech.enable() if self.settings["suspend_screen"]: self.wake_screen()
def suspend(self): self.sleeping = True app.notify(subtitle="entering eye sleep state") if self.settings["sleep_mode"]: actions.speech.disable() if self.settings["suspend_screen"]: self.suspend_screen()
def set_voice_type(type): global voice_type, last_voice_type if voice_type != VoiceType.SLEEPING: last_voice_type = voice_type voice_type = type talon_enabled = type == VoiceType.TALON dragon_enabled = type == VoiceType.DRAGON dictation_enabled = type == VoiceType.DICTATION global speech speech.set_enabled(talon_enabled) global dictation_group if not dictation_enabled: dictation_group.disable() global engine if dragon_enabled: engine.mimic("wake up".split()) else: engine.mimic("go to sleep".split()) if dictation_enabled: # Without postponing this "go to sleep" will be printed dictation_group.enable() if voice_type != VoiceType.SLEEPING: return app.notify(body=spaghetti[type], sound=True) return app.notify(body=spaghetti[type], sound=False)
def mouse_toggle_control_mouse(): """Toggles control mouse""" if not config.control_mouse: app.notify(subtitle="Control mouse: ON") else: app.notify(subtitle="Control mouse: OFF") toggle_control(not config.control_mouse)
def microphone_select(index: int): """Selects a micropohone""" if 1 <= index and index <= len(microphone_device_list): actions.speech.set_microphone(microphone_device_list[index - 1]) app.notify("Activating microphone: {}".format( microphone_device_list[index - 1])) gui.hide()
def _notify_with_deadzone(title, message, deadzone=1): """Send a notification, unless another was sent recently.""" global _LAST_NOTIFICATION now = time.monotonic() if now > _LAST_NOTIFICATION + deadzone: _LAST_NOTIFICATION = now app.notify(title, message)
def screenshot_settings(): """Opens the settings UI for screenshots. Only applies to Mac for now """ if app.platform == "mac": actions.key("cmd-shift-5") else: app.notify("Not supported on this operating system")
def __init__(self, count=10): """Specify the number of default recording to list in the picker""" self.gui_open = False self.recordings_list = [] self.count = count self.recordings = pathlib.Path(TALON_HOME, "recordings/") if settings.get("speech.record_all") != 1: app.notify("Recording appears to be disabled")
def remove_last_saved(self): """Remove the last saved recording""" if self.last_saved_recording is not None: self.last_saved_recording.unlink(missing_ok=True) self.last_saved_recording = None app.notify(f"{self.last_saved_recording} removed") else: app.notify("No recording saved? Nothing removed")
def pop_quick_action_clear(): """Clears the quick macro""" global pop_quick_action global pop_quick_action_last if pop_quick_action: pop_quick_action_last = pop_quick_action pop_quick_action = None app.notify(subtitle="pop quick action cleared")
def code_clear_language_mode(): """Clears the active language mode, and re-enables code.language: extension matching""" global forced_language_mode forced_language_mode = False for __, lang in extension_lang_map.items(): actions.mode.disable("user.{}".format(lang)) app.notify(subtitle="Cleared language modes")
def setup_hat_styles_csv(): global unsubscribe_hat_styles ( color_enablement_settings, is_color_error, ) = actions.user.vscode_get_setting_with_fallback( "cursorless.hatEnablement.colors", default_value={}, fallback_value=FALLBACK_COLOR_ENABLEMENT, fallback_message= "Error finding color enablement; falling back to full enablement", ) ( shape_enablement_settings, is_shape_error, ) = actions.user.vscode_get_setting_with_fallback( "cursorless.hatEnablement.shapes", default_value={}, fallback_value=FALLBACK_SHAPE_ENABLEMENT, fallback_message= "Error finding shape enablement; falling back to full enablement", ) color_enablement = { **DEFAULT_COLOR_ENABLEMENT, **color_enablement_settings, } shape_enablement = { **DEFAULT_SHAPE_ENABLEMENT, **shape_enablement_settings, } active_hat_colors = { spoken_form: value for spoken_form, value in hat_colors.items() if color_enablement[value] } active_hat_shapes = { spoken_form: value for spoken_form, value in hat_shapes.items() if shape_enablement[value] } if unsubscribe_hat_styles is not None: unsubscribe_hat_styles() unsubscribe_hat_styles = init_csv_and_watch_changes( "hat_styles", { "hat_color": active_hat_colors, "hat_shape": active_hat_shapes, }, [*hat_colors.values(), *hat_shapes.values()], no_update_file=is_shape_error or is_color_error, ) if is_shape_error or is_color_error: app.notify("Error reading vscode settings. Restart talon; see log")
def read_file( path: Path, headers: list[str], default_identifiers: list[str], extra_ignored_values: list[str], allow_unknown_values: bool, ): with open(path) as f: lines = list(f) result = {} used_identifiers = [] has_errors = False seen_headers = False expected_headers = create_line(*headers) for i, raw_line in enumerate(lines): line = raw_line.strip() if not line or line.startswith("#"): continue if not seen_headers: seen_headers = True if line != expected_headers: has_errors = True csv_error(path, i, "Malformed header", line) print(f"Expected '{expected_headers}'") continue parts = line.split(",") if len(parts) != len(headers): has_errors = True csv_error(path, i, "Malformed csv entry", line) continue key = parts[0].strip() value = parts[1].strip() if (value not in default_identifiers and value not in extra_ignored_values and not allow_unknown_values): has_errors = True csv_error(path, i, "Unknown identifier", value) continue if value in used_identifiers: has_errors = True csv_error(path, i, "Duplicate identifier", value) continue result[key] = value used_identifiers.append(value) if has_errors: app.notify("Cursorless settings error; see log") return result, has_errors
def cycle_architecture(self): """Switch between supported architectures""" self.arch_index += 1 if self.arch_index == len(self.architectures): self.arch_index = 0 self.architecture = self.architectures[self.arch_index] # XXX - debugger ever has more tags, this will be a problem ctx.tags = [f"user.{self.architecture}"] app.notify(subtitle=f"Debug architecture: {self.architecture}")
def run_homophones_action(targets: dict): """Replaced target with next homophone""" texts = get_text(targets, show_decorations=False) try: updated_texts = list(map(lambda text: get_next_homophone(text), texts)) except LookupError as e: app.notify(str(e)) return actions.user.cursorless_replace(targets, updated_texts)
def mouse_toggle_zoom_mouse(): """Toggles zoom mouse setting""" eye_zoom_mouse.toggle_zoom_mouse(not eye_zoom_mouse.zoom_mouse.enabled) s = "Zoom mouse: " if eye_zoom_mouse.zoom_mouse.enabled: s += "ENABLED" else: s += "DISABLED" app.notify(subtitle=s)
def learn_jargon(m): with clip.capture() as s: press("cmd-c", wait=2000) meaning = s.get() # type: str if meaning: meaning = meaning.strip() key = " ".join(parse_words(m)) app.notify(f"learned {key}={meaning}") add_jargon(key, meaning)
def deactivate(): # dictation (prose mode) is not implemented through speech_toggle, but through changing context maps here and in std. context.unload() engine.mimic("talon deactivate emacs map".split()) engine.mimic("talon deactivate standard map".split()) dictation_map.update(toggle_map) context.keymap(dictation_map) context.load() app.notify("pros mode")
def on_phrase(j): global do_notify try: phrase = getattr(j["parsed"], "_unmapped", j["phrase"]) phrase = " ".join(word.split("\\")[0] for word in phrase) if do_notify: app.notify(phrase) except: pass
def activate(): context.unload() engine.mimic("talon activate emacs map".split()) engine.mimic("talon activate standard map".split()) org_map.update(toggle_map) context.keymap(org_map) context.load() app.notify("edit mode")
def cycle_datatype(self): """Switch between supported datatypes""" # actions.mode.disable(f"user.{self.architecture}") self.datatype_index += 1 if self.datatype_index == len(self.datatypes): self.datatype_index = 0 self.datatype = self.datatypes[self.datatype_index] ctx.tags = [f"user.{self.datatype}"] app.notify(subtitle=f"Cycled to C lang datatype: {self.datatype}")
def personal_info_select(number: int): """selects the personal_info by number""" if number <= len(personal_info_list) and number > 0: return personal_info_list[number - 1] error = "personal_info.py index {} is out of range (1-{})".format( number, len(personal_info_list)) app.notify(error) raise error
def raise_homophones(word_to_find_homophones_for, forced=False, selection=False): global quick_replace global active_word_list global show_help global force_raise global is_selection force_raise = forced is_selection = selection if is_selection: word_to_find_homophones_for = word_to_find_homophones_for.strip() formatter = find_matching_format_function(word_to_find_homophones_for, PHONES_FORMATTERS) word_to_find_homophones_for = word_to_find_homophones_for.lower() # We support plurals, but very naively. If we can't find your word but your word ends in an s, presume its plural # and attempt to find the singular, then present the presumed plurals back. This could be improved! if word_to_find_homophones_for in all_homophones: valid_homophones = all_homophones[word_to_find_homophones_for] elif word_to_find_homophones_for[ -1] == 's' and word_to_find_homophones_for[:-1] in all_homophones: valid_homophones = map( lambda w: w + 's', all_homophones[word_to_find_homophones_for[:-1]]) else: app.notify("homophones.py", '"%s" not in homophones list' % word_to_find_homophones_for) return # Move current word to end of list to reduce searcher's cognitive load valid_homophones_reordered = (list( filter( lambda word_from_list: word_from_list.lower() != word_to_find_homophones_for, valid_homophones)) + [word_to_find_homophones_for]) active_word_list = list(map(formatter, valid_homophones_reordered)) if (is_selection and len(active_word_list) == 2 and quick_replace and not force_raise): if word_to_find_homophones_for == active_word_list[0].lower(): new = active_word_list[1] else: new = active_word_list[0] clip.set(new) actions.edit.paste() return actions.mode.enable("user.homophones") show_help = False gui.show()
def homophones_select(number: int) -> str: """selects the homophone by number""" if number <= len(active_word_list) and number > 0: return active_word_list[number - 1] error = "homophones.py index {} is out of range (1-{})".format( number, len(active_word_list)) app.notify(error) raise error
def insert_cursor(text: str): """Insert a string. Leave the cursor wherever [|] is in the text""" if "[|]" in text: actions.user.insert_between(*text.split("[|]", 1)) else: actions.insert(text) app.notify( "insert_cursor is deprecated, please update your code to use insert_between" )