192 lines
6.5 KiB
Python
192 lines
6.5 KiB
Python
from talon import Module, actions, settings
|
|
|
|
from .edit_command_actions import EditAction, EditSimpleAction, run_action_callback
|
|
from .edit_command_modifiers import EditModifier, run_modifier_callback
|
|
|
|
mod = Module()
|
|
|
|
# providing some settings for customizing the word and line selection delay
|
|
# talon can execute selections must faster than a human
|
|
# resulting in unexpected or inconsistent results in applications such as visual studio code
|
|
mod.setting(
|
|
"edit_command_word_selection_delay",
|
|
type=int,
|
|
default=75,
|
|
desc="Sleep required between word selections",
|
|
)
|
|
|
|
mod.setting(
|
|
"edit_command_line_selection_delay",
|
|
type=int,
|
|
default=75,
|
|
desc="Sleep required between line selections",
|
|
)
|
|
|
|
|
|
def before_line_up():
|
|
actions.edit.up()
|
|
actions.edit.line_start()
|
|
|
|
|
|
def after_line_up():
|
|
actions.edit.up()
|
|
actions.edit.line_end()
|
|
|
|
|
|
def before_line_down():
|
|
actions.edit.down()
|
|
actions.edit.line_start()
|
|
|
|
|
|
def after_line_down():
|
|
actions.edit.down()
|
|
actions.edit.line_end()
|
|
|
|
|
|
def select_lines(action, direction, count):
|
|
if direction == "lineUp":
|
|
selection_callback = actions.edit.extend_line_up
|
|
extend_line_callback = actions.edit.extend_line_start
|
|
else:
|
|
selection_callback = actions.edit.extend_line_down
|
|
extend_line_callback = actions.edit.extend_line_end
|
|
|
|
selection_delay = f"{settings.get('user.edit_command_line_selection_delay')}ms"
|
|
|
|
for i in range(1, count + 1):
|
|
selection_callback()
|
|
actions.sleep(selection_delay)
|
|
|
|
# ensure we take the start/end of the line too!
|
|
extend_line_callback()
|
|
actions.sleep(selection_delay)
|
|
run_action_callback(action)
|
|
|
|
|
|
def select_words(action, direction, count):
|
|
if direction == "wordLeft":
|
|
selection_callback = actions.edit.extend_word_left
|
|
else:
|
|
selection_callback = actions.edit.extend_word_right
|
|
|
|
selection_delay = f"{settings.get('user.edit_command_word_selection_delay')}ms"
|
|
for i in range(1, count + 1):
|
|
selection_callback()
|
|
actions.sleep(selection_delay)
|
|
|
|
run_action_callback(action)
|
|
|
|
|
|
def word_movement_handler(action, direction, count):
|
|
if direction == "wordLeft":
|
|
movement_callback = actions.edit.word_left
|
|
else:
|
|
movement_callback = actions.edit.word_right
|
|
|
|
selection_delay = f"{settings.get('user.edit_command_word_selection_delay')}ms"
|
|
for i in range(1, count + 1):
|
|
movement_callback()
|
|
actions.sleep(selection_delay)
|
|
|
|
|
|
# in some cases, it is necessary to have some custom handling for timing reasons
|
|
custom_callbacks = {
|
|
("goAfter", "wordLeft"): word_movement_handler,
|
|
("goAfter", "wordRight"): word_movement_handler,
|
|
("goBefore", "wordLeft"): word_movement_handler,
|
|
("goBefore", "wordRight"): word_movement_handler,
|
|
# delete
|
|
("delete", "word"): select_words,
|
|
("delete", "wordLeft"): select_words,
|
|
("delete", "wordRight"): select_words,
|
|
("delete", "lineUp"): select_lines,
|
|
("delete", "lineDown"): select_lines,
|
|
# cut
|
|
("cutToClipboard", "word"): select_words,
|
|
("cutToClipboard", "wordLeft"): select_words,
|
|
("cutToClipboard", "wordRight"): select_words,
|
|
("cutToClipboard", "lineUp"): select_lines,
|
|
("cutToClipboard", "lineDown"): select_lines,
|
|
# copy
|
|
("copyToClipboard", "word"): select_words,
|
|
("copyToClipboard", "wordLeft"): select_words,
|
|
("copyToClipboard", "wordRight"): select_words,
|
|
("copyToClipboard", "lineUp"): select_lines,
|
|
("copyToClipboard", "lineDown"): select_lines,
|
|
# select
|
|
("select", "lineUp"): select_lines,
|
|
("select", "lineDown"): select_lines,
|
|
}
|
|
|
|
# In other cases there already is a "compound" talon action for a given action and modifier
|
|
compound_actions = {
|
|
# select
|
|
("select", "wordLeft"): actions.edit.extend_word_left,
|
|
("select", "wordRight"): actions.edit.extend_word_right,
|
|
("select", "left"): actions.edit.extend_left,
|
|
("select", "right"): actions.edit.extend_right,
|
|
("select", "word"): actions.edit.extend_word_right,
|
|
# Go before
|
|
("goBefore", "line"): actions.edit.line_start,
|
|
("goBefore", "lineUp"): before_line_up,
|
|
("goBefore", "lineDown"): before_line_down,
|
|
("goBefore", "paragraph"): actions.edit.paragraph_start,
|
|
("goBefore", "document"): actions.edit.file_start,
|
|
("goBefore", "fileStart"): actions.edit.file_start,
|
|
("goBefore", "selection"): actions.edit.left,
|
|
("goBefore", "wordLeft"): actions.edit.word_left,
|
|
("goBefore", "word"): actions.edit.word_left,
|
|
# Go after
|
|
("goAfter", "line"): actions.edit.line_end,
|
|
("goAfter", "lineUp"): after_line_up,
|
|
("goAfter", "lineDown"): after_line_down,
|
|
("goAfter", "paragraph"): actions.edit.paragraph_end,
|
|
("goAfter", "document"): actions.edit.file_end,
|
|
("goAfter", "fileEnd"): actions.edit.file_end,
|
|
("goAfter", "selection"): actions.edit.right,
|
|
("goAfter", "wordRight"): actions.edit.word_right,
|
|
("goAfter", "wordLeft"): actions.edit.word_left,
|
|
("goAfter", "word"): actions.edit.word_right,
|
|
# Delete
|
|
("delete", "left"): actions.edit.delete,
|
|
("delete", "right"): actions.user.delete_right,
|
|
("delete", "line"): actions.edit.delete_line,
|
|
("delete", "paragraph"): actions.edit.delete_paragraph,
|
|
# ("delete", "document"): actions.edit.delete_all, # Beta only
|
|
("delete", "document"): actions.user.delete_all,
|
|
("delete", "selection"): actions.edit.delete,
|
|
# Cut to clipboard
|
|
("cutToClipboard", "line"): actions.user.cut_line,
|
|
("cutToClipboard", "selection"): actions.edit.cut,
|
|
# copy
|
|
("copyToClipboard", "selection"): actions.edit.copy,
|
|
}
|
|
|
|
|
|
@mod.action_class
|
|
class Actions:
|
|
def edit_command(action: EditAction | str, modifier: EditModifier | str):
|
|
"""Perform edit command with associated modifier.
|
|
Action and modifier can be dataclasses (formed from utterances via
|
|
capture) or str, for use in scripts. Strings should match the action or
|
|
modifier types declared here or in edit_command_modifiers.py or
|
|
edit_command_actions.py"""
|
|
if isinstance(modifier, str):
|
|
modifier = EditModifier(modifier)
|
|
if isinstance(action, str):
|
|
action = EditSimpleAction(action)
|
|
key = (action.type, modifier.type)
|
|
count = modifier.count
|
|
|
|
if key in custom_callbacks:
|
|
custom_callbacks[key](action, modifier.type, count)
|
|
return
|
|
|
|
elif key in compound_actions:
|
|
for i in range(1, count + 1):
|
|
compound_actions[key]()
|
|
return
|
|
|
|
run_modifier_callback(modifier)
|
|
run_action_callback(action)
|