def _update_symbols(state): """Update the currently active symbols.""" global context # TODO: Maybe add a hard cap on the total number here? Might be better to do # that in Emacs, but I think I want redundancy. symbols = state.get(ACTIVE_SYMBOLS_KEY, []) whole_symbols = {} symbol_sections = {} for symbol in symbols: # TODO: Clean up the `lower` calls here. Pull them into `spoken_form`. separated = separate_words(symbol) if len(separated) > 1: whole_symbols[spoken_form(separated).lower()] = separated.lower() for component in separated.split(" "): # TODO: Don't allow clashes here? E.g. "Target" & "target". Might # not need to, Talon might optimize them. symbol_sections[spoken_form( component).lower()] = component.lower() LOGGER.debug(whole_symbols) LOGGER.debug( "Updating Emacs symbols: {} symbols, {} sections added.".format( len(whole_symbols), len(symbol_sections), )) context.lists["user.active_symbols"] = whole_symbols
def _extract_mode_commands(all_commands: List[str]) -> List[str]: """Extract the major- and minor-mode commands from `all_commands`.""" mode_commands = {} for command in all_commands: if command.endswith("-mode"): mode_commands[spoken_form(command)] = command return mode_commands
def action_command(action: str) -> str: """Create a spoken form of a particular action.""" if action.startswith("it-"): action = action[3:] # Go implies movement. It's unnecessary. if action.startswith("go-"): action = action[3:] return utils.spoken_form(action)
def _update_words(state): words = {} window_strings = state.get("visible-text", []) for window_string in window_strings: spoken_map = { spoken_form(word): word for word in _extract_words(window_string) } words.update(spoken_map) context.lists["user.selectable_words"] = words
def _speech_snippet_list(state): """Extract active snippets, in speakable form.""" new_snippets = {} snippet_tables = state.get(SNIPPET_TABLES_KEY, {}) active_tables = state.get(ACTIVE_TABLES_KEY, []) for table_name in active_tables: for snippet in snippet_tables.get(table_name, []): key = snippet["key"] name = snippet["name"] spoken_name = spoken_form(name) spoken_key = spoken_form(key) if spoken_key: new_snippets[spoken_key] = name # Names are generally a better way to speak a snippet. Update names # second so they override keys when there's a clash. # # Note it's possible that by converting to spoken form, we create # identical spoken references to different snippets. Those clashes # will need to be renamed. if spoken_name: new_snippets[spoken_name] = name return new_snippets
def object_bindings(object_tables): simple_commands, prefix_commands, wrap_commands = {}, {}, {} # `object_tables` structure: # {"python-mode": {"type-1": <object>, # "type-2": <object>} # "global": {"type-1": <object>}} for mode, objects in object_tables.items(): # TODO: This method will redefine multiple times for objects in # multiple tables. for object_ in objects: # `object_` structure: # {"name": <str>, # "available-actions": <List[action_set]>} object_name = object_["name"] speakable_name = utils.spoken_form(object_name) action_sets = object_["available-actions"] # Emacs uses "mark", so manually add another selection command mark_command = f"it-mark-{object_name}" simple_commands[f"select {speakable_name}"] = mark_command simple_commands[f"sell {speakable_name}"] = mark_command for action_set in action_sets: # `action_set` structure: # {"action": <str>, # "command": <str>, # "takes-prefix": <bool>} target_map = ( prefix_commands if action_set["takes-prefix"] else simple_commands ) # Just a super simp spoken form for now. action = action_set["action"] # TODO: Cache this? Regenerating for every object. speakable_action = action_command(action) emacs_command = action_set["command"] # Long command long_command = f"{speakable_action} {speakable_name}" target_map[long_command] = emacs_command # Short command for short_command in short_commands(object_name, action): # HACK: Special commands for wrapping that can take a character. # TODO: Make regular wrap available eventually if action == "it-wrap": wrap_commands[short_command] = object_name else: target_map[short_command] = emacs_command return simple_commands, prefix_commands, wrap_commands
def _split_name(text): # Note "dot" is special here, e.g. "formatting.py" should be # "formatting dot py", not "formatting py" return spoken_form(separate_words(text).replace(".", " dot ")).split(" ")
"parens": "( ) left", "braces": "{ } left", "angles": "< > left", # TODO: Audit this with w2l once off Dragon. "loon" may be better # "loon": "end enter", "break": "end enter", "backtab": "shift-tab", }) f_keys = { # Auto-generate 1-9 **{spoken_form(f"F {i}"): f"{i}" for i in range(1, 9)}, "F ten": "f10", "F eleven": "f11", "F twelve": "f12", } keys = {**simple_keys, **alternate_keys, **f_keys} ctx.lists["self.special"] = keys complex_symbols = multi_map({ ("walrus", "wally"): ":=", "rittoe": "->", "leffoe": "<-", "riteek": "=>", "leffeek": "<=", })