Ejemplo n.º 1
0
TODO: Audit on Linux

"""

import time

from talon import Context, Module, actions

key = actions.key
user = actions.user
browser = actions.browser

module = Module()
module.tag("browser", desc="Active when one of the major browsers is active.")

context = Context()
context.matches = r"""
os: windows
os: linux

app: /firefox/
app: /chrome/
# NOTE: Doesn't work properly with Internet Explorer. Will need its own module.
app: /iexplore/
app: /opera/

# TODO: Compatibility with Edge?
# title: /- Microsoft Edge/
"""
context.tags = ["user.browser"]
Ejemplo n.º 2
0
from talon import Context, actions
ctx = Context()
ctx.matches = r"""
app: safari
"""
ctx.tags = ['browser', 'user.tabs']


@ctx.action_class('browser')
class BrowserActions:
    #action(browser.address):

    def bookmark():
        actions.key('cmd-d')

    def bookmark_tabs():
        actions.key('cmd-shift-d')

    def bookmarks():
        actions.key('cmd-alt-b')
        #action(browser.bookmarks_bar):
        #	key(ctrl-shift-b)
    def focus_address():
        actions.key('cmd-l')
        #action(browser.focus_page):
    def focus_search():
        actions.browser.focus_address()

    def go_blank():
        actions.key('cmd-n')
Ejemplo n.º 3
0
from talon import Context, Module, actions, imgui, settings, ui
import os
import subprocess

mod = Module()
mod.apps.mintty = """
os: windows
and app.name: Terminal
os: windows
and app.name: mintty.exe
"""

ctx = Context()
ctx.matches = r"""
app: mintty
"""
ctx.tags = [
    "terminal",
    "user.file_manager",
    "user.generic_terminal",
    "user.git",
    "user.kubectl",
]

directories_to_remap = {}
directories_to_exclude = {}

setting_cyg_path = mod.setting(
    "cygpath",
    type=str,
    default="C:\\cygwin64\\bin\\cygpath.exe",
Ejemplo n.º 4
0
        if app:
            app = app[0]
            app.focus()
            # TODO: replace sleep with a registered callback
            for i in range(25):
                if ui.active_app().bundle == bundle:
                    break
                time.sleep(0.01)
            time.sleep(0.05)

    def launch_app(path: str):
        """Launch a new application by path"""
        ui.launch(path=path)


ctx = Context()
ctx.commands = {
    'focus {self.running}': lambda m: actions.self.focus(m.running),
    'launch {self.launch}': lambda m: actions.selef.launch(m.launch),
}


def update_lists():
    new = {}
    for app in ui.apps():
        if app.background and not app.windows():
            continue
        words = app.name.lower().split(' ')
        for word in words:
            if word and not word in new:
                new[word] = app.bundle
Ejemplo n.º 5
0
from talon import Context

hiss_context = Context()
hiss_context.matches = r"""
tag: user.emacs
# Currently, the way Talon parses contexts means the basic context would
# override hiss-to-cancel too, so we manually exclude it.
user.zoom_mouse_zooming: False
"""

# Scrolling in Emacs is invasive - it doesn't just scroll, it moves the cursor.
# Hisses will misfire while speaking, so we add a deadzone to ignore short
# hisses.
hiss_context.settings["user.hiss_start_deadzone"] = 300
Ejemplo n.º 6
0
from talon import Context, Module

mod = Module()
ctx = Context()

symbols = {
    # operators
    "fraction": "frac",
    "summation": "sum",
    "product": "prod",
    "product": "lim",
    "[square] root": "sqrt",
    "generic root": "root",
    "integral": "int",
    "double integral": "iint",
    "triple integral": "iiint",
    "times": "times",
    "divide": "div",
    "C dot": "cdot",
    "plus or minus": "pm",
    "partial": "partial",
    "infinity": "infty",
    "(nice frack | nice fraction)": "nicefrac",
    "binomial": "binom",
    "vector nabla": "nabla",
    # accents
    "accent hat": "hat",
    "accent tilde": "tilde",
    "accent dot": "dot",
    "accent double dot": "ddot",
    "accent bar": "bar",
Ejemplo n.º 7
0
    return "-".join(mods + [m.unmodified_key])


@mod.capture(rule="<self.key>+")
def keys(m) -> str:
    "A sequence of one or more keys with optional modifiers"
    return " ".join(m.key_list)


@mod.capture(rule="{self.letter}+")
def letters(m) -> str:
    "Multiple letter keys"
    return "".join(m.letter_list)


ctx = Context()
modifier_keys = {
    # If you find 'alt' is often misrecognized, try using 'alter'.
    "alter":   "alt",
    'troll': 'ctrl',
    'sky':   'shift',
    "super": "super",
    #'alter': 'alt',
    #"command": "cmd",
    #"control": "ctrl",
    #"option": "alt",
    #"shift": "shift",  
}
if app.platform  == "mac":
    modifier_keys["command"] = "cmd"
    modifier_keys["option"] = "alt"
from talon import Context, actions
import os

context = Context()
context.matches = "title: /VIM/i"

vim_normal_mode = actions.user.vim_normal_mode
# # Provide simple vim_normal_mode if the user does not already use vim
# try:
#     actions.user.vim_normal_mode()
# except KeyError:
#     print("VIM: using simple insert command")
#     def vim_normal_mode(cmd: str):
#         actions.key("escape")
#         actions.sleep(0.2)
#         actions.insert(cmd)
# except Exception:
#     print("VIM: using fidget")
#     vim_normal_mode = actions.user.vim_normal_mode


@context.action_class("user")
class editor_actions:
    def editor_get_cursor_position():
        title = actions.win.title()
        return eval(title.split(" | ")[-2])

    def editor_go_to_position(row: int, column: int):
        horizontal_movement = f"{column}l" if column > 0 else ""
        vim_normal_mode(f"{row}G0{horizontal_movement}")
Ejemplo n.º 9
0
from talon import Context, Module, actions, imgui, settings, ui, app

import os

ctx = Context()
mod = Module()
ctx.matches = r"""
app: windows_power_shell
app: windows_terminal
and win.title: /PowerShell/
"""

ctx.tags = [
    'user.file_manager', 'user.generic_terminal', 'user.git', 'user.kubectl',
    'terminal'
]

user_path = os.path.expanduser("~")
directories_to_remap = {}
directories_to_exclude = {}


@ctx.action_class('edit')
class EditActions:
    def delete_line():
        actions.key('esc')


@ctx.action_class('user')
class UserActions:
    def file_manager_refresh_title():
Ejemplo n.º 10
0
            actions.mouse_move(*click_info.position_at)
            click_info.function(click_info.modifiers)
            # Sleep for enough time for the click to complete.
            time.sleep(0.1)

    def click_current(click_info: Click):
        """Click where the mouse is currently."""
        click_info.function()


@module.capture
def click(m) -> Click:
    """Get click info from a phrase."""


context = Context()
context.lists["self.clicks"] = CLICKS_MAP.keys()


@context.capture(rule="<user.modifiers> {self.clicks}")
def click(m) -> Click:
    click_command = m["clicks"]
    click_function = CLICKS_MAP[click_command]
    # TODO: Cover no backdated position
    #
    # NOTE: This has quirks. If you say "shift click", it will backdate to the
    #   start of "click", not "shift".
    position = backdated_position(m[-1])
    modifiers = m["modifiers"]
    return Click(click_function, position, modifiers)
Ejemplo n.º 11
0
)


@module.capture
def emacs_snippet(m) -> str:
    """A single Emacs snippet, without prefix."""


@module.action_class
class Actions:
    def emacs_insert_yasnippet(snippet_name: str) -> None:
        """Insert a yasnippet by name."""
        rpc.call("voicemacs-insert-snippet", [snippet_name])


context = Context()
context.matches = r"""
app: /emacs/
user.emacs-minor-mode: yas-global-mode
user.emacs-minor-mode: yas-minor-mode
"""

context.lists[SNIPPET_LIST_PATH] = {}


@context.capture(rule="{" + SNIPPET_LIST_PATH + "}")
def emacs_snippet(m) -> str:
    return getattr(m, SNIPPET_LIST_NAME)


def _speech_snippet_list(state):
Ejemplo n.º 12
0
from talon import Context, Module
from user.utils import utilities

BRING = utilities.load_toml_relative("config/bringme.toml")

mod = Module()
ctx = Context()
mod.list("websites", desc="Websites")
ctx.lists['websites'] = BRING["website"]


@mod.capture
def websites(m) -> str:
    "Websites I use often"


@ctx.capture(rule="{websites}")
def websites(m):
    return m["websites"]
Ejemplo n.º 13
0
path = os.path.dirname(os.path.abspath(__file__))
with open(path + "/dictionary/german.dic", encoding='ISO-8859-1') as f:
    list_of_words = f.read().split("\n")

dict_of_words = {}
for word in list_of_words:
    if word.lower() in dict_of_words:
        # multiple entries, use lower
        dict_of_words[word.lower()] = word.lower()
    else:
        dict_of_words[word.lower()] = word

mod = Module()
mod.mode('german')

ctx = Context()
ctx.matches = 'mode: user.german'
ctx.settings = {
    'speech.engine': 'vosk',
    #	'speech.language': 'de_DE',
    'speech.timeout': 0.3
}

mod.setting("german_unicode",
            type=int,
            default=1,
            desc="Enable proper unicode punctuation")

mod.list("buchstabe", desc="The spoken phonetic alphabet")
ctx.lists["self.buchstabe"] = {
    "alpha": "a",
Ejemplo n.º 14
0
from talon import Module, Context, actions, ui, imgui, clip, settings, registry, app

mod = Module()
ctx = Context()

ctx_talon_lists = Context()

# restrict all the talon_* lists to when the user.talon_populate_lists tag
# is active to prevent them from being active in contexts where they are not wanted.
# Do not enable this tag with dragon, as it will be unusable.
# with conformer, the latency increase may also be unacceptable depending on your cpu
# see https://github.com/knausj85/knausj_talon/issues/600
ctx_talon_lists.matches = r"""
tag: user.talon_populate_lists
"""

mod.tag("talon_python", "Tag to activate talon-specific python commands")
mod.tag(
    "talon_populate_lists",
    "Tag to activate talon-specific lists of actions, scopes, modes etcetera. Do not use this tag with dragon"
)
mod.list("talon_actions")
mod.list("talon_lists")
mod.list("talon_captures")
mod.list("talon_apps")
mod.list("talon_tags")
mod.list("talon_modes")
mod.list("talon_settings")
mod.list("talon_scopes")
mod.list("talon_modes")
Ejemplo n.º 15
0
from talon import Context, actions, ui, Module, app
is_mac = app.platform == 'mac'

ctx = Context()
mod = Module()

ctx.matches = r'''
app: Microsoft Visual Studio 2019
app: devenv.exe
'''
@ctx.action_class('win')
class win_actions:
    def filename(): 
        title = actions.win.title()
        #this doesn't seem to be necessary on VSCode for Mac
        #if title == "":
        #    title = ui.active_window().doc
    
        if is_mac:
            result = title.split(" — ")[0]
        else:
            result = title.split(" - ")[0]

        if "." in result:
            return result
    
        return ""

    def file_ext():
        return actions.win.filename().split(".")[-1]
Ejemplo n.º 16
0
from talon import Context, Module, actions

# How old a request file needs to be before we declare it stale and are willing
# to remove it
STALE_TIMEOUT_MS = 60_000

# The amount of time to wait for VSCode to perform a command, in seconds
VSCODE_COMMAND_TIMEOUT_SECONDS = 3.0

# When doing exponential back off waiting for vscode to perform a command, how
# long to sleep the first time
MINIMUM_SLEEP_TIME_SECONDS = 0.0005

mod = Module()

ctx = Context()
mac_ctx = Context()

ctx.matches = r"""
app: vscode
"""
mac_ctx.matches = r"""
os: mac
app: vscode
"""


class NotSet:
    def __repr__(self):
        return "<argument not set>"
Ejemplo n.º 17
0
from talon import Context, actions, ui, Module

mod = Module()
ctx = Context()

apps = mod.apps
apps.notepad_plus_plus = """
os: windows
and app.name: Notepad++ : a free (GNU) source code editor
os: windows
and app.name: notepad++.exe
"""

ctx.matches = r"""
app: notepad_plus_plus
"""

ctx.tags = ['user.find_and_replace', 'user.line_commands', 'user.tabs']


@ctx.action_class('app')
class AppActions:
    def tab_previous():
        actions.key('ctrl-pageup')

    def tab_next():
        actions.key('ctrl-pagedown')


@ctx.action_class('code')
class CodeActions:
Ejemplo n.º 18
0
from talon import Context, Module

fractions = {
    "half": "2",
    "halves": "2",
    "quarter": "4",
    "fourth": "4",
    "fifth": "5",
    "sixth": "6",
    "seventh": "7",
    "eighth": "8",
    "ninth": "9",
    "tenth": "10",
}

mod = Module()
ctx = Context()

mod.list("mathfly_fractions", "Fractions")
ctx.lists["mathfly_fractions"] = {
    **fractions,
    **{f"{k}s": v
       for k, v in fractions.items()},
}
Ejemplo n.º 19
0
from talon import Context, actions
ctx = Context()
ctx.matches = r"""
# Its note that this is not actual EMACS itself, but refers to the default
# command line editing mode enabled in most common linux shells like bash, zsh,
# is also used by lots of command line tools/interfaces, for example gdb
# command line interface.
#
# It more information about the commands can be found here:
# https://www.gnu.org/software/bash/manual/html_node/Command-Line-Editing.html
#
# The idea is that certain shell tools can assert the tag to ensure that the
# generic talon line editing commands will still work. Is also allows for
# things like zsh being configured in vi mode, but then using gdb with the more
# traditional emacs-style keyboard shortcuts

tag: user.readline
"""


@ctx.action_class('edit')
class EditActions:
    def undo():
        actions.key('ctrl-x ctrl-u')

    def up():
        actions.key('up')

    def down():
        actions.key('down')
Ejemplo n.º 20
0
from typing import Optional, Tuple, Literal, Callable
import re

mod = Module()

setting_context_sensitive_dictation = mod.setting(
    "context_sensitive_dictation",
    type=bool,
    default=False,
    desc=
    "Look at surrounding text to improve auto-capitalization/spacing in dictation mode. By default, this works by selecting that text & copying it to the clipboard, so it may be slow or fail in some applications.",
)

mod.list("prose_modifiers", desc="Modifiers that can be used within prose")
mod.list("prose_snippets", desc="Snippets that can be used within prose")
ctx = Context()
# Maps spoken forms to DictationFormat method names (see DictationFormat below).
ctx.lists["user.prose_modifiers"] = {
    "cap": "cap",
    "no cap": "no_cap",
    "no caps": "no_cap",  # "no caps" variant for Dragon
    "no space": "no_space",
}
ctx.lists["user.prose_snippets"] = {
    "spacebar": " ",
    "new line": "\n",
    "new paragraph": "\n\n",
    # Curly quotes are used to obtain proper spacing for left and right quotes, but will later be straightened.
    "open quote": "“",
    "close quote": "”",
    "smiley": ":-)",
Ejemplo n.º 21
0
from talon import Context, Module, actions
from talon import ui

key = actions.key

ctx = Context()
ctx.on({'app.bundle': 'com.google.Chrome'})


@ctx.action_class('app')
class AppActions:
    def window_close():
        key('cmd-shift-w')

    def tab_reopen():
        key('cmd-shift-t')


@ctx.action_class('browser')
class BrowserActions:
    def focus_address():
        key('cmd-l')

    def reload():
        key('cmd-r')

    def reload_hard():
        key('cmd-shift-r')

    def open_private_window():
        key('cmd-shift-n')
Ejemplo n.º 22
0
from talon import Context

from user.misc.chunked_phrase import chainable_formatters

context = Context()
context.matches = """
tag: user.emacs
user.emacs-major-mode: cmake-mode
"""
context.lists["user.chainable_formatters"] = {
    **chainable_formatters,
    # TODO: easy way to type vars in cmake
    # "var": "format_cmake_var",
}