init commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
app: one_password
|
||||
-
|
||||
password new: user.password_new()
|
||||
password dup: user.password_duplicate()
|
||||
password edit: user.password_edit()
|
||||
password delete: user.password_delete()
|
||||
@@ -0,0 +1,4 @@
|
||||
#todo: tags
|
||||
-
|
||||
password fill: user.password_fill()
|
||||
password show: user.password_show()
|
||||
@@ -0,0 +1,31 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
|
||||
# i don't see a need to restrict the app here, this just defines the actions
|
||||
# each app can support appropriate voice commands as needed
|
||||
# the below are for 1password, redefine as needed
|
||||
ctx.matches = r"""
|
||||
os: mac
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def password_fill():
|
||||
actions.key("cmd-\\")
|
||||
|
||||
def password_show():
|
||||
actions.key("cmd-alt-\\")
|
||||
|
||||
def password_new():
|
||||
actions.key("cmd-i")
|
||||
|
||||
def password_duplicate():
|
||||
actions.key("cmd-d")
|
||||
|
||||
def password_edit():
|
||||
actions.key("cmd-e")
|
||||
|
||||
def password_delete():
|
||||
actions.key("cmd-backspace")
|
||||
@@ -0,0 +1,31 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
|
||||
# i don't see a need to restrict the app here, this just defines the actions
|
||||
# each app can support appropriate voice commands as needed
|
||||
# the below are for 1password, redefine as needed
|
||||
ctx.matches = r"""
|
||||
os: windows
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def password_fill():
|
||||
actions.key("ctrl-\\\\")
|
||||
|
||||
def password_show():
|
||||
actions.key("alt-ctrl-\\\\")
|
||||
|
||||
def password_new():
|
||||
actions.key("ctrl-n")
|
||||
|
||||
def password_duplicate():
|
||||
actions.key("ctrl-d")
|
||||
|
||||
def password_edit():
|
||||
actions.key("ctrl-e")
|
||||
|
||||
def password_delete():
|
||||
actions.key("ctrl-delete")
|
||||
@@ -0,0 +1,29 @@
|
||||
from talon import Module
|
||||
|
||||
mod = Module()
|
||||
|
||||
# 1password
|
||||
mod.apps.one_password = "app.bundle: com.agilebits.onepassword7"
|
||||
mod.apps.one_password = "app.name: 1Password for Windows desktop"
|
||||
mod.apps.one_password = "app.name: 1Password.exe"
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def password_fill():
|
||||
"""fill the password"""
|
||||
|
||||
def password_show():
|
||||
"""show the password"""
|
||||
|
||||
def password_new():
|
||||
"""New password"""
|
||||
|
||||
def password_duplicate():
|
||||
"""Duplicate password"""
|
||||
|
||||
def password_edit():
|
||||
"""Edit password"""
|
||||
|
||||
def password_delete():
|
||||
"""Delete password"""
|
||||
@@ -0,0 +1,15 @@
|
||||
# Web apps and browser extensions
|
||||
|
||||
Some of the Talon files for web apps (e.g. `apps/github/github_web.talon`) use a `browser.host` matcher. These talon files should work out of the box for Safari, Chrome, Brave, on Mac, but require additional configuration on other browsers/operating systems.
|
||||
|
||||
`community` is set up so that if a URL is found in the titlebar of an application matching the 'browser' tag it will be used to populate the browser.host matcher (see `code/browser.py`). This probably means that you will need an extension to make the browser.host based scripts work.
|
||||
|
||||
Browser extensions that can add the protocol and hostname or even the entire URL to the window title:
|
||||
|
||||
Firefox:
|
||||
|
||||
- https://addons.mozilla.org/en-US/firefox/addon/keepass-helper-url-in-title/
|
||||
|
||||
Chrome:
|
||||
|
||||
- https://chrome.google.com/webstore/detail/url-in-title/ignpacbgnbnkaiooknalneoeladjnfgb
|
||||
@@ -0,0 +1,15 @@
|
||||
from talon import Module
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.adobe_acrobat_reader_dc = r"""
|
||||
os: windows
|
||||
and app.name: Adobe Acrobat DC
|
||||
os: windows
|
||||
and app.exe: /^acrobat\.exe$/i
|
||||
os: windows
|
||||
and app.name: Adobe Acrobat Reader DC
|
||||
os: windows
|
||||
and app.exe: /^acrord32\.exe$/i
|
||||
"""
|
||||
# TODO: mac context and implementation
|
||||
@@ -0,0 +1,5 @@
|
||||
app: adobe_acrobat_reader_dc
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.tabs
|
||||
tag(): user.pages
|
||||
@@ -0,0 +1,61 @@
|
||||
from talon import Context, actions
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = """
|
||||
os: windows
|
||||
app: adobe_acrobat_reader_dc
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
# app.tabs
|
||||
def tab_next():
|
||||
actions.key("ctrl-tab")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-shift-tab")
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def zoom_in():
|
||||
actions.key("ctrl-0") # in german version
|
||||
|
||||
def zoom_out():
|
||||
actions.key("ctrl-1") # in german version TODO: differentiate languages
|
||||
|
||||
def zoom_reset():
|
||||
actions.key("ctrl-2")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_current():
|
||||
actions.key("ctrl-shift-n")
|
||||
page = actions.edit.selected_text()
|
||||
actions.key("tab:2 enter")
|
||||
return int(page)
|
||||
|
||||
def page_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def page_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-shift-n")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
|
||||
def page_final():
|
||||
actions.key("end")
|
||||
|
||||
def page_rotate_right():
|
||||
actions.key("shift-ctrl-0")
|
||||
|
||||
def page_rotate_left():
|
||||
actions.key("shift-ctrl-1")
|
||||
@@ -0,0 +1,13 @@
|
||||
user.running: amethyst
|
||||
-
|
||||
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 float: key(alt-shift-t)
|
||||
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")
|
||||
window reevaluate: key("alt-shift-z")
|
||||
@@ -0,0 +1,9 @@
|
||||
from talon import Context, Module
|
||||
|
||||
mod = Module()
|
||||
mod.tag("anaconda", desc="tag for enabling anaconda commands in your terminal")
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
tag: user.anaconda
|
||||
"""
|
||||
@@ -0,0 +1,40 @@
|
||||
tag: terminal
|
||||
and tag: user.anaconda
|
||||
-
|
||||
anaconda: "conda "
|
||||
anaconda help: "conda --help\n"
|
||||
anaconda version: "conda --version\n"
|
||||
|
||||
anaconda environment list: "conda env list\n"
|
||||
anaconda environment create: "conda env create -f "
|
||||
anaconda environment remove: "conda env remove -n "
|
||||
|
||||
anaconda activate: "conda activate "
|
||||
anaconda clean: "conda clean "
|
||||
anaconda compare: "conda compare "
|
||||
anaconda config: "conda config "
|
||||
anaconda create: "conda create "
|
||||
anaconda info: "conda info "
|
||||
anaconda init: "conda init "
|
||||
anaconda install: "conda install "
|
||||
anaconda list: "conda list "
|
||||
anaconda package: "conda package "
|
||||
anaconda remove: "conda remove "
|
||||
anaconda uninstall: "conda uninstall "
|
||||
anaconda run: "conda run "
|
||||
anaconda search: "conda search "
|
||||
anaconda update: "conda update "
|
||||
anaconda upgrade: "conda upgrade "
|
||||
|
||||
anaconda build: "conda build "
|
||||
anaconda convert: "conda convert "
|
||||
anaconda debug: "conda debug "
|
||||
anaconda develop: "conda develop "
|
||||
anaconda environment: "conda env "
|
||||
anaconda index: "conda index "
|
||||
anaconda inspect: "conda inspect "
|
||||
anaconda metapackage: "conda metapackage "
|
||||
anaconda render: "conda render "
|
||||
anaconda server: "conda server "
|
||||
anaconda skeleton: "conda skeleton "
|
||||
anaconda verify: "conda verify "
|
||||
@@ -0,0 +1,21 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: notes
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def zoom_in():
|
||||
actions.key("shift-cmd->")
|
||||
|
||||
def zoom_out():
|
||||
actions.key("shift-cmd-<")
|
||||
|
||||
def zoom_reset():
|
||||
actions.key("shift-cmd-0")
|
||||
|
||||
def indent_less():
|
||||
actions.key("cmd-[")
|
||||
@@ -0,0 +1,32 @@
|
||||
os: mac
|
||||
and app: notes
|
||||
-
|
||||
|
||||
new note: key(cmd-n)
|
||||
duplicate note: key(cmd-d)
|
||||
new folder: key(shift-cmd-n)
|
||||
toggle folders: key(alt-cmd-s)
|
||||
show main: key(cmd-0)
|
||||
list view: key(cmd-1)
|
||||
gallery view: key(cmd-2)
|
||||
toggle attachments: key(cmd-3)
|
||||
find all: key(alt-cmd-f)
|
||||
print note: key(cmd-p)
|
||||
attach file: key(shift-cmd-a)
|
||||
create link: key(cmd-k)
|
||||
insert table: key(alt-cmd-t)
|
||||
apply title: key(shift-cmd-t)
|
||||
apply heading: key(shift-cmd-h)
|
||||
apply subheading: key(shift-cmd-j)
|
||||
apply body: key(shift-cmd-b)
|
||||
apply mono: key(shift-cmd-m)
|
||||
apply bullet: key(shift-cmd-7)
|
||||
apply dash: key(shift-cmd-8)
|
||||
apply number: key(shift-cmd-9)
|
||||
apply checklist: key(shift-cmd-l)
|
||||
increase font: key(cmd-+)
|
||||
decrease font: key(cmd--)
|
||||
line break: key(ctrl-enter)
|
||||
mark: key(shift-cmd-u)
|
||||
drag [line] down: key('ctrl-cmd-down')
|
||||
drag [line] up: key('ctrl-cmd-up')
|
||||
@@ -0,0 +1,90 @@
|
||||
import os
|
||||
|
||||
from talon import Context, actions, ui
|
||||
|
||||
# TODO: fit this to terminal.py
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: apple_terminal
|
||||
"""
|
||||
directories_to_remap = {}
|
||||
directories_to_exclude = {}
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def delete_line():
|
||||
actions.key("ctrl-u")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def file_manager_current_path():
|
||||
title = ui.active_window().title
|
||||
|
||||
# take the first split for the zsh-based terminal
|
||||
if " — " in title:
|
||||
title = title.split(" — ")[0]
|
||||
|
||||
if "~" in title:
|
||||
title = os.path.expanduser(title)
|
||||
|
||||
if title in directories_to_remap:
|
||||
title = directories_to_remap[title]
|
||||
|
||||
if title in directories_to_exclude:
|
||||
title = None
|
||||
|
||||
return title
|
||||
|
||||
def file_manager_show_properties():
|
||||
"""Shows the properties for the file"""
|
||||
|
||||
def file_manager_open_directory(path: str):
|
||||
"""opens the directory that's already visible in the view"""
|
||||
actions.insert("cd ")
|
||||
path = f'"{path}"'
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
# jtk - refresh title isn't necessary since the apple terminal does it for us
|
||||
# actions.user.file_manager_refresh_title()
|
||||
|
||||
def file_manager_open_parent():
|
||||
actions.insert("cd ..")
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_select_directory(path: str):
|
||||
"""selects the directory"""
|
||||
actions.insert(path)
|
||||
|
||||
def file_manager_new_folder(name: str):
|
||||
"""Creates a new folder in a gui filemanager or inserts the command to do so for terminals"""
|
||||
name = f'"{name}"'
|
||||
|
||||
actions.insert("mkdir " + name)
|
||||
|
||||
def file_manager_open_file(path: str):
|
||||
"""opens the file"""
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_select_file(path: str):
|
||||
"""selects the file"""
|
||||
actions.insert(path)
|
||||
|
||||
def file_manager_refresh_title():
|
||||
return
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class app_actions:
|
||||
# other tab functions should already be implemented in
|
||||
# code/platforms/mac/app.py
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-shift-tab")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-tab")
|
||||
@@ -0,0 +1,25 @@
|
||||
app: apple_terminal
|
||||
-
|
||||
# makes the commands in terminal.talon available
|
||||
tag(): terminal
|
||||
|
||||
# use readline keybindings for various editing commands
|
||||
tag(): user.readline
|
||||
|
||||
# activates the implementation of the commands/functions in terminal.talon
|
||||
tag(): user.generic_unix_shell
|
||||
|
||||
# makes commands for certain applications available
|
||||
# you can deactivate them if you do not use the application
|
||||
tag(): user.git
|
||||
tag(): user.anaconda
|
||||
tag(): user.kubectl
|
||||
|
||||
# TODO: explain
|
||||
tag(): user.tabs
|
||||
tag(): user.file_manager
|
||||
|
||||
suspend: key(ctrl-z)
|
||||
resume:
|
||||
insert("fg")
|
||||
key(enter)
|
||||
@@ -0,0 +1,34 @@
|
||||
from talon import Context, Module, actions, app
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.arc = "app.name: Arc"
|
||||
mod.apps.arc = """
|
||||
os: mac
|
||||
app.bundle: company.thebrowser.Browser
|
||||
|
||||
"""
|
||||
ctx.matches = r"""
|
||||
app: arc
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
def command_search(command: str = ""):
|
||||
actions.key("cmd-l")
|
||||
if command != "":
|
||||
actions.sleep("200ms")
|
||||
actions.insert(command)
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def show_extensions():
|
||||
actions.app.tab_open()
|
||||
actions.browser.go("arc://extensions")
|
||||
@@ -0,0 +1,6 @@
|
||||
app: arc
|
||||
os: mac
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
tag(): user.command_search
|
||||
@@ -0,0 +1,8 @@
|
||||
user.running: arc
|
||||
os: mac
|
||||
-
|
||||
# This assumes that you have not disabled Little Arc
|
||||
little arc [<user.text>]:
|
||||
key("cmd-alt-n")
|
||||
sleep(200ms)
|
||||
insert(user.text or "")
|
||||
@@ -0,0 +1,39 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.atril = """
|
||||
os: linux
|
||||
and app.name: Atril
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: atril
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_current():
|
||||
actions.key("ctrl-l")
|
||||
page = actions.edit.selected_text()
|
||||
actions.key("right escape")
|
||||
return int(page)
|
||||
|
||||
def page_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def page_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-l")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
|
||||
def page_final():
|
||||
actions.key("ctrl-end")
|
||||
@@ -0,0 +1,4 @@
|
||||
app: atril
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
@@ -0,0 +1,32 @@
|
||||
from talon import Context, Module, actions, app
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.brave = "app.name: Brave Browser"
|
||||
mod.apps.brave = "app.name: Brave-browser"
|
||||
mod.apps.brave = r"""
|
||||
os: windows
|
||||
and app.exe: /^brave\.exe$/i
|
||||
os: linux
|
||||
and app.exe: brave
|
||||
os: mac
|
||||
and app.bundle: com.brave.Browser
|
||||
"""
|
||||
ctx.matches = r"""
|
||||
app: brave
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def show_extensions():
|
||||
actions.app.tab_open()
|
||||
actions.browser.go("brave://extensions")
|
||||
@@ -0,0 +1,4 @@
|
||||
app: brave
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
@@ -0,0 +1,19 @@
|
||||
from talon import Module
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.calibre = r"""
|
||||
os: windows
|
||||
and app.name: calibre.exe
|
||||
os: windows
|
||||
and app.exe: /^calibre\.exe$/i
|
||||
os: windows
|
||||
and app.name: calibre-parallel.exe
|
||||
os: windows
|
||||
and app.exe: /^calibre-parallel\.exe$/i
|
||||
"""
|
||||
mod.apps.calibre = """
|
||||
os: linux
|
||||
app.name: calibre
|
||||
"""
|
||||
# TODO: mac context
|
||||
@@ -0,0 +1,39 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.calibre_viewer = """
|
||||
app: calibre
|
||||
title: /E-book viewer$/
|
||||
title: /eBook-Betrachter$/
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = """
|
||||
os: windows
|
||||
os: linux
|
||||
app: calibre_viewer
|
||||
"""
|
||||
# TODO: mac implementation
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_next():
|
||||
actions.key("pagedown")
|
||||
|
||||
def page_previous():
|
||||
actions.key("pageup")
|
||||
|
||||
def page_final():
|
||||
actions.key("ctrl-end")
|
||||
|
||||
# user.chapters
|
||||
def chapter_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def chapter_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
@@ -0,0 +1,5 @@
|
||||
app: calibre_viewer
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
tag(): user.chapters
|
||||
@@ -0,0 +1,54 @@
|
||||
from talon import Context, Module, actions, app
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.chrome = "app.name: Google Chrome"
|
||||
mod.apps.chrome = r"""
|
||||
os: windows
|
||||
and app.exe: /^chrome\.exe$/i
|
||||
"""
|
||||
mod.apps.chrome = """
|
||||
os: mac
|
||||
app.bundle: com.google.Chrome
|
||||
app.bundle: com.google.Chrome.canary
|
||||
app.bundle: org.chromium.Chromium
|
||||
"""
|
||||
mod.apps.chrome = """
|
||||
os: linux
|
||||
app.exe: chrome
|
||||
app.exe: chromium-browser
|
||||
app.exe: chromium
|
||||
"""
|
||||
mod.apps.chrome = """
|
||||
os: linux
|
||||
and app.name: Google-chrome
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: chrome
|
||||
"""
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def chrome_mod(key: str):
|
||||
"""Press the specified key with the correct modifier key for the OS"""
|
||||
if app.platform == "mac":
|
||||
actions.key(f"cmd-{key}")
|
||||
else:
|
||||
actions.key(f"ctrl-{key}")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def show_extensions():
|
||||
actions.app.tab_open()
|
||||
actions.browser.go("chrome://extensions")
|
||||
@@ -0,0 +1,14 @@
|
||||
app: chrome
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
|
||||
profile switch: user.chrome_mod("shift-m")
|
||||
|
||||
tab search: user.chrome_mod("shift-a")
|
||||
|
||||
tab search <user.text>$:
|
||||
user.chrome_mod("shift-a")
|
||||
sleep(200ms)
|
||||
insert("{text}")
|
||||
key(down)
|
||||
@@ -0,0 +1,6 @@
|
||||
os: windows
|
||||
app.exe: /^conemu64\.exe$/i
|
||||
-
|
||||
|
||||
tag(): terminal
|
||||
tag(): user.git
|
||||
@@ -0,0 +1,85 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
apps = mod.apps
|
||||
apps.discord = "app.bundle: com.hnc.Discord"
|
||||
apps.discord = "app.name: Discord"
|
||||
apps.discord = "app.name: Discord.exe"
|
||||
apps.discord = """
|
||||
tag: browser
|
||||
browser.host: discord.com
|
||||
"""
|
||||
|
||||
mod.list("discord_destination", desc="discord destination")
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: discord
|
||||
"""
|
||||
|
||||
ctx.lists["user.discord_destination"] = {
|
||||
"user": "@",
|
||||
"voice": "!",
|
||||
"server": "*",
|
||||
}
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class discord_actions:
|
||||
def discord_mentions_last():
|
||||
"""Go up to channel with unread mentions"""
|
||||
|
||||
def discord_mentions_next():
|
||||
"""Go down to channel with unread mentions"""
|
||||
|
||||
def discord_oldest_unread():
|
||||
"""Go to oldest unread message"""
|
||||
|
||||
def discord_toggle_pins():
|
||||
"""Toggle pins popout"""
|
||||
|
||||
def discord_toggle_inbox():
|
||||
"""Toggle inbox popout"""
|
||||
|
||||
def discord_toggle_members():
|
||||
"""Toggle channel member list"""
|
||||
|
||||
def discord_emoji_picker():
|
||||
"""Toggle emoji picker"""
|
||||
|
||||
def discord_gif_picker():
|
||||
"""Toggle gif picker"""
|
||||
|
||||
def discord_sticker_picker():
|
||||
"""Toggle sticker picker"""
|
||||
|
||||
def discord_mark_inbox_read():
|
||||
"""Mark top inbox channel read"""
|
||||
|
||||
def discord_mute():
|
||||
"""Toggle mute"""
|
||||
|
||||
def discord_deafen():
|
||||
"""Toggle deafen"""
|
||||
|
||||
def discord_answer_call():
|
||||
"""Answer incoming call"""
|
||||
|
||||
def discord_decline_call():
|
||||
"""Decline incoming call"""
|
||||
|
||||
def discord_quick_switcher(dest_type: str, dest_search: str):
|
||||
"""Open up the quick switcher, optionally specifying a type of destination"""
|
||||
|
||||
def discord_go_current_call():
|
||||
"""Go to current call"""
|
||||
|
||||
def discord_toggle_dms():
|
||||
"""Toggle between dms and your most recent server"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# Navigation: Channels
|
||||
def messaging_open_channel_picker():
|
||||
actions.user.discord_quick_switcher("#", "")
|
||||
@@ -0,0 +1,34 @@
|
||||
app: discord
|
||||
-
|
||||
tag(): user.messaging
|
||||
tag(): user.emoji
|
||||
|
||||
# Navigation: QuickSwitcher
|
||||
{user.discord_destination} [<user.text>]:
|
||||
user.discord_quick_switcher(user.discord_destination, user.text or "")
|
||||
switcher: user.discord_quick_switcher("", "")
|
||||
|
||||
# Navigation: Channels
|
||||
[channel] mentions last: user.discord_mentions_last()
|
||||
[channel] mentions next: user.discord_mentions_next()
|
||||
oldest unread: user.discord_oldest_unread()
|
||||
current call: user.discord_go_current_call()
|
||||
|
||||
# UI
|
||||
toggle pins: user.discord_toggle_pins()
|
||||
toggle inbox: user.discord_toggle_inbox()
|
||||
toggle (members | member list): user.discord_toggle_members()
|
||||
toggle (dee ems | dims): user.discord_toggle_dms()
|
||||
pick emoji: user.discord_emoji_picker()
|
||||
pick (jif | gif | gift): user.discord_gif_picker()
|
||||
pick sticker: user.discord_sticker_picker()
|
||||
|
||||
# Misc
|
||||
mark inbox channel read: user.discord_mark_inbox_read()
|
||||
[toggle] (mute | unmute): user.discord_mute()
|
||||
(mute | unmute) and sleep:
|
||||
user.discord_mute()
|
||||
speech.disable()
|
||||
[toggle] (deafen | undeafen): user.discord_deafen()
|
||||
answer call: user.discord_answer_call()
|
||||
decline call: user.discord_decline_call()
|
||||
@@ -0,0 +1,96 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
os: mac
|
||||
app: discord
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# Navigation: QuickSwitcher
|
||||
def discord_quick_switcher(dest_type: str, dest_search: str):
|
||||
actions.key("cmd-k")
|
||||
actions.insert(dest_type)
|
||||
if dest_search:
|
||||
actions.insert(dest_search)
|
||||
|
||||
# Navigation: Servers
|
||||
def messaging_workspace_previous():
|
||||
actions.key("cmd-alt-up")
|
||||
|
||||
def messaging_workspace_next():
|
||||
actions.key("cmd-alt-down")
|
||||
|
||||
# Navigation: Channels
|
||||
def messaging_channel_previous():
|
||||
actions.key("alt-up")
|
||||
|
||||
def messaging_channel_next():
|
||||
actions.key("alt-down")
|
||||
|
||||
def messaging_unread_previous():
|
||||
actions.key("alt-shift-up")
|
||||
|
||||
def messaging_unread_next():
|
||||
actions.key("alt-shift-down")
|
||||
|
||||
def discord_mentions_last():
|
||||
actions.key("cmd-alt-shift-up")
|
||||
|
||||
def discord_mentions_next():
|
||||
actions.key("cmd-alt-shift-down")
|
||||
|
||||
def discord_oldest_unread():
|
||||
actions.key("shift-pageup")
|
||||
|
||||
# UI
|
||||
def discord_toggle_pins():
|
||||
actions.key("cmd-p")
|
||||
|
||||
def discord_toggle_inbox():
|
||||
actions.key("cmd-i")
|
||||
|
||||
def discord_toggle_members():
|
||||
actions.key("cmd-u")
|
||||
|
||||
def discord_emoji_picker():
|
||||
actions.key("cmd-e")
|
||||
|
||||
def discord_gif_picker():
|
||||
actions.key("cmd-g")
|
||||
|
||||
def discord_sticker_picker():
|
||||
actions.key("cmd-s")
|
||||
|
||||
# Misc
|
||||
def messaging_mark_workspace_read():
|
||||
actions.key("shift-esc")
|
||||
|
||||
def messaging_mark_channel_read():
|
||||
actions.key("esc")
|
||||
|
||||
def messaging_upload_file():
|
||||
actions.key("cmd-shift-u")
|
||||
|
||||
def discord_mark_inbox_read():
|
||||
actions.key("cmd-shift-e")
|
||||
|
||||
def discord_mute():
|
||||
actions.key("cmd-shift-m")
|
||||
|
||||
def discord_deafen():
|
||||
actions.key("cmd-shift-d")
|
||||
|
||||
def discord_answer_call():
|
||||
actions.key("cmd-enter")
|
||||
|
||||
def discord_decline_call():
|
||||
actions.key("esc")
|
||||
|
||||
def discord_go_current_call():
|
||||
actions.key("cmd-alt-a")
|
||||
|
||||
def discord_toggle_dms():
|
||||
actions.key("cmd-alt-right")
|
||||
@@ -0,0 +1,97 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
os: windows
|
||||
os: linux
|
||||
app: discord
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# Navigation: QuickSwitcher
|
||||
def discord_quick_switcher(dest_type: str, dest_search: str):
|
||||
actions.key("ctrl-k")
|
||||
actions.insert(dest_type)
|
||||
if dest_search:
|
||||
actions.insert(dest_search)
|
||||
|
||||
# Navigation: Servers
|
||||
def messaging_workspace_previous():
|
||||
actions.key("ctrl-alt-up")
|
||||
|
||||
def messaging_workspace_next():
|
||||
actions.key("ctrl-alt-down")
|
||||
|
||||
# Navigation: Channels
|
||||
def messaging_channel_previous():
|
||||
actions.key("alt-up")
|
||||
|
||||
def messaging_channel_next():
|
||||
actions.key("alt-down")
|
||||
|
||||
def messaging_unread_previous():
|
||||
actions.key("alt-shift-up")
|
||||
|
||||
def messaging_unread_next():
|
||||
actions.key("alt-shift-down")
|
||||
|
||||
def discord_mentions_last():
|
||||
actions.key("ctrl-alt-shift-up")
|
||||
|
||||
def discord_mentions_next():
|
||||
actions.key("ctrl-alt-shift-down")
|
||||
|
||||
def discord_oldest_unread():
|
||||
actions.key("shift-pageup")
|
||||
|
||||
# UI
|
||||
def discord_toggle_pins():
|
||||
actions.key("ctrl-p")
|
||||
|
||||
def discord_toggle_inbox():
|
||||
actions.key("ctrl-i")
|
||||
|
||||
def discord_toggle_members():
|
||||
actions.key("ctrl-u")
|
||||
|
||||
def discord_emoji_picker():
|
||||
actions.key("ctrl-e")
|
||||
|
||||
def discord_gif_picker():
|
||||
actions.key("ctrl-g")
|
||||
|
||||
def discord_sticker_picker():
|
||||
actions.key("ctrl-s")
|
||||
|
||||
# Misc
|
||||
def messaging_mark_workspace_read():
|
||||
actions.key("shift-esc")
|
||||
|
||||
def messaging_mark_channel_read():
|
||||
actions.key("esc")
|
||||
|
||||
def messaging_upload_file():
|
||||
actions.key("ctrl-shift-u")
|
||||
|
||||
def discord_mark_inbox_read():
|
||||
actions.key("ctrl-shift-e")
|
||||
|
||||
def discord_mute():
|
||||
actions.key("ctrl-shift-m")
|
||||
|
||||
def discord_deafen():
|
||||
actions.key("ctrl-shift-d")
|
||||
|
||||
def discord_answer_call():
|
||||
actions.key("ctrl-enter")
|
||||
|
||||
def discord_decline_call():
|
||||
actions.key("esc")
|
||||
|
||||
def discord_go_current_call():
|
||||
actions.key("ctrl-shift-alt-v")
|
||||
|
||||
def discord_toggle_dms():
|
||||
actions.key("ctrl-alt-right")
|
||||
@@ -0,0 +1,50 @@
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from talon import Context, Module, actions, clip, ui
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
ctx.matches = """
|
||||
os: mac
|
||||
"""
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def dock_send_notification(notification: str):
|
||||
"""Send a CoreDock notification to the macOS Dock using SPI"""
|
||||
|
||||
def dock_app_expose(app: Optional[ui.App] = None):
|
||||
"""Activate macOS app Exposé via its Dock item (for the frontmost app if not specified)"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def dock_app_expose(app=None):
|
||||
if app is None:
|
||||
app = ui.active_app()
|
||||
|
||||
app_name = Path(app.path).stem
|
||||
dock_items = ui.apps(bundle="com.apple.dock")[0].children.find(
|
||||
AXSubrole="AXApplicationDockItem", AXTitle=app_name, max_depth=1
|
||||
)
|
||||
match len(dock_items):
|
||||
case 1:
|
||||
dock_items[0].perform("AXShowExpose")
|
||||
case 0:
|
||||
actions.app.notify(
|
||||
body=f"No dock icon for “{app_name}”",
|
||||
title="Unable to activate App Exposé",
|
||||
)
|
||||
case _:
|
||||
actions.app.notify(
|
||||
body=f"Multiple dock icons for “{app_name}”",
|
||||
title="Unable to activate App Exposé",
|
||||
)
|
||||
|
||||
def dock_send_notification(notification: str):
|
||||
from talon.mac.dock import dock_notify
|
||||
|
||||
dock_notify(notification)
|
||||
@@ -0,0 +1,5 @@
|
||||
os: mac
|
||||
-
|
||||
^desktop$: user.dock_send_notification("com.apple.showdesktop.awake")
|
||||
^window$: user.dock_app_expose()
|
||||
^launch pad$: user.dock_send_notification("com.apple.launchpad.toggle")
|
||||
@@ -0,0 +1,9 @@
|
||||
os: linux
|
||||
-
|
||||
|
||||
show notifications: key(ctrl-`)
|
||||
dismiss [notifications]: user.system_command("dunstctl close")
|
||||
dismiss all [notifications]: user.system_command("dunstctl close-all")
|
||||
#dunce pause: user.system_command('notify-send "DUNST_COMMAND_PAUSE"')
|
||||
#dunce resume: user.system_command('notify-send "DUNST_COMMAND_RESUME"')
|
||||
#test notification: user.system_command('notify-send "Hello from Talon"')
|
||||
@@ -0,0 +1,144 @@
|
||||
#custom eclipse commands go here
|
||||
app: eclipse
|
||||
-
|
||||
tag(): user.find_and_replace
|
||||
tag(): user.line_commands
|
||||
# tag(): user.multiple_cursors
|
||||
tag(): user.splits
|
||||
tag(): user.tabs
|
||||
tag(): user.command_search
|
||||
# splits.py support end
|
||||
|
||||
# Sidebar
|
||||
bar explore: key(alt-shift-w p)
|
||||
# bar extensions:
|
||||
bar outline: key(alt-shift-q o)
|
||||
|
||||
# bar run:
|
||||
|
||||
# bar source:
|
||||
# bar switch:
|
||||
|
||||
# Panels
|
||||
# panel control:
|
||||
panel output:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(c)
|
||||
panel problems:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(x)
|
||||
panel errors:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(l)
|
||||
panel breakpoints:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(b)
|
||||
panel search:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(s)
|
||||
panel variables:
|
||||
key(alt-shift-q)
|
||||
sleep(200ms)
|
||||
key(v)
|
||||
# panel switch:
|
||||
# panel terminal:
|
||||
|
||||
# Settings
|
||||
show settings: key(alt-w p)
|
||||
show shortcuts: key(ctrl-shift-l)
|
||||
#show snippets:
|
||||
|
||||
# Display
|
||||
# centered switch:
|
||||
# fullscreen switch:
|
||||
# theme switch:
|
||||
# wrap switch:
|
||||
# zen switch:
|
||||
|
||||
# File Commands
|
||||
file hunt [<user.text>]:
|
||||
key(ctrl-shift-r)
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
# file copy path:
|
||||
# file create sibling:
|
||||
file create: key(ctrl-n)
|
||||
file open folder: key(alt-shift-w x)
|
||||
file rename: key(alt-shift-w p enter f2)
|
||||
file reveal: key(alt-shift-w p enter)
|
||||
|
||||
# Language Features
|
||||
# suggest show:
|
||||
# hint show:
|
||||
# definition show:
|
||||
# definition peek:
|
||||
# definition side:
|
||||
# references show:
|
||||
# references find:
|
||||
# format that:
|
||||
# format selection:
|
||||
imports fix: key(ctrl-shift-o)
|
||||
# problem last:
|
||||
# problem fix:
|
||||
# rename that:
|
||||
# refactor that:
|
||||
# whitespace trim:
|
||||
# language switch:
|
||||
refactor rename: key(alt-shift-r)
|
||||
refactor this: key(alt-shift-i)
|
||||
|
||||
#code navigation
|
||||
(go declaration | follow): key(f3)
|
||||
go back: key(alt-left)
|
||||
go forward: key(alt-right)
|
||||
# go implementation:
|
||||
# go recent:
|
||||
# go type:
|
||||
# go usage:
|
||||
|
||||
# Bookmarks.
|
||||
#requires https://marketplace.eclipse.org/content/quick-bookmarks
|
||||
go marks: key(alt-end)
|
||||
toggle mark: key(ctrl-alt-b down enter)
|
||||
go next mark: key(alt-pagedown)
|
||||
go last mark: key(alt-pageup)
|
||||
|
||||
# Folding
|
||||
# fold that:
|
||||
# unfold that:
|
||||
# fold those:
|
||||
# unfold those:
|
||||
# fold all:
|
||||
# unfold all:
|
||||
# fold comments:
|
||||
|
||||
#Debugging
|
||||
break point: key(ctrl-shift-b)
|
||||
step over: key(f6)
|
||||
debug step into: key(f5)
|
||||
debug step out [of]: key(f7)
|
||||
#debug start: user.vscode("workbench.action.debug.start")
|
||||
#debug pause:
|
||||
#debug stopper:
|
||||
debug continue: key(f8)
|
||||
#debug restart:
|
||||
|
||||
# Terminal
|
||||
# terminal external: user.vscode("workbench.action.terminal.openNativeConsole")
|
||||
|
||||
# terminal new: user.vscode("workbench.action.terminal.new")
|
||||
# terminal next: user.vscode("workbench.action.terminal.focusNextPane")
|
||||
# terminal last:user.vscode("workbench.action.terminal.focusPreviousPane")
|
||||
# terminal split: user.vscode("workbench.action.terminal.split")
|
||||
# terminal trash: user.vscode("Terminal:Kill")
|
||||
# terminal scroll up: user.vscode("Terminal:ScrollUp")
|
||||
# terminal scroll down: user.vscode("Terminal:ScrollDown")
|
||||
|
||||
#TODO: should this be added to linecommands?
|
||||
copy line down: key(ctrl-alt-down)
|
||||
copy line up: key(ctrl-alt-up)
|
||||
@@ -0,0 +1,175 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.eclipse = """
|
||||
os: windows
|
||||
and app.name: eclipse.exe
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: eclipse
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
# talon app actions
|
||||
def tab_close():
|
||||
actions.key("ctrl-w")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
# action(app.tab_reopen):
|
||||
def window_close():
|
||||
actions.key("alt-f4")
|
||||
|
||||
def window_open():
|
||||
actions.key("alt-w n")
|
||||
|
||||
|
||||
@ctx.action_class("code")
|
||||
class CodeActions:
|
||||
# talon code actions
|
||||
def toggle_comment():
|
||||
actions.key("ctrl-7")
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def find_next():
|
||||
actions.key("enter")
|
||||
|
||||
def find_previous():
|
||||
actions.key("shift-enter")
|
||||
|
||||
def line_swap_up():
|
||||
actions.key("alt-up")
|
||||
|
||||
def line_swap_down():
|
||||
actions.key("alt-down")
|
||||
|
||||
def line_clone():
|
||||
actions.key("ctrl-alt-down")
|
||||
|
||||
def jump_line(n: int):
|
||||
actions.key("ctrl-l")
|
||||
actions.insert(str(n))
|
||||
actions.key("enter")
|
||||
|
||||
def delete_line():
|
||||
actions.key("ctrl-d")
|
||||
|
||||
def indent_more():
|
||||
actions.key("tab")
|
||||
|
||||
def indent_less():
|
||||
actions.key("shift-tab")
|
||||
|
||||
def save_all():
|
||||
actions.key("ctrl-shift-s")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# splits.py support begin
|
||||
# requires https://marketplace.eclipse.org/content/handysplit
|
||||
def split_clear_all():
|
||||
actions.key("alt-shift-s f")
|
||||
|
||||
def split_clear():
|
||||
actions.key("alt-shift-s f")
|
||||
|
||||
# action(user.split_flip):
|
||||
def split_last():
|
||||
actions.key("alt-shift-s t")
|
||||
|
||||
def split_next():
|
||||
actions.key("alt-shift-s t")
|
||||
|
||||
def split_window_down():
|
||||
actions.key("alt-shift-s m")
|
||||
|
||||
def split_window_horizontally():
|
||||
actions.key("alt-ctrl-s s")
|
||||
|
||||
def split_window_right():
|
||||
actions.key("alt-shift-s m")
|
||||
|
||||
def split_window_up():
|
||||
actions.key("alt-shift-s m")
|
||||
|
||||
def split_window_vertically():
|
||||
actions.key("alt-shift-s s")
|
||||
|
||||
def split_window():
|
||||
actions.key("alt-ctrl-s s")
|
||||
|
||||
def command_search(command: str = ""):
|
||||
actions.key("ctrl-3")
|
||||
if command != "":
|
||||
actions.insert(command)
|
||||
|
||||
# splits.py support end
|
||||
|
||||
# find_and_replace.py support begin
|
||||
|
||||
def find_everywhere(text: str):
|
||||
"""Triggers find across project"""
|
||||
actions.key("ctrl-h")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
# todo: these commands should only be available
|
||||
# when it's focused
|
||||
def find_toggle_match_by_case():
|
||||
"""Toggles find match by case sensitivity"""
|
||||
actions.key("alt-c")
|
||||
|
||||
def find_toggle_match_by_word():
|
||||
"""Toggles find match by whole words"""
|
||||
actions.key("alt-w")
|
||||
|
||||
def find_toggle_match_by_regex():
|
||||
"""Toggles find match by regex"""
|
||||
actions.key("alt-e")
|
||||
|
||||
def replace(text: str):
|
||||
"""Search and replaces in the active editor"""
|
||||
actions.key("ctrl-f")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_everywhere(text: str):
|
||||
"""Search and replaces in the entire project"""
|
||||
actions.key("alt-a f")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_confirm():
|
||||
"""Confirm replace at current position"""
|
||||
actions.key("alt-r")
|
||||
|
||||
def replace_confirm_all():
|
||||
"""Confirm replace all"""
|
||||
actions.key("alt-a")
|
||||
|
||||
def select_previous_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("alt-b alt-f enter esc")
|
||||
|
||||
def select_next_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("alt-f alt-o esc")
|
||||
|
||||
# find_and_replace.py support end
|
||||
@@ -0,0 +1,28 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
mod.apps.microsoft_edge = r"""
|
||||
os: windows
|
||||
and app.name: msedge.exe
|
||||
os: windows
|
||||
and app.name: Microsoft Edge
|
||||
os: windows
|
||||
and app.exe: /^msedge\.exe$/i
|
||||
os: mac
|
||||
and app.bundle: com.microsoft.edgemac
|
||||
os: linux
|
||||
and app.exe: msedge
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: microsoft_edge
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def show_extensions():
|
||||
actions.app.tab_open()
|
||||
actions.browser.go("edge://extensions")
|
||||
@@ -0,0 +1,4 @@
|
||||
app: microsoft_edge
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
@@ -0,0 +1,363 @@
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from talon import Context, Module, actions, settings
|
||||
|
||||
mod = Module()
|
||||
mod.setting(
|
||||
"emacs_meta",
|
||||
type=str,
|
||||
default="esc",
|
||||
desc="""What to use for the meta key in emacs. Defaults to 'esc', since that should work everywhere. Other options are 'alt' and 'cmd'.""",
|
||||
)
|
||||
|
||||
mod.apps.emacs = "app.name: Emacs"
|
||||
mod.apps.emacs = "app.name: emacs"
|
||||
mod.apps.emacs = "app.name: /^GNU Emacs/"
|
||||
mod.apps.emacs = """
|
||||
os: mac
|
||||
app.bundle: org.gnu.Emacs
|
||||
"""
|
||||
mod.apps.emacs = r"""
|
||||
os: windows
|
||||
app.exe: /^emacs\.exe$/i
|
||||
"""
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = "app: emacs"
|
||||
|
||||
|
||||
def meta(keys):
|
||||
m = settings.get("user.emacs_meta")
|
||||
if m == "alt":
|
||||
return " ".join("alt-" + k for k in keys.split())
|
||||
elif m == "cmd":
|
||||
return " ".join("cmd-" + k for k in keys.split())
|
||||
elif m != "esc":
|
||||
logging.error(
|
||||
f"Unrecognized 'emacs_meta' setting: {m!r}. Falling back to 'esc'."
|
||||
)
|
||||
return "esc " + keys
|
||||
|
||||
|
||||
def meta_fixup(k):
|
||||
if k.startswith("meta-"):
|
||||
k = meta(k[len("meta-") :])
|
||||
elif "meta-" in k:
|
||||
raise NotImplementedError("user.emacs_key(): please put meta- first")
|
||||
return k
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def emacs_meta(key: str):
|
||||
"Presses some keys modified by Emacs' meta key."
|
||||
actions.key(meta(key))
|
||||
|
||||
def emacs_key(keys: str):
|
||||
"""
|
||||
Presses some keys, translating 'meta-' prefix to the appropriate keys. For
|
||||
example, if the setting user.emacs_meta = 'esc', user.emacs_key("meta-ctrl-a")
|
||||
becomes key("esc ctrl-a").
|
||||
"""
|
||||
# TODO: handle corner-cases like key(" ") and key("ctrl- "), etc.
|
||||
actions.key(" ".join(meta_fixup(k) for k in keys.split()))
|
||||
|
||||
def emacs_prefix(n: Optional[int] = None):
|
||||
"Inputs a prefix argument."
|
||||
if n is None:
|
||||
# `M-x universal-argument` doesn't have the same effect as pressing the key.
|
||||
prefix_key = actions.user.emacs_command_keybinding("universal-argument")
|
||||
actions.key(prefix_key or "ctrl-u") # default to ctrl-u
|
||||
else:
|
||||
# Applying meta to each key can use fewer keypresses and 'works' in ansi-term
|
||||
# mode.
|
||||
actions.user.emacs_meta(" ".join(str(n)))
|
||||
|
||||
def emacs(command_name: str, prefix: Optional[int] = None):
|
||||
"""
|
||||
Runs the emacs command `command_name`. Defaults to using M-x, but may use
|
||||
a key binding if known or rpc if available. Provides numeric prefix argument
|
||||
`prefix` if specified.
|
||||
"""
|
||||
meta_x = actions.user.emacs_command_keybinding("execute-extended-command")
|
||||
keys = actions.user.emacs_command_keybinding(command_name)
|
||||
short_form = actions.user.emacs_command_short_form(command_name)
|
||||
if prefix is not None:
|
||||
actions.user.emacs_prefix(prefix)
|
||||
if keys is not None:
|
||||
actions.user.emacs_key(keys)
|
||||
else:
|
||||
actions.user.emacs_key(meta_x or "meta-x")
|
||||
actions.insert(short_form or command_name)
|
||||
actions.key("enter")
|
||||
|
||||
def emacs_help(key: str = None):
|
||||
"Runs the emacs help command prefix, optionally followed by some keys."
|
||||
# NB. f1 works in ansi-term mode; C-h doesn't.
|
||||
actions.key("f1")
|
||||
if key is not None:
|
||||
actions.key(key)
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def cut_line():
|
||||
actions.edit.line_start()
|
||||
actions.user.emacs("kill-line", 1)
|
||||
|
||||
def split_window():
|
||||
actions.user.emacs("split-window-below")
|
||||
|
||||
def split_window_vertically():
|
||||
actions.user.emacs("split-window-below")
|
||||
|
||||
def split_window_up():
|
||||
actions.user.emacs("split-window-below")
|
||||
|
||||
def split_window_down():
|
||||
actions.user.emacs("split-window-below")
|
||||
actions.user.emacs("other-window")
|
||||
|
||||
def split_window_horizontally():
|
||||
actions.user.emacs("split-window-right")
|
||||
|
||||
def split_window_left():
|
||||
actions.user.emacs("split-window-right")
|
||||
|
||||
def split_window_right():
|
||||
actions.user.emacs("split-window-right")
|
||||
actions.user.emacs("other-window")
|
||||
|
||||
def split_clear():
|
||||
actions.user.emacs("delete-window")
|
||||
|
||||
def split_clear_all():
|
||||
actions.user.emacs("delete-other-windows")
|
||||
|
||||
def split_reset():
|
||||
actions.user.emacs("balance-windows")
|
||||
|
||||
def split_next():
|
||||
actions.user.emacs("other-window")
|
||||
|
||||
def split_last():
|
||||
actions.user.emacs("other-window", -1)
|
||||
|
||||
def split_flip():
|
||||
# only works reliably if there are only two panes/windows.
|
||||
actions.key("ctrl-x b enter ctrl-x o ctrl-x b enter")
|
||||
actions.user.split_last()
|
||||
actions.key("ctrl-x b enter ctrl-x o")
|
||||
|
||||
def select_range(line_start, line_end):
|
||||
# Assumes transient mark mode.
|
||||
actions.edit.jump_line(line_start)
|
||||
actions.edit.jump_line(line_end + 1)
|
||||
actions.user.emacs("exchange-point-and-mark")
|
||||
|
||||
# # Version that highlights without transient-mark-mode:
|
||||
# def select_range(line_start, line_end):
|
||||
# actions.edit.jump_line(line_end + 1)
|
||||
# actions.key("ctrl-@ ctrl-@")
|
||||
# actions.edit.jump_line(line_start)
|
||||
|
||||
# dictation_peek() probably won't work in a terminal. PRs welcome.
|
||||
def dictation_peek(left, right):
|
||||
# clobber transient selection if it exists
|
||||
actions.key("space backspace")
|
||||
before, after = None, None
|
||||
if left:
|
||||
actions.edit.extend_word_left()
|
||||
before = actions.edit.selected_text()
|
||||
actions.user.emacs("pop-to-mark-command")
|
||||
if right:
|
||||
actions.edit.extend_line_end()
|
||||
after = actions.edit.selected_text()
|
||||
actions.user.emacs("pop-to-mark-command")
|
||||
return (before, after)
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def save():
|
||||
actions.user.emacs("save-buffer")
|
||||
|
||||
def save_all():
|
||||
actions.user.emacs("save-some-buffers")
|
||||
|
||||
def copy():
|
||||
actions.user.emacs("kill-ring-save")
|
||||
|
||||
def cut():
|
||||
actions.user.emacs("kill-region")
|
||||
|
||||
def undo():
|
||||
actions.user.emacs("undo")
|
||||
|
||||
def paste():
|
||||
actions.user.emacs("yank")
|
||||
|
||||
def delete():
|
||||
actions.user.emacs("kill-region")
|
||||
|
||||
def file_start():
|
||||
actions.user.emacs("beginning-of-buffer")
|
||||
|
||||
def file_end():
|
||||
actions.user.emacs("end-of-buffer")
|
||||
|
||||
# works for eg 'select to top', but not if preceded by other selections :(
|
||||
def extend_file_start():
|
||||
actions.user.emacs("beginning-of-buffer")
|
||||
|
||||
def extend_file_end():
|
||||
actions.user.emacs("end-of-buffer")
|
||||
|
||||
def select_none():
|
||||
actions.user.emacs("keyboard-quit")
|
||||
|
||||
def select_all():
|
||||
actions.user.emacs("mark-whole-buffer")
|
||||
# If you don't use transient-mark-mode, maybe do this:
|
||||
# actions.key('ctrl-u ctrl-x ctrl-x')
|
||||
|
||||
def word_left():
|
||||
actions.user.emacs("backward-word")
|
||||
|
||||
def word_right():
|
||||
actions.user.emacs("forward-word")
|
||||
|
||||
def extend_word_left():
|
||||
actions.user.emacs_meta("shift-b")
|
||||
|
||||
def extend_word_right():
|
||||
actions.user.emacs_meta("shift-f")
|
||||
|
||||
def sentence_start():
|
||||
actions.user.emacs("backward-sentence")
|
||||
|
||||
def sentence_end():
|
||||
actions.user.emacs("forward-sentence")
|
||||
|
||||
def extend_sentence_start():
|
||||
actions.user.emacs_meta("shift-a")
|
||||
|
||||
def extend_sentence_end():
|
||||
actions.user.emacs_meta("shift-e")
|
||||
|
||||
def paragraph_start():
|
||||
actions.user.emacs("backward-paragraph")
|
||||
|
||||
def paragraph_end():
|
||||
actions.user.emacs("forward-paragraph")
|
||||
|
||||
def line_start():
|
||||
actions.user.emacs("move-beginning-of-line")
|
||||
|
||||
def line_end():
|
||||
actions.user.emacs("move-end-of-line")
|
||||
|
||||
def extend_line_start():
|
||||
actions.key("shift-ctrl-a")
|
||||
|
||||
def extend_line_end():
|
||||
actions.key("shift-ctrl-e")
|
||||
|
||||
def line_swap_down():
|
||||
actions.key("down ctrl-x ctrl-t up")
|
||||
|
||||
def line_swap_up():
|
||||
actions.key("ctrl-x ctrl-t up:2")
|
||||
|
||||
def delete_line():
|
||||
actions.key("ctrl-a ctrl-k")
|
||||
|
||||
def line_clone():
|
||||
actions.user.emacs_key("ctrl-a meta-1 ctrl-k ctrl-y ctrl-y up meta-m")
|
||||
|
||||
def jump_line(n):
|
||||
actions.user.emacs("goto-line", n)
|
||||
|
||||
def select_line(n: int = None):
|
||||
if n is not None:
|
||||
actions.edit.jump_line(n)
|
||||
else:
|
||||
actions.edit.line_start()
|
||||
actions.edit.extend_line_end()
|
||||
actions.edit.extend_right()
|
||||
# This makes it so the cursor is on the same line, which can make
|
||||
# subsequent commands more convenient.
|
||||
actions.user.emacs("exchange-point-and-mark")
|
||||
|
||||
def indent_more():
|
||||
actions.user.emacs("indent-rigidly", 4)
|
||||
|
||||
def indent_less():
|
||||
actions.user.emacs("indent-rigidly", -4)
|
||||
|
||||
# These all perform text-scale-adjust, which examines the actual key pressed, so can't
|
||||
# be done with actions.user.emacs.
|
||||
def zoom_in():
|
||||
actions.key("ctrl-x ctrl-+")
|
||||
|
||||
def zoom_out():
|
||||
actions.key("ctrl-x ctrl--")
|
||||
|
||||
def zoom_reset():
|
||||
actions.key("ctrl-x ctrl-0")
|
||||
|
||||
# Some modes override ctrl-s/r to do something other than isearch-forward, so we
|
||||
# deliberately don't use actions.user.emacs.
|
||||
def find(text: str = None):
|
||||
actions.key("ctrl-s")
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def find_next():
|
||||
actions.key("ctrl-s")
|
||||
|
||||
def find_previous():
|
||||
actions.key("ctrl-r")
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def window_open():
|
||||
actions.user.emacs("make-frame-command")
|
||||
|
||||
def tab_next():
|
||||
actions.user.emacs("tab-next")
|
||||
|
||||
def tab_previous():
|
||||
actions.user.emacs("tab-previous")
|
||||
|
||||
def tab_close():
|
||||
actions.user.emacs("tab-close")
|
||||
|
||||
def tab_reopen():
|
||||
actions.user.emacs("tab-undo")
|
||||
|
||||
def tab_open():
|
||||
actions.user.emacs("tab-new")
|
||||
|
||||
|
||||
@ctx.action_class("code")
|
||||
class CodeActions:
|
||||
def toggle_comment():
|
||||
actions.user.emacs("comment-dwim")
|
||||
|
||||
def language():
|
||||
# Assumes win.filename() gives buffer name.
|
||||
if "*scratch*" == actions.win.filename():
|
||||
return "elisp"
|
||||
return actions.next()
|
||||
|
||||
|
||||
@ctx.action_class("win")
|
||||
class WinActions:
|
||||
# This assumes the title is/contains the filename.
|
||||
# To do this, put this in init.el:
|
||||
# (setq-default frame-title-format '((:eval (buffer-name (window-buffer (minibuffer-selected-window))))))
|
||||
def filename():
|
||||
return actions.win.title()
|
||||
@@ -0,0 +1,367 @@
|
||||
app: emacs
|
||||
-
|
||||
tag(): user.tabs
|
||||
tag(): user.splits
|
||||
tag(): user.line_commands
|
||||
|
||||
# ----- GENERAL ----- #
|
||||
#suplex: key(ctrl-x)
|
||||
cancel: user.emacs("keyboard-quit")
|
||||
exchange: user.emacs("exchange-point-and-mark")
|
||||
execute: user.emacs("execute-extended-command")
|
||||
execute {user.emacs_command}$: user.emacs(emacs_command)
|
||||
execute <user.text>$:
|
||||
user.emacs("execute-extended-command")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
evaluate | (evaluate | eval) (exper | expression): user.emacs("eval-expression")
|
||||
prefix: user.emacs_prefix()
|
||||
prefix <user.number_signed_small>: user.emacs_prefix(number_signed_small)
|
||||
|
||||
abort recursive [edit]: user.emacs("abort-recursive-edit")
|
||||
browse kill ring: user.emacs("browse-kill-ring")
|
||||
fill paragraph: user.emacs("fill-paragraph")
|
||||
insert char: user.emacs("insert-char")
|
||||
occurs: user.emacs("occur")
|
||||
other scroll [down]: user.emacs("scroll-other-window")
|
||||
other scroll up: user.emacs("scroll-other-window-down")
|
||||
package autoremove: user.emacs("package-autoremove")
|
||||
package list | [package] list packages: user.emacs("list-packages")
|
||||
reverse (lines | region): user.emacs("reverse-region")
|
||||
save buffers kill emacs: user.emacs("save-buffers-kill-emacs")
|
||||
save some buffers: user.emacs("save-some-buffers")
|
||||
sort lines: user.emacs("sort-lines")
|
||||
sort words: user.emacs("sort-words")
|
||||
file [loop] continue: user.emacs("fileloop-continue")
|
||||
|
||||
go directory: user.emacs("dired-jump")
|
||||
other go directory: user.emacs("dired-jump-other-window")
|
||||
|
||||
[toggle] debug on error: user.emacs("toggle-debug-on-error")
|
||||
[toggle] debug on quit: user.emacs("toggle-debug-on-quit")
|
||||
[toggle] input method: user.emacs("toggle-input-method")
|
||||
[toggle] truncate lines: user.emacs("toggle-truncate-lines")
|
||||
[toggle] word wrap: user.emacs("toggle-word-wrap")
|
||||
|
||||
manual: user.emacs("man")
|
||||
manual <user.text>:
|
||||
user.emacs("man")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
|
||||
# BUFFER SWITCHING #
|
||||
switch: user.emacs("switch-to-buffer")
|
||||
other switch: user.emacs("switch-to-buffer-other-window")
|
||||
display: user.emacs("display-buffer")
|
||||
|
||||
# SHELL COMMANDS #
|
||||
shell command: user.emacs("shell-command")
|
||||
shell command inserting:
|
||||
user.emacs_prefix()
|
||||
user.emacs("shell-command")
|
||||
shell command on region: user.emacs("shell-command-on-region")
|
||||
shell command on region replacing:
|
||||
user.emacs_prefix()
|
||||
user.emacs("shell-command-on-region")
|
||||
|
||||
# CUSTOMIZE #
|
||||
customize face: user.emacs("customize-face")
|
||||
customize face <user.text>$:
|
||||
user.emacs("customize-face")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
customize group: user.emacs("customize-group")
|
||||
customize variable: user.emacs("customize-variable")
|
||||
(customize | custom) [theme] visit theme: user.emacs("custom-theme-visit-theme")
|
||||
|
||||
# MODE COMMANDS #
|
||||
auto fill mode: user.emacs("auto-fill-mode")
|
||||
dired omit mode: user.emacs("dired-omit-mode")
|
||||
display line numbers mode: user.emacs("display-line-numbers-mode")
|
||||
electric quote local mode: user.emacs("electric-quote-local-mode")
|
||||
emacs lisp mode: user.emacs("emacs-lisp-mode")
|
||||
fundamental mode: user.emacs("fundamental-mode")
|
||||
global display line numbers mode: user.emacs("global-display-line-numbers-mode")
|
||||
global highlight line mode: user.emacs("global-hl-line-mode")
|
||||
global visual line mode: user.emacs("global-visual-line-mode")
|
||||
highlight line mode: user.emacs("hl-line-mode")
|
||||
lisp interaction mode: user.emacs("lisp-interaction-mode")
|
||||
markdown mode: user.emacs("markdown-mode")
|
||||
menu bar mode: user.emacs("menu-bar-mode")
|
||||
overwrite mode: user.emacs("overwrite-mode")
|
||||
paredit mode: user.emacs("paredit-mode")
|
||||
rainbow mode: user.emacs("rainbow-mode")
|
||||
read only mode: user.emacs("read-only-mode")
|
||||
shell script mode: user.emacs("sh-mode")
|
||||
sub word mode: user.emacs("subword-mode")
|
||||
tab bar mode: user.emacs("tab-bar-mode")
|
||||
talon script mode: user.emacs("talonscript-mode")
|
||||
text mode: user.emacs("text-mode")
|
||||
transient mark mode: user.emacs("transient-mark-mode")
|
||||
visual line mode: user.emacs("visual-line-mode")
|
||||
whitespace mode: user.emacs("whitespace-mode")
|
||||
|
||||
# MACROS #
|
||||
emacs record: user.emacs("kmacro-start-macro")
|
||||
emacs stop: user.emacs("kmacro-end-macro")
|
||||
emacs play: user.emacs("kmacro-end-and-call-macro")
|
||||
|
||||
# PROFILER #
|
||||
profiler start: user.emacs("profiler-start")
|
||||
profiler stop: user.emacs("profiler-stop")
|
||||
profiler report: user.emacs("profiler-report")
|
||||
|
||||
# WINDOW/SPLIT MANAGEMENT #
|
||||
# What emacs calls windows, we call splits.
|
||||
split solo: user.emacs("delete-other-windows")
|
||||
[split] rebalance: user.emacs("balance-windows")
|
||||
split shrink: user.emacs("shrink-window-if-larger-than-buffer")
|
||||
other [split] shrink:
|
||||
user.split_next()
|
||||
user.emacs("shrink-window-if-larger-than-buffer")
|
||||
user.split_last()
|
||||
split grow: user.emacs("enlarge-window")
|
||||
split grow <number_small>: user.emacs("enlarge-window", number_small)
|
||||
split shrink <number_small>:
|
||||
amount = number_small or 1
|
||||
user.emacs("enlarge-window", 0 - amount)
|
||||
split widen [<number_small>]:
|
||||
user.emacs("enlarge-window-horizontally", number_small or 1)
|
||||
split narrow [<number_small>]:
|
||||
user.emacs("shrink-window-horizontally", number_small or 1)
|
||||
|
||||
# ----- HELP ----- #
|
||||
apropos: user.emacs_help("a")
|
||||
describe (fun | function): user.emacs_help("f")
|
||||
describe key: user.emacs_help("k")
|
||||
describe key briefly: user.emacs_help("c")
|
||||
describe symbol: user.emacs_help("o")
|
||||
describe variable: user.emacs_help("v")
|
||||
describe mode: user.emacs_help("m")
|
||||
describe bindings: user.emacs_help("b")
|
||||
describe (char | character): user.emacs("describe-character")
|
||||
describe text properties: user.emacs("describe-text-properties")
|
||||
describe face: user.emacs("describe-face")
|
||||
view lossage: user.emacs_help("l")
|
||||
|
||||
apropos <user.text>$:
|
||||
user.emacs_help("a")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
key(enter)
|
||||
describe (fun | function) <user.text>$:
|
||||
user.emacs_help("f")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
key(enter)
|
||||
describe symbol <user.text>$:
|
||||
user.emacs_help("o")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
key(enter)
|
||||
describe variable <user.text>$:
|
||||
user.emacs_help("v")
|
||||
user.insert_formatted(text, "DASH_SEPARATED")
|
||||
key(enter)
|
||||
|
||||
# ----- FILES & BUFFERS -----
|
||||
file open: user.emacs("find-file")
|
||||
file rename: user.emacs("rename-file")
|
||||
(file open | find file) at point: user.emacs("ffap")
|
||||
other file open: user.emacs("find-file-other-window")
|
||||
(file | buffer) close:
|
||||
user.emacs("kill-buffer")
|
||||
key(enter)
|
||||
|
||||
buffer kill: user.emacs("kill-buffer")
|
||||
buffer bury: user.emacs("bury-buffer")
|
||||
buffer revert | revert buffer: user.emacs("revert-buffer")
|
||||
buffer finish:
|
||||
edit.save()
|
||||
user.emacs("server-edit")
|
||||
buffer list: user.emacs("buffer-menu")
|
||||
buffer next: user.emacs("next-buffer")
|
||||
buffer last: user.emacs("previous-buffer")
|
||||
buffer rename: user.emacs("rename-buffer")
|
||||
buffer widen: user.emacs("widen")
|
||||
buffer narrow | [buffer] narrow to region: user.emacs("narrow-to-region")
|
||||
|
||||
diff (buffer | [buffer] with file):
|
||||
user.emacs("diff-buffer-with-file")
|
||||
key(enter)
|
||||
|
||||
# ----- MOTION AND EDITING ----- #
|
||||
mark: user.emacs("set-mark-command")
|
||||
go back: user.emacs("pop-to-mark-command")
|
||||
global [go] back: user.emacs("pop-global-mark")
|
||||
|
||||
auto indent: user.emacs("indent-region")
|
||||
indent <user.number_signed_small>: user.emacs("indent-rigidly", number_signed_small)
|
||||
|
||||
search back: user.emacs("isearch-backward")
|
||||
(search regex | regex search): user.emacs("isearch-forward-regexp")
|
||||
(search regex | regex search) back: user.emacs("isearch-backward-regexp")
|
||||
replace: user.emacs("query-replace")
|
||||
replace regex | regex replace: user.emacs("query-replace-regexp")
|
||||
# These start a word/symbol-search or toggle an existing search's mode.
|
||||
search [toggle] words: user.emacs("isearch-forward-word")
|
||||
search [toggle] symbol: user.emacs("isearch-forward-symbol")
|
||||
# These keybindings are only active in isearch-mode.
|
||||
search edit: user.emacs_meta("e")
|
||||
search toggle case [fold | sensitive]: user.emacs_meta("c")
|
||||
search toggle regex: user.emacs_meta("r")
|
||||
|
||||
highlight lines matching [regex]: user.emacs("highlight-lines-matching-regexp")
|
||||
highlight phrase: user.emacs("highlight-phrase")
|
||||
highlight regex: user.emacs("highlight-regexp")
|
||||
unhighlight (regex | phrase): user.emacs("unhighlight-regexp")
|
||||
unhighlight all:
|
||||
user.emacs_prefix()
|
||||
user.emacs("unhighlight-regexp")
|
||||
|
||||
recenter:
|
||||
user.emacs_prefix()
|
||||
user.emacs("recenter-top-bottom")
|
||||
(center | [center] <number_small> from) top:
|
||||
user.emacs("recenter-top-bottom", number_small or 0)
|
||||
(center | [center] <number_small> from) bottom:
|
||||
number = number_small or 0
|
||||
user.emacs("recenter-top-bottom", -1 - number)
|
||||
go <number> top:
|
||||
edit.jump_line(number)
|
||||
user.emacs("recenter-top-bottom", 0)
|
||||
go <number> bottom:
|
||||
edit.jump_line(number)
|
||||
user.emacs("recenter-top-bottom", -2)
|
||||
|
||||
next error | error next: user.emacs("next-error")
|
||||
last error | error last: user.emacs("previous-error")
|
||||
|
||||
term right: user.emacs("forward-sexp")
|
||||
term left: user.emacs("backward-sexp")
|
||||
term up: user.emacs("backward-up-list")
|
||||
term end: user.emacs("up-list")
|
||||
term down: user.emacs("down-list")
|
||||
term kill: user.emacs("kill-sexp")
|
||||
term wipe: user.emacs("kill-sexp", -1)
|
||||
term (mark | select): user.emacs("mark-sexp")
|
||||
term copy:
|
||||
user.emacs("mark-sexp")
|
||||
edit.copy()
|
||||
term freeze:
|
||||
user.emacs("mark-sexp")
|
||||
user.emacs("comment-region")
|
||||
term [auto] indent:
|
||||
user.emacs("mark-sexp")
|
||||
user.emacs("indent-region")
|
||||
|
||||
(sentence | sent) (right | end): edit.sentence_end()
|
||||
(sentence | sent) (left | start): edit.sentence_start()
|
||||
(sentence | sent) kill: user.emacs("kill-sentence")
|
||||
|
||||
graph kill: user.emacs("kill-paragraph")
|
||||
graph up: edit.paragraph_start()
|
||||
graph down: edit.paragraph_end()
|
||||
graph mark: user.emacs("mark-paragraph")
|
||||
graph copy:
|
||||
user.emacs("mark-paragraph")
|
||||
edit.copy()
|
||||
graph cut:
|
||||
user.emacs("mark-paragraph")
|
||||
edit.cut()
|
||||
|
||||
# NB. can use these to implement "drag <X> left/right/up/down" commands,
|
||||
# but note that 'transpose line' and 'drag line down' are different.
|
||||
transpose [word | words]: user.emacs("transpose-words")
|
||||
transpose (term | terms): user.emacs("transpose-sexps")
|
||||
transpose (char | chars): user.emacs("transpose-chars")
|
||||
transpose (line | lines): user.emacs("transpose-lines")
|
||||
transpose (sentence | sentences): user.emacs("transpose-sentences")
|
||||
transpose (graph | graphs | paragraphs): user.emacs("transpose-paragraphs")
|
||||
|
||||
register (copy | save): user.emacs("copy-to-register")
|
||||
register (paste | insert): user.emacs("insert-register")
|
||||
register jump: user.emacs("jump-to-register")
|
||||
register (copy | save) rectangle: user.emacs("copy-rectangle-to-register")
|
||||
|
||||
rectangle clear: user.emacs("clear-rectangle")
|
||||
rectangle delete: user.emacs("delete-rectangle")
|
||||
rectangle kill: user.emacs("kill-rectangle")
|
||||
rectangle open: user.emacs("open-rectangle")
|
||||
rectangle (copy | save) [to] register: user.emacs("copy-rectangle-to-register")
|
||||
rectangle (yank | paste): user.emacs("yank-rectangle")
|
||||
rectangle copy: user.emacs("copy-rectangle-as-kill")
|
||||
rectangle number lines: user.emacs("rectangle-number-lines")
|
||||
|
||||
# ----- XREF SUPPORT ----- #
|
||||
[xref] find definition: user.emacs("xref-find-definitions")
|
||||
[xref] find definition other window: user.emacs("xref-find-definitions-other-window")
|
||||
[xref] find definition other frame: user.emacs("xref-find-definitions-other-frame")
|
||||
[xref] find references: user.emacs("xref-find-references")
|
||||
[xref] find references [and] replace: user.emacs("xref-find-references-and-replace")
|
||||
xref find apropos: user.emacs("xref-find-apropos")
|
||||
xref go back: user.emacs("xref-go-back")
|
||||
visit tags table: user.emacs("visit-tags-table")
|
||||
|
||||
# ----- PROJECT SUPPORT ----- #
|
||||
project [find] file: user.emacs("project-find-file")
|
||||
project [find] (regex | grep): user.emacs("project-find-regexp")
|
||||
project [query] replace regex: user.emacs("project-query-replace-regexp")
|
||||
project (dired | directory): user.emacs("projectile-dired")
|
||||
project [run] shell: user.emacs("projectile-run-shell")
|
||||
project [run] eshell: user.emacs("projectile-run-eshell")
|
||||
project search: user.emacs("project-search")
|
||||
project vc dir: user.emacs("project-vc-dir")
|
||||
project compile [project]: user.emacs("projectile-compile-project")
|
||||
project [run] shell command: user.emacs("projectile-run-shell-command-in-root")
|
||||
project [run] async shell command:
|
||||
user.emacs("projectile-run-async-shell-command-in-root")
|
||||
project (switch [to buffer] | buffer | buff): user.emacs("projectile-switch-to-buffer")
|
||||
project kill [buffers]: user.emacs("projectile-kill-buffers")
|
||||
project switch [project]: user.emacs("project-switch-project")
|
||||
|
||||
# ----- VC/GIT SUPPORT ----- #
|
||||
vc (annotate | blame): user.emacs("vc-annotate")
|
||||
|
||||
# ----- MAJOR & MINOR MODES ----- #
|
||||
# python-mode #
|
||||
python mode: user.emacs("python-mode")
|
||||
run python: user.emacs("run-python")
|
||||
python [shell] send buffer: user.emacs("python-shell-send-buffer")
|
||||
python [shell] send file: user.emacs("python-shell-send-file")
|
||||
python [shell] send region: user.emacs("python-shell-send-region")
|
||||
python [shell] send (function | defun): user.emacs("python-shell-send-defun")
|
||||
python [shell] send statement: user.emacs("python-shell-send-statement")
|
||||
python (shell switch | switch [to] shell): user.emacs("python-shell-switch-to-shell")
|
||||
|
||||
# smerge-mode #
|
||||
smerge mode: user.emacs("smerge-mode")
|
||||
merge next: user.emacs("smerge-next")
|
||||
merge last: user.emacs("smerge-prev")
|
||||
merge keep upper: user.emacs("smerge-keep-upper")
|
||||
merge keep lower: user.emacs("smerge-keep-lower")
|
||||
merge keep base: user.emacs("smerge-keep-base")
|
||||
merge keep (this | current): user.emacs("smerge-keep-current")
|
||||
merge refine: user.emacs("smerge-refine")
|
||||
merge split: user.emacs("smerge-resolve")
|
||||
|
||||
# outline-minor-mode #
|
||||
# frequent: overview, show, hide, next, last, forward, backward, up
|
||||
outline minor mode: user.emacs("outline-minor-mode")
|
||||
outline show all: user.emacs("outline-show-all")
|
||||
outline show entry: user.emacs("outline-show-entry")
|
||||
outline hide entry: user.emacs("outline-hide-entry")
|
||||
outline show [subtree]: user.emacs("outline-show-subtree")
|
||||
outline hide [subtree]: user.emacs("outline-hide-subtree")
|
||||
outline show children: user.emacs("outline-show-children")
|
||||
outline show branches: user.emacs("outline-show-branches")
|
||||
outline hide leaves: user.emacs("outline-hide-leaves")
|
||||
outline hide sublevels: user.emacs("outline-hide-sublevels")
|
||||
outline (hide body | [show] (overview | outline)): user.emacs("outline-hide-body")
|
||||
outline hide other: user.emacs("outline-hide-other")
|
||||
outline forward [same level]: user.emacs("outline-forward-same-level")
|
||||
outline (backward | back) [same level]: user.emacs("outline-backward-same-level")
|
||||
outline next [visible heading]: user.emacs("outline-next-visible-heading")
|
||||
outline (previous | last) [visible heading]:
|
||||
user.emacs("outline-previous-visible-heading")
|
||||
outline insert [heading]: user.emacs("outline-insert-heading")
|
||||
outline up [heading]: user.emacs("outline-up-heading")
|
||||
outline promote: user.emacs("outline-promote")
|
||||
outline demote: user.emacs("outline-demote")
|
||||
outline move [subtree] down: user.emacs("outline-move-subtree-down")
|
||||
outline move [subtree] up: user.emacs("outline-move-subtree-up")
|
||||
outline mark [subtree]: user.emacs("outline-mark-subtree")
|
||||
@@ -0,0 +1,231 @@
|
||||
Command, Key binding, Short form, Spoken form
|
||||
abort-recursive-edit, ctrl-]
|
||||
auto-fill-mode,, auto-f
|
||||
backward-paragraph, meta-{
|
||||
backward-sentence, meta-a
|
||||
backward-sexp, meta-ctrl-b
|
||||
backward-up-list, meta-ctrl-up
|
||||
backward-word, meta-b
|
||||
balance-windows, ctrl-x +
|
||||
beginning-of-buffer, meta-<
|
||||
browse-kill-ring,, b-k-r
|
||||
buffer-menu, ctrl-x ctrl-b
|
||||
bury-buffer,, bur
|
||||
byte-compile-file,, by-c
|
||||
byte-recompile-directory
|
||||
byte-recompile-file
|
||||
clear-rectangle, ctrl-x r c
|
||||
clone-indirect-buffer,, clo-i
|
||||
comment-dwim, meta-;
|
||||
comment-line,, comment-l
|
||||
comment-region, ctrl-c ;
|
||||
compile
|
||||
compile-defun,, co-def
|
||||
copy-rectangle-as-kill, ctrl-x r meta-w
|
||||
copy-rectangle-to-register, ctrl-x r r
|
||||
copy-to-register, ctrl-x r s
|
||||
custom-theme-visit-theme
|
||||
customize-face
|
||||
customize-group
|
||||
customize-variable
|
||||
delete-other-windows, ctrl-x 1
|
||||
delete-rectangle, ctrl-x r d
|
||||
delete-window, ctrl-x 0
|
||||
describe-character,, desc-char
|
||||
diff-buffer-with-file,, d-b-w-f
|
||||
display-buffer, ctrl-x 4 ctrl-o
|
||||
dired-jump, ctrl-x ctrl-j
|
||||
dired-jump-other-window, ctrl-x 4 ctrl-j
|
||||
display-buffer, ctrl-x 4 ctrl-o
|
||||
display-line-numbers-mode,, dis-num
|
||||
down-list, meta-ctrl-down
|
||||
electric-quote-local-mode
|
||||
electric-quote-mode
|
||||
end-of-buffer, meta->
|
||||
enlarge-window, ctrl-x ^
|
||||
enlarge-window-horizontally, ctrl-x }
|
||||
eval-expression, meta-:
|
||||
eval-print-last-sexp,, ev-p
|
||||
eval-region,, ev-r
|
||||
exchange-point-and-mark, ctrl-x ctrl-x
|
||||
execute-extended-command, meta-x
|
||||
fileloop-continue,, filel
|
||||
fill-paragraph, meta-q
|
||||
find-file, ctrl-x ctrl-f
|
||||
font-lock-update, ctrl-x x f
|
||||
forward-paragraph, meta-}
|
||||
forward-sentence, meta-e
|
||||
forward-sexp, meta-ctrl-f
|
||||
forward-word, meta-f
|
||||
fundamental-mode,, fun-m
|
||||
global-display-line-numbers-mode,, g-d-l-n-m
|
||||
global-hl-line-mode,, g-hl-l-m
|
||||
global-visual-line-mode,, gl-v-l-m
|
||||
goto-line, meta-g meta-g
|
||||
highlight-lines-matching-regexp, meta-s h l
|
||||
highlight-phrase, meta-s h p
|
||||
highlight-regexp, meta-s h r
|
||||
hl-line-mode,, hl-l-m
|
||||
indent-region, meta-ctrl-\
|
||||
indent-rigidly, ctrl-x tab
|
||||
insert-char, ctrl-x 8 enter
|
||||
insert-register, ctrl-x r i
|
||||
isearch-backward, ctrl-r
|
||||
isearch-backward-regexp, meta-ctrl-r
|
||||
isearch-forward, ctrl-s
|
||||
isearch-forward-regexp, meta-ctrl-s
|
||||
isearch-forward-symbol, meta-s _
|
||||
isearch-forward-word, meta-s w
|
||||
jump-to-register, ctrl-x r j
|
||||
keyboard-quit, ctrl-g
|
||||
kill-buffer, ctrl-x k
|
||||
kill-line, ctrl-k
|
||||
kill-paragraph,, kill-par
|
||||
kill-rectangle, ctrl-x r k
|
||||
kill-region, ctrl-w
|
||||
kill-ring-save, meta-w
|
||||
kill-sentence, meta-k
|
||||
kill-sexp, meta-ctrl-k
|
||||
kill-word, meta-d
|
||||
kmacro-end-and-call-macro, ctrl-x e
|
||||
kmacro-end-macro, ctrl-x )
|
||||
kmacro-start-macro, ctrl-x (
|
||||
list-packages
|
||||
make-frame-command, ctrl-x 5 2
|
||||
mark-paragraph, meta-h
|
||||
mark-sexp, meta-ctrl-@
|
||||
mark-whole-buffer, ctrl-x h
|
||||
move-beginning-of-line, ctrl-a
|
||||
move-end-of-line, ctrl-e
|
||||
narrow-to-region, ctrl-x n n
|
||||
next-buffer, ctrl-x right
|
||||
next-error, meta-g n
|
||||
occur, meta-s o
|
||||
open-rectangle, ctrl-x r o
|
||||
other-frame, ctrl-x 5 o
|
||||
other-window, ctrl-x o
|
||||
outline-backward-same-level, ctrl-c @ ctrl-b
|
||||
outline-demote, ctrl-c @ ctrl->
|
||||
outline-forward-same-level, ctrl-c @ ctrl-f
|
||||
outline-hide-body, ctrl-c @ ctrl-t
|
||||
outline-hide-entry, ctrl-c @ ctrl-c
|
||||
outline-hide-leaves, ctrl-c @ ctrl-l
|
||||
outline-hide-other, ctrl-c @ ctrl-o
|
||||
outline-hide-sublevels, ctrl-c @ ctrl-q
|
||||
outline-hide-subtree, ctrl-c @ ctrl-d
|
||||
outline-insert-heading, ctrl-c @ RET
|
||||
outline-mark-subtree, ctrl-c @ @
|
||||
outline-move-subtree-down, ctrl-c @ ctrl-v
|
||||
outline-move-subtree-up, ctrl-c @ ctrl-^
|
||||
outline-next-visible-heading, ctrl-c @ ctrl-n
|
||||
outline-previous-visible-heading, ctrl-c @ ctrl-p
|
||||
outline-promote, ctrl-c @ ctrl-<
|
||||
outline-show-all, ctrl-c @ ctrl-a
|
||||
outline-show-branches, ctrl-c @ ctrl-k
|
||||
outline-show-children, ctrl-c @ tab
|
||||
outline-show-entry, ctrl-c @ ctrl-e
|
||||
outline-show-subtree, ctrl-c @ ctrl-s
|
||||
outline-up-heading, ctrl-c @ ctrl-u
|
||||
overwrite-mode,, overwr
|
||||
package-autoremove
|
||||
pop-global-mark, ctrl-x ctrl-@
|
||||
pop-to-mark-command, ctrl-u ctrl-space
|
||||
previous-buffer, ctrl-x left
|
||||
previous-error, meta-g p
|
||||
project-find-file, ctrl-x p f
|
||||
project-find-regexp, ctrl-x p g
|
||||
project-query-replace-regexp, ctrl-x p r
|
||||
project-search, ctrl-x p ctrl-s
|
||||
project-switch-project
|
||||
project-vc-dir, ctrl-x p v
|
||||
projectile-compile-project, ctrl-x p c
|
||||
projectile-dired, ctrl-x p d
|
||||
projectile-kill-buffers, ctrl-x p k
|
||||
projectile-run-async-shell-command-in-root, ctrl-x p &
|
||||
projectile-run-eshell, ctrl-x p e
|
||||
projectile-run-shell, ctrl-x p s
|
||||
projectile-run-shell-command-in-root, ctrl-x p !
|
||||
projectile-switch-to-buffer, ctrl-x p b
|
||||
query-replace, meta-%
|
||||
query-replace-regexp, meta-ctrl-%
|
||||
read-only-mode, ctrl-x ctrl-q
|
||||
recenter-top-bottom, ctrl-l
|
||||
recenter-top-bottom, ctrl-l
|
||||
rectangle-number-lines, ctrl-x r N
|
||||
rename-buffer, ctrl-x x r, ren-b
|
||||
rename-uniquely, ctrl-x x u
|
||||
reverse-region
|
||||
revert-buffer,, rev-buf
|
||||
revert-buffer-quick, ctrl-x x g
|
||||
save-buffer, ctrl-x ctrl-s
|
||||
save-buffers-kill-emacs,, s-b-k-e
|
||||
save-some-buffers, ctrl-x s
|
||||
scroll-other-window, meta-pagedown
|
||||
scroll-other-window-down, meta-pageup
|
||||
server-edit, ctrl-x #
|
||||
set-mark-command, ctrl-@
|
||||
sh-mode
|
||||
shell-command, meta-!
|
||||
shell-command-on-region, meta-|
|
||||
shell-script-mode
|
||||
shrink-window-horizontally, ctrl-x {
|
||||
shrink-window-if-larger-than-buffer, ctrl-x -
|
||||
smerge-combine-with-next
|
||||
smerge-diff-base-lower
|
||||
smerge-diff-base-upper
|
||||
smerge-diff-upper-lower
|
||||
smerge-ediff
|
||||
smerge-keep-all
|
||||
smerge-keep-base
|
||||
smerge-keep-current, ctrl-c ^ enter
|
||||
smerge-keep-lower, ctrl-c ^ l
|
||||
smerge-keep-upper, ctrl-c ^ u
|
||||
smerge-next, ctrl-c ^ n
|
||||
smerge-prev, ctrl-c ^ p
|
||||
smerge-refine, ctrl-c ^ R
|
||||
smerge-resolve, ctrl-c ^ r
|
||||
sort-lines
|
||||
sort-words
|
||||
split-window-below, ctrl-x 2
|
||||
split-window-right, ctrl-x 3
|
||||
switch-to-buffer, ctrl-x b
|
||||
switch-to-buffer-other-window, ctrl-x 4 b
|
||||
tab-bar-mode
|
||||
tab-close, ctrl-x t 0
|
||||
tab-close-other, ctrl-x t 1
|
||||
tab-new, ctrl-x t 2
|
||||
tab-next, ctrl-x t o
|
||||
tab-previous, ctrl-x t O
|
||||
tab-undo, ctrl-x t u
|
||||
text-mode,, text-m
|
||||
toggle-debug-on-error,, t-d-on-e
|
||||
toggle-debug-on-quit,, t-d-on-q
|
||||
toggle-input-method, ctrl-\
|
||||
toggle-truncate-lines, ctrl-x x t
|
||||
toggle-word-wrap
|
||||
transient-mark-mode,, tr-m-m
|
||||
transpose-chars, ctrl-t
|
||||
transpose-lines, ctrl-x ctrl-t
|
||||
transpose-paragraphs,, tr-par
|
||||
transpose-sentences,, tr-sen
|
||||
transpose-sexps, meta-ctrl-t
|
||||
transpose-words, meta-t
|
||||
undo, ctrl-_
|
||||
unhighlight-regexp, meta-s h u
|
||||
universal-argument, ctrl-u
|
||||
vc-annotate, ctrl-x v g
|
||||
view-lossage, ctrl-h l
|
||||
visit-tags-table,, v-t-t
|
||||
visual-line-mode,, visu-l-m
|
||||
whitespace-cleanup,, wh-cl
|
||||
whitespace-mode,, white-m
|
||||
widen, ctrl-x n w
|
||||
xref-find-apropos, meta-ctrl-.
|
||||
xref-find-definitions, meta-.
|
||||
xref-find-definitions-other-frame, ctrl-x 5 .
|
||||
xref-find-definitions-other-window, ctrl-x 4 .
|
||||
xref-find-references, meta-?
|
||||
xref-find-references-and-replace
|
||||
xref-go-back,"meta-,"
|
||||
yank, ctrl-y
|
||||
yank-rectangle, ctrl-x r y
|
||||
|
@@ -0,0 +1,71 @@
|
||||
import csv
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
from talon import Context, Module, actions, app, resource
|
||||
|
||||
mod = Module()
|
||||
mod.list("emacs_command", desc="Emacs commands")
|
||||
|
||||
ctx = Context()
|
||||
|
||||
|
||||
class Command(NamedTuple):
|
||||
name: str
|
||||
keys: Optional[str] = None
|
||||
short: Optional[str] = None
|
||||
spoken: Optional[str] = None
|
||||
|
||||
|
||||
# Maps command name to Command.
|
||||
emacs_commands = {}
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def emacs_command_keybinding(command_name: str) -> Optional[str]:
|
||||
"Looks up the keybinding for command_name in emacs_commands.csv."
|
||||
return emacs_commands.get(command_name, Command(command_name)).keys
|
||||
|
||||
def emacs_command_short_form(command_name: str) -> Optional[str]:
|
||||
"Looks up the short form for command_name in emacs_commands.csv."
|
||||
return emacs_commands.get(command_name, Command(command_name)).short
|
||||
|
||||
|
||||
@resource.watch("emacs_commands.csv")
|
||||
def load_commands(f):
|
||||
rows = list(csv.reader(f))
|
||||
# Check headers
|
||||
assert rows[0] == ["Command", " Key binding", " Short form", " Spoken form"]
|
||||
|
||||
commands = []
|
||||
for row in rows[1:]:
|
||||
if 0 == len(row):
|
||||
continue
|
||||
if len(row) > 4:
|
||||
print(
|
||||
f"emacs_commands.csv: More than four values in row: {row}. "
|
||||
+ " Ignoring the extras"
|
||||
)
|
||||
name, keys, short, spoken = (
|
||||
[x.strip() or None for x in row] + [None, None, None]
|
||||
)[:4]
|
||||
commands.append(Command(name=name, keys=keys, short=short, spoken=spoken))
|
||||
|
||||
# Update global command info.
|
||||
global emacs_commands
|
||||
emacs_commands = {c.name: c for c in commands}
|
||||
|
||||
# Generate spoken forms and apply overrides.
|
||||
try:
|
||||
command_list = actions.user.create_spoken_forms_from_list(
|
||||
[c.name for c in commands], generate_subsequences=False
|
||||
)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
for c in commands:
|
||||
if c.spoken:
|
||||
command_list[c.spoken] = c.name
|
||||
ctx.lists["self.emacs_command"] = command_list
|
||||
@@ -0,0 +1,6 @@
|
||||
app: evernote
|
||||
os: mac
|
||||
-
|
||||
settings():
|
||||
# Necessary to stop commands like 'slap' getting jumbled
|
||||
key_wait = 9.0
|
||||
@@ -0,0 +1,4 @@
|
||||
app: evince
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
@@ -0,0 +1,39 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.evince = """
|
||||
os: linux
|
||||
and app.name: Evince
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: evince
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_current():
|
||||
actions.key("ctrl-l")
|
||||
page = actions.edit.selected_text()
|
||||
actions.key("escape")
|
||||
return int(page)
|
||||
|
||||
def page_next():
|
||||
actions.key("n")
|
||||
|
||||
def page_previous():
|
||||
actions.key("p")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-l")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
|
||||
def page_final():
|
||||
actions.key("ctrl-end")
|
||||
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
|
||||
from talon import Context, actions, ui
|
||||
from talon.mac import applescript
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: finder
|
||||
"""
|
||||
directories_to_remap = {"": "/Volumes"}
|
||||
directories_to_exclude = {}
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def file_manager_open_parent():
|
||||
actions.key("cmd-up")
|
||||
|
||||
def file_manager_current_path():
|
||||
title = ui.active_window().title
|
||||
|
||||
if "~" in title:
|
||||
title = os.path.expanduser(title)
|
||||
|
||||
if title in directories_to_remap:
|
||||
title = directories_to_remap[title]
|
||||
|
||||
if title in directories_to_exclude:
|
||||
title = ""
|
||||
|
||||
return title
|
||||
|
||||
def file_manager_terminal_here():
|
||||
applescript.run(
|
||||
r"""
|
||||
tell application "Finder"
|
||||
set myWin to window 1
|
||||
set thePath to (quoted form of POSIX path of (target of myWin as alias))
|
||||
tell application "Terminal"
|
||||
activate
|
||||
tell window 1
|
||||
do script "cd " & thePath
|
||||
end tell
|
||||
end tell
|
||||
end tell"""
|
||||
)
|
||||
|
||||
def file_manager_show_properties():
|
||||
"""Shows the properties for the file"""
|
||||
actions.key("cmd-i")
|
||||
|
||||
def file_manager_open_directory(path: str):
|
||||
"""opens the directory that's already visible in the view"""
|
||||
actions.key("cmd-shift-g")
|
||||
actions.sleep("50ms")
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_select_directory(path: str):
|
||||
"""selects the directory"""
|
||||
actions.insert(path)
|
||||
|
||||
def file_manager_new_folder(name: str):
|
||||
"""Creates a new folder in a gui filemanager or inserts the command to do so for terminals"""
|
||||
actions.key("cmd-shift-n")
|
||||
actions.insert(name)
|
||||
|
||||
def file_manager_open_file(path: str):
|
||||
"""opens the file"""
|
||||
actions.key("home")
|
||||
actions.insert(path)
|
||||
actions.key("cmd-o")
|
||||
|
||||
def file_manager_select_file(path: str):
|
||||
"""selects the file"""
|
||||
actions.key("home")
|
||||
actions.insert(path)
|
||||
|
||||
def address_focus():
|
||||
actions.key("cmd-shift-g")
|
||||
|
||||
def address_copy_address():
|
||||
actions.key("alt-cmd-c")
|
||||
|
||||
def address_navigate(address: str):
|
||||
actions.user.file_manager_open_directory(address)
|
||||
@@ -0,0 +1,29 @@
|
||||
os: mac
|
||||
app: finder
|
||||
-
|
||||
tag(): user.address
|
||||
tag(): user.file_manager
|
||||
tag(): user.navigation
|
||||
tag(): user.tabs
|
||||
preferences: key(cmd-,)
|
||||
options: key(cmd-j)
|
||||
search: key(cmd-alt-f)
|
||||
|
||||
# bit of a mouthful, but it's probably not the kind of thing you'd be saying frequently
|
||||
sort by none: key(ctrl-alt-cmd-0)
|
||||
sort by name: key(ctrl-alt-cmd-1)
|
||||
sort by kind: key(ctrl-alt-cmd-2)
|
||||
sort by date opened: key(ctrl-alt-cmd-3)
|
||||
sort by date added: key(ctrl-alt-cmd-4)
|
||||
sort by date modified: key(ctrl-alt-cmd-5)
|
||||
sort by size: key(ctrl-alt-cmd-6)
|
||||
|
||||
icon view: key(cmd-1)
|
||||
column view: key(cmd-3)
|
||||
list view: key(cmd-2)
|
||||
gallery view: key(cmd-4)
|
||||
|
||||
trash it: key(cmd-backspace)
|
||||
|
||||
hide [finder]: key(cmd-h)
|
||||
hide others: app.window_hide_others()
|
||||
@@ -0,0 +1,61 @@
|
||||
from talon import Context, Module, actions, app
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
apps = mod.apps
|
||||
apps.firefox = "app.name: Firefox"
|
||||
apps.firefox = "app.name: Firefox Developer Edition"
|
||||
apps.firefox = "app.name: firefox"
|
||||
apps.firefox = "app.name: org.mozilla.firefox"
|
||||
apps.firefox = "app.name: Firefox-esr"
|
||||
apps.firefox = "app.name: firefox-esr"
|
||||
apps.firefox = "app.name: LibreWolf"
|
||||
apps.firefox = "app.name: waterfox"
|
||||
apps.firefox = r"""
|
||||
os: windows
|
||||
and app.name: Firefox
|
||||
os: windows
|
||||
and app.exe: /^firefox\.exe$/i
|
||||
"""
|
||||
apps.firefox = """
|
||||
os: mac
|
||||
and app.bundle: org.mozilla.firefox
|
||||
"""
|
||||
|
||||
# Make the context match more specifically than anything else. This is important, eg. to
|
||||
# override the browser.go_home() implementation in tags/browser/browser_mac.py.
|
||||
ctx.matches = r"""
|
||||
os: windows
|
||||
os: linux
|
||||
os: mac
|
||||
tag: browser
|
||||
app: firefox
|
||||
"""
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def firefox_bookmarks_sidebar():
|
||||
"""Toggles the Firefox bookmark sidebar"""
|
||||
|
||||
def firefox_history_sidebar():
|
||||
"""Toggles the Firefox history sidebar"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def focus_page():
|
||||
actions.browser.focus_address()
|
||||
actions.edit.find()
|
||||
actions.sleep("180ms")
|
||||
actions.key("escape")
|
||||
|
||||
def go_home():
|
||||
actions.key("alt-home")
|
||||
@@ -0,0 +1,15 @@
|
||||
app: firefox
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
|
||||
tab search:
|
||||
browser.focus_address()
|
||||
insert("% ")
|
||||
tab search <user.text>$:
|
||||
browser.focus_address()
|
||||
insert("% {text}")
|
||||
key(down)
|
||||
|
||||
(sidebar | panel) bookmarks: user.firefox_bookmarks_sidebar()
|
||||
(sidebar | panel) history: user.firefox_history_sidebar()
|
||||
@@ -0,0 +1,33 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
|
||||
ctx.matches = r"""
|
||||
os: mac
|
||||
tag: browser
|
||||
app: firefox
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def firefox_bookmarks_sidebar():
|
||||
actions.key("cmd-b")
|
||||
|
||||
def firefox_history_sidebar():
|
||||
actions.key("cmd-shift-h")
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def bookmarks():
|
||||
actions.key("cmd-shift-o")
|
||||
|
||||
def open_private_window():
|
||||
actions.key("cmd-shift-p")
|
||||
|
||||
def show_downloads():
|
||||
actions.key("cmd-j")
|
||||
|
||||
def show_extensions():
|
||||
actions.key("cmd-shift-a")
|
||||
@@ -0,0 +1,44 @@
|
||||
from talon import Context, actions, app
|
||||
|
||||
ctx = Context()
|
||||
|
||||
ctx.matches = r"""
|
||||
os: windows
|
||||
os: linux
|
||||
tag: browser
|
||||
app: firefox
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def firefox_bookmarks_sidebar():
|
||||
actions.key("ctrl-b")
|
||||
|
||||
def firefox_history_sidebar():
|
||||
actions.key("ctrl-h")
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def focus_address():
|
||||
# Only using "ctrl-l" might fail and clear the console if the user
|
||||
# is focused in the devtools
|
||||
actions.key("f6")
|
||||
actions.sleep("100ms")
|
||||
actions.key("ctrl-l")
|
||||
|
||||
def open_private_window():
|
||||
actions.key("ctrl-shift-p")
|
||||
|
||||
def show_downloads():
|
||||
if app.platform == "linux":
|
||||
actions.key("ctrl-shift-y")
|
||||
else:
|
||||
actions.key("ctrl-j")
|
||||
|
||||
def show_extensions():
|
||||
actions.key("ctrl-shift-a")
|
||||
|
||||
def show_history():
|
||||
actions.key("ctrl-shift-h")
|
||||
@@ -0,0 +1,70 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
# --- App definition ---
|
||||
mod.apps.foxit_reader = r"""
|
||||
os: windows
|
||||
and app.name: /^Foxit Reader/
|
||||
os: windows
|
||||
and app.exe: /^foxitreader\.exe$/i
|
||||
os: windows
|
||||
and app.name: Foxit PDF Reader
|
||||
os: windows
|
||||
and app.exe: /^foxitpdfreader\.exe$/i
|
||||
"""
|
||||
# Context matching
|
||||
ctx.matches = """
|
||||
app: foxit_reader
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
# app.tabs
|
||||
def tab_open():
|
||||
actions.key("ctrl-o")
|
||||
|
||||
def tab_reopen():
|
||||
actions.app.notify("Foxit does not support this action.")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.tabs
|
||||
def tab_jump(number):
|
||||
actions.app.notify("Foxit does not support this action.")
|
||||
|
||||
def tab_final():
|
||||
actions.app.notify("Foxit does not support this action.")
|
||||
|
||||
def tab_duplicate():
|
||||
actions.app.notify("Foxit does not support this action.")
|
||||
|
||||
# user.pages
|
||||
def page_current() -> int:
|
||||
actions.key("ctrl-g")
|
||||
page = actions.edit.selected_text()
|
||||
return int(page)
|
||||
|
||||
def page_next():
|
||||
actions.key("right")
|
||||
|
||||
def page_previous():
|
||||
actions.key("left")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-g")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
|
||||
def page_final():
|
||||
# actions.key("fn-right")
|
||||
actions.key("end")
|
||||
|
||||
def page_rotate_right():
|
||||
actions.key("shift-ctrl-keypad_plus")
|
||||
|
||||
def page_rotate_left():
|
||||
actions.key("shift-ctrl-keypad_minus")
|
||||
@@ -0,0 +1,6 @@
|
||||
app: foxit_reader
|
||||
-
|
||||
tag(): user.tabs
|
||||
tag(): user.pages
|
||||
|
||||
tab close all: key(ctrl-shift-w)
|
||||
@@ -0,0 +1,117 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
mod.tag("gdb", "Tag to enabled gdb-related functionality")
|
||||
|
||||
# user.gdb-specific context
|
||||
ctx_gdb_enabled = Context()
|
||||
ctx_gdb_enabled.matches = r"""
|
||||
tag: user.gdb
|
||||
"""
|
||||
|
||||
# global context for enabling and disabling user.gdb tag
|
||||
ctx_global = Context()
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def gdb_enable():
|
||||
"""Enables the gdb tag"""
|
||||
ctx_global.tags = ["user.gdb"]
|
||||
|
||||
def gdb_disable():
|
||||
"""Disables the gdb tag"""
|
||||
ctx_global.tags = []
|
||||
|
||||
|
||||
@ctx_gdb_enabled.action_class("user")
|
||||
class UserActions:
|
||||
##
|
||||
# Generic debugger actions
|
||||
##
|
||||
|
||||
# Code execution
|
||||
def debugger_step_into():
|
||||
actions.auto_insert("stepi\n")
|
||||
|
||||
def debugger_step_over():
|
||||
actions.auto_insert("nexti\n")
|
||||
|
||||
def debugger_step_line():
|
||||
actions.auto_insert("step\n")
|
||||
|
||||
def debugger_step_over_line():
|
||||
actions.auto_insert("next\n")
|
||||
|
||||
def debugger_step_out():
|
||||
actions.auto_insert("finish\n")
|
||||
|
||||
def debugger_continue():
|
||||
actions.auto_insert("c\n")
|
||||
|
||||
def debugger_stop():
|
||||
actions.key("ctrl-c")
|
||||
|
||||
def debugger_start():
|
||||
actions.auto_insert("run\n")
|
||||
|
||||
def debugger_restart():
|
||||
actions.auto_insert("run\n")
|
||||
|
||||
# XXX -
|
||||
def debugger_detach():
|
||||
actions.auto_insert("")
|
||||
|
||||
# Registers
|
||||
def debugger_show_registers():
|
||||
actions.auto_insert("info registers\n")
|
||||
|
||||
def debugger_get_register():
|
||||
actions.auto_insert("r ")
|
||||
|
||||
def debugger_set_register():
|
||||
actions.user.insert_between("set $", "=")
|
||||
# Breakpoints
|
||||
|
||||
def debugger_show_breakpoints():
|
||||
actions.auto_insert("info breakpoints\n")
|
||||
|
||||
def debugger_add_sw_breakpoint():
|
||||
actions.auto_insert("break ")
|
||||
|
||||
# XXX -
|
||||
def debugger_add_hw_breakpoint():
|
||||
actions.auto_insert("")
|
||||
|
||||
def debugger_break_now():
|
||||
actions.key("ctrl-c")
|
||||
|
||||
def debugger_break_here():
|
||||
actions.auto_insert("break\n")
|
||||
|
||||
def debugger_clear_all_breakpoints():
|
||||
actions.auto_insert("d br\n")
|
||||
|
||||
def debugger_clear_breakpoint():
|
||||
actions.insert("d br ")
|
||||
|
||||
def debugger_enable_all_breakpoints():
|
||||
actions.insert("enable br\n")
|
||||
|
||||
def debugger_enable_breakpoint():
|
||||
actions.insert("enable br ")
|
||||
|
||||
def debugger_disable_all_breakpoints():
|
||||
actions.insert("disable br\n")
|
||||
|
||||
def debugger_disable_breakpoint():
|
||||
actions.insert("disable br ")
|
||||
|
||||
def debugger_clear_breakpoint_id(number_small: int):
|
||||
actions.insert(f"d br {number_small}\n")
|
||||
|
||||
def debugger_disable_breakpoint_id(number_small: int):
|
||||
actions.insert(f"disable br {number_small}\n")
|
||||
|
||||
def debugger_enable_breakpoint_id(number_small: int):
|
||||
actions.insert(f"enable br {number_small}\n")
|
||||
@@ -0,0 +1,102 @@
|
||||
os: linux
|
||||
# XXX - this matches .gdb files atm
|
||||
#win.title: /gdb/
|
||||
tag: terminal
|
||||
and tag: user.gdb
|
||||
-
|
||||
tag(): user.debugger
|
||||
until <number>: "until {number}"
|
||||
force clear all break points:
|
||||
insert("d br\n")
|
||||
insert("y\n")
|
||||
break [on] clipboard:
|
||||
insert("break ")
|
||||
key(ctrl-shift-v)
|
||||
key(enter)
|
||||
|
||||
# information
|
||||
list [source]: "list\n"
|
||||
info source: "info source\n"
|
||||
|
||||
print: "p "
|
||||
print [variable] <user.text>: "p {text}"
|
||||
print hex: "p/x "
|
||||
print hex [variable] <user.text>: "p/x {text}"
|
||||
print string: "p/s "
|
||||
|
||||
# hexdumping
|
||||
# XXX - switch the sizes to a list in python?
|
||||
# XXX - should cache the last used size
|
||||
hex dump <number> bytes: "x/{number}bx "
|
||||
hex dump <number> (half | short) words: "x/{number}hx "
|
||||
hex dump <number> (d | long) words: "x/{number}dx "
|
||||
hex dump <number> quad words: "x/{number}gx "
|
||||
# this is some arbitrary default for convenience
|
||||
hex dump: "x/100gx "
|
||||
hex dump highlighted:
|
||||
insert("x/100gx ")
|
||||
edit.copy()
|
||||
edit.paste()
|
||||
key(enter)
|
||||
hex dump clipboard:
|
||||
insert("x/100gx ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
|
||||
# execution
|
||||
source: "source \t\t"
|
||||
|
||||
# displays
|
||||
# XXX - move thee invoke command into a python script
|
||||
(list | show | info) display: "info display\n"
|
||||
display assembly line$: "display /i $pc\n"
|
||||
display source: "display "
|
||||
enable display <number_small>: "enable display {number_small}\n"
|
||||
disable display <number_small>: "disable display {number_small}\n"
|
||||
undisplay: "undisplay\n"
|
||||
|
||||
# variables
|
||||
(list | show | info) local: "info local "
|
||||
(list | show | info) local typed: "info local -t "
|
||||
(list | show | info) variable: "info variable "
|
||||
(list | show | info) variable typed: "info variable -t "
|
||||
(list | show | info) locals: "info local\n"
|
||||
(list | show | info) variables: "info variables\n"
|
||||
|
||||
# threads
|
||||
info threads: "info threads\n"
|
||||
|
||||
restart [program]: "r\n"
|
||||
continue: "c\n"
|
||||
back trace: "bt\n"
|
||||
debug quit: "quit\n"
|
||||
# more quickly quit when there are inferiors
|
||||
debug force quit: "quit\ny\n"
|
||||
(show | info) (inf | inferiors): "info inferiors\n"
|
||||
inferior <number_small>$: "inferior {number_small}\n"
|
||||
inferior: "inferior "
|
||||
resume main (inf | inferior):
|
||||
insert("inferior 1\n")
|
||||
insert("c\n")
|
||||
resume [from] (inf | inferior) <number_small>$:
|
||||
insert("inferior {number_small}\n")
|
||||
insert("c\n")
|
||||
|
||||
# arguments
|
||||
set args: "set args "
|
||||
|
||||
# settings
|
||||
show follow (fork | forks) [mode]: "show follow-fork-mode\n"
|
||||
[set] follow (fork | forks) [mode] child: "set follow-fork-mode child\n"
|
||||
[set] follow (fork | forks) [mode] parent: "set follow-fork-mode parent\n"
|
||||
|
||||
show detach on fork: "show detach-on-fork\n"
|
||||
set detach on fork: "set detach-on-fork on\n"
|
||||
unset detach on fork: "set detach-on-fork off\n"
|
||||
|
||||
# list
|
||||
show list size: "show listsize\n"
|
||||
set list size <number_small>: "set listsize {number_small}\n"
|
||||
|
||||
# misc
|
||||
clear screen: "shell clear\n"
|
||||
@@ -0,0 +1,2 @@
|
||||
[enable] debug mode: user.gdb_enable()
|
||||
disable debug mode: user.gdb_disable()
|
||||
@@ -0,0 +1,17 @@
|
||||
import csv
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from talon import Context, Module, actions, resource
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
mod.list("git_command", desc="Git commands.")
|
||||
mod.list("git_argument", desc="Command-line git options and arguments.")
|
||||
|
||||
|
||||
@mod.capture(rule="{user.git_argument}+")
|
||||
def git_arguments(m) -> str:
|
||||
"""A non-empty sequence of git command arguments, preceded by a space."""
|
||||
return " " + " ".join(m.git_argument_list)
|
||||
@@ -0,0 +1,51 @@
|
||||
tag: terminal
|
||||
and tag: user.git
|
||||
-
|
||||
git {user.git_command} [<user.git_arguments>]:
|
||||
args = git_arguments or ""
|
||||
"git {git_command}{args} "
|
||||
git commit [<user.git_arguments>] message [<user.prose>]:
|
||||
args = git_arguments or ""
|
||||
message = prose or ""
|
||||
user.insert_between('git commit{args} --message "{message}', '"')
|
||||
git stash [push] [<user.git_arguments>] message [<user.prose>]:
|
||||
args = git_arguments or ""
|
||||
message = prose or ""
|
||||
user.insert_between('git stash push{args} --message "{message}', '"')
|
||||
|
||||
# Optimistic execution for frequently used commands that are harmless (don't
|
||||
# change repository or index state).
|
||||
git status$: "git status\n"
|
||||
git add patch$: "git add --patch\n"
|
||||
git show head$: "git show HEAD\n"
|
||||
git diff$: "git diff\n"
|
||||
git diff (cached | cashed)$: "git diff --cached\n"
|
||||
|
||||
# Convenience
|
||||
git clone clipboard:
|
||||
insert("git clone ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
git diff highlighted:
|
||||
edit.copy()
|
||||
insert("git diff ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
git diff clipboard:
|
||||
insert("git diff ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
git add highlighted:
|
||||
edit.copy()
|
||||
insert("git add ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
git add clipboard:
|
||||
insert("git add ")
|
||||
edit.paste()
|
||||
key(enter)
|
||||
git commit highlighted:
|
||||
edit.copy()
|
||||
insert("git add ")
|
||||
edit.paste()
|
||||
insert("\ngit commit\n")
|
||||
@@ -0,0 +1,19 @@
|
||||
tag: terminal
|
||||
and tag: user.git
|
||||
title: /git add .*\-p/
|
||||
-
|
||||
yank:
|
||||
key(y)
|
||||
key(enter)
|
||||
near:
|
||||
key(n)
|
||||
key(enter)
|
||||
quench:
|
||||
key(q)
|
||||
key(enter)
|
||||
drum:
|
||||
key(d)
|
||||
key(enter)
|
||||
air:
|
||||
key(a)
|
||||
key(enter)
|
||||
@@ -0,0 +1,69 @@
|
||||
list: user.git_argument
|
||||
-
|
||||
abort: --abort
|
||||
all: --all
|
||||
allow empty: --allow-empty
|
||||
amend: --amend
|
||||
cached: --cached
|
||||
cashed: --cached
|
||||
color words: --color-words
|
||||
colour words: --color-words
|
||||
continue: --continue
|
||||
copy: --copy
|
||||
create: --create
|
||||
delete: --delete
|
||||
detach: --detach
|
||||
dir diff: --dir-diff
|
||||
directory diff: --dir-diff
|
||||
dry run: --dry-run
|
||||
edit: --edit
|
||||
fast forward only: --ff-only
|
||||
force: --force
|
||||
force create: --force-create
|
||||
force with lease: --force-with-lease
|
||||
global: --global
|
||||
global: --global
|
||||
hard: --hard
|
||||
ignore case: --ignore-case
|
||||
include untracked: --include-untracked
|
||||
interactive: --interactive
|
||||
keep index: --keep-index
|
||||
list: --list
|
||||
local: --local
|
||||
mixed: --mixed
|
||||
move: --move
|
||||
no edit: --no-edit
|
||||
no keep index: --no-keep-index
|
||||
no rebase: --no-rebase
|
||||
no track: --no-track
|
||||
no verify: --no-verify
|
||||
orphan: --orphan
|
||||
patch: --patch
|
||||
prune: --prune
|
||||
quiet: --quiet
|
||||
quit: --quit
|
||||
rebase: --rebase
|
||||
remote: --remote
|
||||
set up stream: --set-upstream
|
||||
set up stream to: --set-upstream-to
|
||||
short: --short
|
||||
short stat: --shortstat
|
||||
skip: --skip
|
||||
soft: --soft
|
||||
staged: --staged
|
||||
stat: --stat
|
||||
system: --system
|
||||
track: --track
|
||||
update: --update
|
||||
verbose: --verbose
|
||||
branch: -b
|
||||
combined: -c
|
||||
deep: -d
|
||||
very verbose: -vv
|
||||
HEAD
|
||||
main
|
||||
master
|
||||
origin
|
||||
upstream
|
||||
origin main: origin/main
|
||||
origin master: origin/master
|
||||
@@ -0,0 +1,71 @@
|
||||
list: user.git_command
|
||||
-
|
||||
add
|
||||
archive
|
||||
bisect
|
||||
blame
|
||||
branch
|
||||
checkout
|
||||
cherry pick: cherry-pick
|
||||
clean
|
||||
clone
|
||||
commit
|
||||
config
|
||||
diff
|
||||
diff tool: difftool
|
||||
fetch
|
||||
gc
|
||||
grep
|
||||
help
|
||||
in it: init
|
||||
log
|
||||
ls files: ls-files
|
||||
merge
|
||||
merge tool: mergetool
|
||||
move: mv
|
||||
pull
|
||||
push
|
||||
range diff: range-diff
|
||||
rebase
|
||||
ref log: reflog
|
||||
remote
|
||||
remote add
|
||||
remote remove
|
||||
remote rename
|
||||
remote set url: remote set-url
|
||||
remote set you are el: remote set-url
|
||||
remote show
|
||||
rerere
|
||||
rerere diff
|
||||
rerere status
|
||||
reset
|
||||
restore
|
||||
revert
|
||||
remove: rm
|
||||
short log: shortlog
|
||||
show
|
||||
sparse checkout: sparse-checkout
|
||||
stash
|
||||
stash apply
|
||||
stash list
|
||||
stash pop
|
||||
stash push
|
||||
stash show
|
||||
stash save
|
||||
status
|
||||
submodule
|
||||
submodule add
|
||||
submodule in it: submodule init
|
||||
submodule status
|
||||
submodule update
|
||||
switch
|
||||
tag
|
||||
worktree
|
||||
worktree add
|
||||
worktree list
|
||||
worktree lock
|
||||
worktree move
|
||||
worktree prune
|
||||
worktree remove
|
||||
worktree repair
|
||||
worktree unlock
|
||||
@@ -0,0 +1,70 @@
|
||||
# https://help.github.com/en/github/getting-started-with-github/keyboard-shortcuts
|
||||
tag: browser
|
||||
browser.host: github.com
|
||||
-
|
||||
|
||||
# site wide shortcuts
|
||||
focus search: key(s)
|
||||
go to notifications: insert("gn")
|
||||
go to dashboard: insert("gd")
|
||||
(keyboard shortcuts show | show keyboard shortcuts): key(?)
|
||||
(selection move down | move selection down): key(j)
|
||||
(selection move up | move selection up): key(k)
|
||||
(selection toggle | toggle selection): key(x)
|
||||
(selection open | open selection): key(o)
|
||||
|
||||
# repositories
|
||||
go to code: insert("gc")
|
||||
go to issues: insert("gi")
|
||||
go to pull requests: insert("gp")
|
||||
go to wiki: insert("gw")
|
||||
go to actions: insert("ga")
|
||||
go to projects: insert("gb")
|
||||
go to discussions: insert("gg")
|
||||
|
||||
# source code editing
|
||||
[web] editor open: key(.)
|
||||
|
||||
# source code browsing
|
||||
(file find | find file): key(t)
|
||||
jump to line: key(l)
|
||||
((branch | tag) switch | switch (branch | tag)): key(w)
|
||||
(url expand | expand url): key(y)
|
||||
(show | hide) comments: key(i)
|
||||
blame view open: key(b)
|
||||
(show | hide) annotations: key(a)
|
||||
|
||||
# issues
|
||||
(issue create | create [an] issue): key(c)
|
||||
search (issues | [pull] requests): key(/)
|
||||
(filter by | edit) labels: key(l)
|
||||
(filter by | edit) milestones: key(m)
|
||||
(filter by | edit) assignee: key(a)
|
||||
reply: key(r)
|
||||
(comment submit | submit comment): key(ctrl-enter)
|
||||
(comment preview | preview comment): key(ctrl-shift-p)
|
||||
git hub full screen: key(ctrl-shift-l)
|
||||
|
||||
# browsing commit
|
||||
(form close | close form): key(escape)
|
||||
parent commit: key(p)
|
||||
other parent commit: key(o)
|
||||
|
||||
# notifications
|
||||
mark as read: key(y)
|
||||
(thread mute | mute thread): key(shift-m)
|
||||
|
||||
# issue or pull request list
|
||||
(issue open | open issue): key(o)
|
||||
(issue create | create issue): key(c)
|
||||
|
||||
# issues and pull requests
|
||||
reviewer request: key(q)
|
||||
milestone set: key(m)
|
||||
assignee set: key(a)
|
||||
label set: key(l)
|
||||
|
||||
# actions
|
||||
go to workflow: insert("gf")
|
||||
timestamps toggle: key(shift-t)
|
||||
fullscreen toggle: key(shift-f)
|
||||
@@ -0,0 +1,60 @@
|
||||
# Shortcuts taken from: https://docs.gitlab.com/ee/user/shortcuts.html
|
||||
#
|
||||
tag: browser
|
||||
browser.host: /gitlab\.com/
|
||||
#win.title: /GitLab/
|
||||
-
|
||||
|
||||
# global shortcuts
|
||||
show shortcuts: key(?)
|
||||
go to projects [page]: key(shift-p)
|
||||
go to groups [page]: key(shift-g)
|
||||
go to activity [page]: key(shift-a)
|
||||
go to milestones [page]: key(shift-l)
|
||||
go to snippets [page]: key(shift-s)
|
||||
search page: key(s)
|
||||
go to issues [page]: key(shift-i)
|
||||
go to merge requests [page]: key(shift-m)
|
||||
go to to do [list] [page]: key(shift-t)
|
||||
(show | hide) performance bar: key(p)
|
||||
|
||||
edit last comment: key(1)
|
||||
toggle mark down [preview]: key(ctrl-shift-p)
|
||||
|
||||
# projects
|
||||
go [to] project home [page]: insert("gp")
|
||||
go [to] project activity [feed]: insert("gv")
|
||||
go [to] project releases [list]: insert("gr")
|
||||
go [to] project files [list]: insert("gf")
|
||||
go [to] project file search [page]: key(t)
|
||||
go [to] project (commit | commits) [list]: insert("gc")
|
||||
go [to] (repository | repo) graph [page]: insert("gn")
|
||||
go [to] (repository | repo) charts: insert("gd")
|
||||
go [to] project issues [list]: insert("gi")
|
||||
go [to] new issues [list]: insert("i")
|
||||
go [to] project issues boards [list]: insert("gb")
|
||||
go [to] project merge requests [list]: insert("gm")
|
||||
go [to] jobs [list]: insert("gj")
|
||||
go [to] project metrics: insert("gl")
|
||||
go [to] project environments: insert("ge")
|
||||
go [to] project cubes: insert("gk")
|
||||
go [to] project snippets [list]: insert("gs")
|
||||
go [to] project wiki: insert("gw")
|
||||
|
||||
# issues and merge requests
|
||||
edit description: key(e)
|
||||
change assignee: key(a)
|
||||
change milestone: key(m)
|
||||
change label: key(l)
|
||||
right comment: key(r)
|
||||
next [unresolved] discussion: key(n)
|
||||
previous [unresolved] discussion: key(p)
|
||||
next file: key(])
|
||||
previous file: key([)
|
||||
|
||||
# project files
|
||||
back to files: key(escape)
|
||||
open permalink: key(y)
|
||||
|
||||
# wiki pages
|
||||
edit page: key(e)
|
||||
@@ -0,0 +1,93 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# App definition
|
||||
mod = Module()
|
||||
mod.apps.gnome_terminal = """
|
||||
os: linux
|
||||
and app.exe: gnome-terminal-server
|
||||
os: linux
|
||||
and app.name: Gnome-terminal
|
||||
os: linux
|
||||
and app.name: Mate-terminal
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: gnome_terminal
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class user_actions:
|
||||
# user.tabs
|
||||
def tab_jump(number):
|
||||
actions.key(f"alt-{number}")
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class app_actions:
|
||||
# app.tabs
|
||||
def tab_open():
|
||||
actions.key("ctrl-shift-t")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def tab_close():
|
||||
actions.key("ctrl-shift-w")
|
||||
|
||||
# global (overwrite linux/app.py)
|
||||
def window_open():
|
||||
actions.key("ctrl-shift-n")
|
||||
|
||||
def window_close():
|
||||
actions.key("ctrl-shift-q")
|
||||
|
||||
|
||||
# global (overwrite linux/edit.py)
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def page_down():
|
||||
actions.key("shift-pagedown")
|
||||
|
||||
def page_up():
|
||||
actions.key("shift-pageup")
|
||||
|
||||
def paste():
|
||||
actions.key("ctrl-shift-v")
|
||||
|
||||
def copy():
|
||||
actions.key("ctrl-shift-c")
|
||||
|
||||
def find(text: str = None):
|
||||
actions.key("ctrl-shift-f")
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def delete_line():
|
||||
actions.edit.line_start()
|
||||
actions.key("ctrl-k")
|
||||
|
||||
# afaik not possible in gnome-terminal
|
||||
def extend_left():
|
||||
pass
|
||||
|
||||
def extend_right():
|
||||
pass
|
||||
|
||||
def extend_up():
|
||||
pass
|
||||
|
||||
def extend_down():
|
||||
pass
|
||||
|
||||
def extend_word_left():
|
||||
pass
|
||||
|
||||
def extend_word_right():
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
app: gnome_terminal
|
||||
-
|
||||
# Set tags
|
||||
tag(): terminal
|
||||
tag(): user.tabs
|
||||
tag(): user.generic_unix_shell
|
||||
tag(): user.git
|
||||
tag(): user.kubectl
|
||||
@@ -0,0 +1,23 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
os: linux
|
||||
app: Guake
|
||||
"""
|
||||
ctx.tags = ["user.git", "user.kubectl", "user.tabs", "terminal"]
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def tab_open():
|
||||
actions.key("ctrl-shift-t")
|
||||
|
||||
def tab_close():
|
||||
actions.key("ctrl-shift-w")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
@@ -0,0 +1,118 @@
|
||||
import subprocess
|
||||
from typing import Optional, Union
|
||||
|
||||
from talon import Context, Module, actions, settings
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
mod.tag("i3wm", desc="tag for loading i3wm related files")
|
||||
mod.setting(
|
||||
"i3_config_path",
|
||||
type=str,
|
||||
default="~/.i3/config",
|
||||
desc="Where to find the configuration path",
|
||||
)
|
||||
mod.setting(
|
||||
"i3_mod_key",
|
||||
type=str,
|
||||
default="super",
|
||||
desc="The default key to use for i3wm commands",
|
||||
)
|
||||
|
||||
ctx.matches = """
|
||||
tag: user.i3wm
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def window_close():
|
||||
subprocess.check_call(("i3-msg", "kill"))
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def i3wm_mode(name: str):
|
||||
"""Switch i3 mode"""
|
||||
subprocess.check_call(("i3-msg", "mode", name))
|
||||
|
||||
def i3wm_reload():
|
||||
"""Reload the i3 config"""
|
||||
subprocess.check_call(("i3-msg", "reload"))
|
||||
|
||||
def i3wm_restart():
|
||||
"""Restart the window manager"""
|
||||
subprocess.check_call(("i3-msg", "restart"))
|
||||
|
||||
def i3wm_layout(layout: Optional[str] = None):
|
||||
"""Change to specified layout. Toggle split if unspecified."""
|
||||
if layout is None:
|
||||
subprocess.check_call(("i3-msg", "layout", "toggle", "split"))
|
||||
else:
|
||||
subprocess.check_call(("i3-msg", "layout", layout))
|
||||
|
||||
def i3wm_fullscreen():
|
||||
"""Fullscreen the current container"""
|
||||
subprocess.check_call(("i3-msg", "fullscreen"))
|
||||
|
||||
def i3wm_split(direction: str):
|
||||
"""Split the focused container"""
|
||||
subprocess.check_call(("i3-msg", "split", direction))
|
||||
|
||||
def i3wm_float():
|
||||
"""Toggle whether the focused container should float."""
|
||||
subprocess.check_call(("i3-msg", "floating", "toggle"))
|
||||
|
||||
def i3wm_launch():
|
||||
"""Trigger the i3 launcher: ex rofi"""
|
||||
key = settings.get("user.i3_mod_key")
|
||||
actions.key(f"{key}-d")
|
||||
|
||||
def i3wm_shell():
|
||||
"""Launch a shell"""
|
||||
key = settings.get("user.i3_mod_key")
|
||||
actions.key(f"{key}-enter")
|
||||
|
||||
def i3wm_focus(what: str):
|
||||
"""Move focus"""
|
||||
subprocess.check_call(("i3-msg", "focus", what))
|
||||
|
||||
def i3wm_switch_to_workspace(which: Union[str, int]):
|
||||
"""Focus the specified workspace"""
|
||||
if isinstance(which, int):
|
||||
subprocess.check_call(("i3-msg", "workspace", "number", str(which)))
|
||||
else:
|
||||
subprocess.check_call(("i3-msg", "workspace", which))
|
||||
|
||||
def i3wm_show_scratchpad():
|
||||
"""Focus/cycle/hide the scratchpad"""
|
||||
subprocess.check_call(("i3-msg", "scratchpad", "show"))
|
||||
|
||||
def i3wm_move(to: str):
|
||||
"""Move the focused container"""
|
||||
subprocess.check_call(("i3-msg", "move", to))
|
||||
|
||||
def i3wm_move_to_workspace(which: Union[str, int]):
|
||||
"""Move the focused container to the specified workspace"""
|
||||
if isinstance(which, int):
|
||||
subprocess.check_call(
|
||||
("i3-msg", "move", "container", "to", "workspace", "number", str(which))
|
||||
)
|
||||
else:
|
||||
subprocess.check_call(
|
||||
("i3-msg", "move", "container", "to", "workspace", which)
|
||||
)
|
||||
|
||||
def i3wm_move_to_output(which: str):
|
||||
"""Move the focused container to the specified output."""
|
||||
subprocess.check_call(("i3-msg", "move", "container", "to", "output", which))
|
||||
|
||||
def i3wm_move_position(where: str):
|
||||
"""Move the focused container to the specified position."""
|
||||
subprocess.check_call(("i3-msg", "move", "position", where))
|
||||
|
||||
def i3wm_lock():
|
||||
"""Trigger the lock screen"""
|
||||
key = settings.get("user.i3_mod_key")
|
||||
actions.key(f"{key}-shift-x")
|
||||
@@ -0,0 +1,99 @@
|
||||
# NOTE: If you want to use i3wm you must enable the tag settings.talon. i.e.: `tag(): user.i3wm`
|
||||
os: linux
|
||||
tag: user.i3wm
|
||||
-
|
||||
port <number_small>: user.i3wm_switch_to_workspace(number_small)
|
||||
(port flip | flipper): user.i3wm_switch_to_workspace("back_and_forth")
|
||||
port right: user.i3wm_switch_to_workspace("next")
|
||||
port left: user.i3wm_switch_to_workspace("prev")
|
||||
|
||||
(win | window) left: user.i3wm_focus("left")
|
||||
(win | window) right: user.i3wm_focus("right")
|
||||
(win | window) up: user.i3wm_focus("up")
|
||||
(win | window) down: user.i3wm_focus("down")
|
||||
(win | window) kill: app.window_close()
|
||||
(win | window) stacking: user.i3wm_layout("stacking")
|
||||
(win | window) default: user.i3wm_layout()
|
||||
(win | window) tabbed: user.i3wm_layout("tabbed")
|
||||
|
||||
reload i three config: user.i3wm_reload()
|
||||
restart i three: user.i3wm_restart()
|
||||
|
||||
(full screen | scuba): user.i3wm_fullscreen()
|
||||
toggle floating: user.i3wm_float()
|
||||
focus floating: user.i3wm_focus("mode_toggle")
|
||||
center window: user.i3wm_move_position("center")
|
||||
resize mode: user.i3wm_mode("resize")
|
||||
focus parent: user.i3wm_focus("parent")
|
||||
focus child: user.i3wm_focus("child")
|
||||
|
||||
# resize helpers
|
||||
grow window:
|
||||
user.i3wm_mode("resize")
|
||||
key(right:10)
|
||||
key(down:10)
|
||||
# escape resize mode
|
||||
key(escape)
|
||||
# center window
|
||||
sleep(200ms)
|
||||
user.i3wm_move_position("center")
|
||||
|
||||
# resize helpers
|
||||
shrink window:
|
||||
user.i3wm_mode("resize")
|
||||
key(left:10)
|
||||
key(up:10)
|
||||
# escape resize mode
|
||||
key(escape)
|
||||
# center window
|
||||
sleep(200ms)
|
||||
user.i3wm_move_position("center")
|
||||
|
||||
horizontal (shell | terminal):
|
||||
user.i3wm_split("h")
|
||||
user.i3wm_shell()
|
||||
|
||||
vertical (shell | terminal):
|
||||
user.i3wm_split("v")
|
||||
user.i3wm_shell()
|
||||
|
||||
# XXX - just replace with shuffle eventually?
|
||||
# XXX - like also need to match the generic talon commands
|
||||
(shuffle | move (win | window) [to] port) <number_small>:
|
||||
user.i3wm_move_to_workspace(number_small)
|
||||
(shuffle | move (win | window) [to] last port):
|
||||
user.i3wm_move_to_workspace("back_and_forth")
|
||||
(shuffle | move) flipper: user.i3wm_move_to_workspace("back_and_forth")
|
||||
(shuffle | move (win | window) left): user.i3wm_move("left")
|
||||
(shuffle | move (win | window) right): user.i3wm_move("right")
|
||||
(shuffle | move (win | window) up): user.i3wm_move("up")
|
||||
(shuffle | move (win | window) down): user.i3wm_move("down")
|
||||
|
||||
(win | window) horizontal: user.i3wm_split("h")
|
||||
(win | window) vertical: user.i3wm_split("v")
|
||||
|
||||
make scratch: user.i3wm_move("scratchpad")
|
||||
[(show | hide)] scratch: user.i3wm_show_scratchpad()
|
||||
next scratch:
|
||||
user.i3wm_show_scratchpad()
|
||||
user.i3wm_show_scratchpad()
|
||||
|
||||
# these rely on the user settings for the mod key. see i3wm.py Actions class
|
||||
launch: user.i3wm_launch()
|
||||
launch <user.text>:
|
||||
user.i3wm_launch()
|
||||
sleep(100ms)
|
||||
insert("{text}")
|
||||
lock screen: user.i3wm_lock()
|
||||
|
||||
(launch shell | koopa): user.i3wm_shell()
|
||||
|
||||
new scratch (shell | window):
|
||||
user.i3wm_shell()
|
||||
sleep(200ms)
|
||||
user.i3wm_move("scratchpad")
|
||||
user.i3wm_show_scratchpad()
|
||||
|
||||
murder:
|
||||
user.deprecate_command("2023-02-04", "murder", "win kill")
|
||||
app.window_close()
|
||||
@@ -0,0 +1,28 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.iterm2 = """
|
||||
os: mac
|
||||
and app.bundle: com.googlecode.iterm2
|
||||
"""
|
||||
ctx.matches = r"""
|
||||
app: iterm2
|
||||
"""
|
||||
|
||||
directories_to_remap = {}
|
||||
directories_to_exclude = {}
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_jump(number: int):
|
||||
actions.key(f"cmd-{number}")
|
||||
|
||||
def tab_final():
|
||||
actions.key("cmd-9")
|
||||
|
||||
def terminal_clear_screen():
|
||||
"""Clear screen"""
|
||||
actions.key("ctrl-l")
|
||||
@@ -0,0 +1,11 @@
|
||||
os: mac
|
||||
app: iterm2
|
||||
-
|
||||
tag(): terminal
|
||||
# todo: filemanager support
|
||||
#tag(): user.file_manager
|
||||
tag(): user.generic_unix_shell
|
||||
tag(): user.git
|
||||
tag(): user.kubectl
|
||||
tag(): user.tabs
|
||||
tag(): user.readline
|
||||
@@ -0,0 +1,405 @@
|
||||
import os
|
||||
import os.path
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
from talon import Context, Module, actions, app, clip, ui
|
||||
|
||||
# Courtesy of https://github.com/anonfunc/talon-user/blob/master/apps/jetbrains.py
|
||||
|
||||
# Each IDE gets its own port, as otherwise you wouldn't be able
|
||||
# to run two at the same time and switch between them.
|
||||
# Note that MPS and IntelliJ ultimate will conflict...
|
||||
port_mapping = {
|
||||
"com.google.android.studio": 8652,
|
||||
"com.jetbrains.AppCode": 8655,
|
||||
"com.jetbrains.CLion": 8657,
|
||||
"com.jetbrains.datagrip": 8664,
|
||||
"com.jetbrains.goland-EAP": 8659,
|
||||
"com.jetbrains.goland": 8659,
|
||||
"com.jetbrains.intellij-EAP": 8653,
|
||||
"com.jetbrains.intellij.ce": 8654,
|
||||
"com.jetbrains.intellij": 8653,
|
||||
"com.jetbrains.PhpStorm": 8662,
|
||||
"com.jetbrains.pycharm": 8658,
|
||||
"com.jetbrains.rider": 8660,
|
||||
"com.jetbrains.rubymine": 8661,
|
||||
"com.jetbrains.rubymine-EAP": 8661,
|
||||
"com.jetbrains.WebStorm": 8663,
|
||||
"google-android-studio": 8652,
|
||||
"idea64.exe": 8653,
|
||||
"IntelliJ IDEA": 8653,
|
||||
"IntelliJ IDEA Community Edition": 8654,
|
||||
"jetbrains-appcode": 8655,
|
||||
"jetbrains-clion": 8657,
|
||||
"jetbrains-datagrip": 8664,
|
||||
"jetbrains-goland-eap": 8659,
|
||||
"jetbrains-goland": 8659,
|
||||
"jetbrains-idea-ce": 8654,
|
||||
"jetbrains-idea-eap": 8653,
|
||||
"jetbrains-idea": 8653,
|
||||
"jetbrains-phpstorm": 8662,
|
||||
"jetbrains-pycharm-ce": 8658,
|
||||
"jetbrains-pycharm": 8658,
|
||||
"jetbrains-rider": 8660,
|
||||
"JetBrains Rider": 8660,
|
||||
"jetbrains-rubymine": 8661,
|
||||
"jetbrains-rubymine-eap": 8661,
|
||||
"jetbrains-studio": 8652,
|
||||
"jetbrains-webstorm": 8663,
|
||||
"RubyMine": 8661,
|
||||
"RubyMine-EAP": 8661,
|
||||
"PyCharm": 8658,
|
||||
"pycharm64.exe": 8658,
|
||||
"WebStorm": 8663,
|
||||
"webstorm64.exe": 8663,
|
||||
"PhpStorm": 8662,
|
||||
# Local plugin development:
|
||||
"com.jetbrains.jbr.java": 8666,
|
||||
}
|
||||
|
||||
|
||||
def _get_nonce(port: int, file_prefix: str) -> Optional[str]:
|
||||
file_name = file_prefix + str(port)
|
||||
try:
|
||||
with open(os.path.join(tempfile.gettempdir(), file_name)) as fh:
|
||||
return fh.read()
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
with open(Path.home() / file_name) as fh:
|
||||
return fh.read()
|
||||
except FileNotFoundError:
|
||||
print(f"Could not find {file_name} in tmp or home")
|
||||
return None
|
||||
except OSError as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
|
||||
def send_idea_command(cmd: str) -> str:
|
||||
active_app = ui.active_app()
|
||||
bundle = active_app.bundle or active_app.name
|
||||
port = port_mapping.get(bundle, None)
|
||||
if not port:
|
||||
raise Exception(f"unknown application {bundle}")
|
||||
nonce = _get_nonce(port, ".vcidea_") or _get_nonce(port, "vcidea_")
|
||||
if not nonce:
|
||||
raise FileNotFoundError(f"Couldn't find IDEA nonce file for port {port}")
|
||||
|
||||
response = requests.get(
|
||||
f"http://localhost:{port}/{nonce}/{cmd}",
|
||||
proxies={"http": None, "https": None},
|
||||
timeout=(0.05, 3.05),
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.text
|
||||
|
||||
|
||||
def get_idea_location() -> list[str]:
|
||||
return send_idea_command("location").split()
|
||||
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.jetbrains = "app.name: /jetbrains/"
|
||||
appNames = [
|
||||
"CLion",
|
||||
"IntelliJ IDEA",
|
||||
"PhpStorm",
|
||||
"PyCharm",
|
||||
"Webstorm",
|
||||
"RubyMine",
|
||||
"DataGrip",
|
||||
]
|
||||
for appName in appNames:
|
||||
mod.apps.jetbrains = f"app.name: {appName}"
|
||||
mod.apps.jetbrains = f"app.name: {appName}-EAP"
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.google.android.studio
|
||||
"""
|
||||
# windows
|
||||
mod.apps.jetbrains = r"app.exe: /^idea64\.exe$/i"
|
||||
mod.apps.jetbrains = r"app.exe: /^PyCharm64\.exe$/i"
|
||||
mod.apps.jetbrains = r"app.exe: /^webstorm64\.exe$/i"
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.jetbrains.pycharm
|
||||
"""
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.jetbrains.rider
|
||||
"""
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.jetbrains.goland
|
||||
"""
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.jetbrains.intellij.ce
|
||||
"""
|
||||
mod.apps.jetbrains = r"""
|
||||
os: windows
|
||||
and app.name: JetBrains Rider
|
||||
os: windows
|
||||
and app.exe: /^rider64\.exe$/i
|
||||
"""
|
||||
|
||||
# Local plugin development:
|
||||
mod.apps.jetbrains = """
|
||||
os: mac
|
||||
and app.bundle: com.jetbrains.jbr.java
|
||||
"""
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
|
||||
def idea(commands: str):
|
||||
"""Send a command to Jetbrains product"""
|
||||
command_list = commands.split(",")
|
||||
try:
|
||||
for cmd in command_list:
|
||||
if cmd:
|
||||
send_idea_command(cmd.strip())
|
||||
actions.sleep(0.1)
|
||||
except Exception as e:
|
||||
app.notify(str(e))
|
||||
raise
|
||||
|
||||
def idea_grab(times: int):
|
||||
"""Copies specified number of words to the left"""
|
||||
old_clip = clip.get()
|
||||
try:
|
||||
original_line, original_column = get_idea_location()
|
||||
for _ in range(times):
|
||||
send_idea_command("action EditorSelectWord")
|
||||
send_idea_command("action EditorCopy")
|
||||
send_idea_command(f"goto {original_line} {original_column}")
|
||||
send_idea_command("action EditorPaste")
|
||||
finally:
|
||||
clip.set(old_clip)
|
||||
|
||||
|
||||
ctx.matches = r"""
|
||||
app: jetbrains
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def tab_next():
|
||||
actions.user.idea("action NextTab")
|
||||
|
||||
def tab_previous():
|
||||
actions.user.idea("action PreviousTab")
|
||||
|
||||
def tab_close():
|
||||
actions.user.idea("action CloseContent")
|
||||
|
||||
def tab_reopen():
|
||||
actions.user.idea("action ReopenClosedTab")
|
||||
|
||||
|
||||
@ctx.action_class("code")
|
||||
class CodeActions:
|
||||
# talon code actions
|
||||
def toggle_comment():
|
||||
actions.user.idea("action CommentByLineComment")
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
# talon edit actions
|
||||
def copy():
|
||||
actions.user.idea("action EditorCopy")
|
||||
|
||||
def cut():
|
||||
actions.user.idea("action EditorCut")
|
||||
|
||||
def delete():
|
||||
actions.user.idea("action EditorBackSpace")
|
||||
|
||||
def paste():
|
||||
actions.user.idea("action EditorPaste")
|
||||
|
||||
def find_next():
|
||||
actions.user.idea("action FindNext")
|
||||
|
||||
def find_previous():
|
||||
actions.user.idea("action FindPrevious")
|
||||
|
||||
def find(text: str = None):
|
||||
actions.user.idea("action Find")
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def line_clone():
|
||||
actions.user.idea("action EditorDuplicate")
|
||||
|
||||
def line_swap_down():
|
||||
actions.user.idea("action MoveLineDown")
|
||||
|
||||
def line_swap_up():
|
||||
actions.user.idea("action MoveLineUp")
|
||||
|
||||
def indent_more():
|
||||
actions.user.idea("action EditorIndentLineOrSelection")
|
||||
|
||||
def indent_less():
|
||||
actions.user.idea("action EditorUnindentSelection")
|
||||
|
||||
def select_line(n: int = None):
|
||||
actions.user.idea("action EditorSelectLine")
|
||||
|
||||
def select_word():
|
||||
actions.user.idea("action EditorSelectWord")
|
||||
|
||||
def select_all():
|
||||
actions.user.idea("action $SelectAll")
|
||||
|
||||
def file_start():
|
||||
actions.user.idea("action EditorTextStart")
|
||||
|
||||
def file_end():
|
||||
actions.user.idea("action EditorTextEnd")
|
||||
|
||||
def extend_file_start():
|
||||
actions.user.idea("action EditorTextStartWithSelection")
|
||||
|
||||
def extend_file_end():
|
||||
actions.user.idea("action EditorTextEndWithSelection")
|
||||
|
||||
def extend_word_left():
|
||||
actions.user.idea("action EditorPreviousWordWithSelection")
|
||||
|
||||
def extend_word_right():
|
||||
actions.user.idea("action EditorNextWordWithSelection")
|
||||
|
||||
def jump_line(n: int):
|
||||
actions.user.idea(f"goto {n} 0")
|
||||
# move the cursor to the first nonwhite space character of the line
|
||||
actions.user.idea("action EditorLineEnd")
|
||||
actions.user.idea("action EditorLineStart")
|
||||
|
||||
|
||||
@ctx.action_class("win")
|
||||
class WinActions:
|
||||
def filename() -> str:
|
||||
title: str = actions.win.title()
|
||||
result = title.split()
|
||||
|
||||
# iterate over reversed result
|
||||
# to support titles such as
|
||||
# Class.Library2 – a.js [.workspace]
|
||||
for word in reversed(result):
|
||||
if not word.startswith("[") and "." in word:
|
||||
return word
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
|
||||
def command_server_directory() -> str:
|
||||
return "jetbrains-command-server"
|
||||
|
||||
def tab_jump(number: int):
|
||||
# depends on plugin GoToTabs
|
||||
if number < 10:
|
||||
actions.user.idea(f"action GoToTab{number}")
|
||||
|
||||
def extend_until_line(line: int):
|
||||
actions.user.idea(f"extend {line}")
|
||||
|
||||
def select_range(line_start: int, line_end: int):
|
||||
# if it's a single line, select the entire thing including the ending new-line5
|
||||
if line_start == line_end:
|
||||
actions.user.idea(f"goto {line_start} 0")
|
||||
actions.user.idea("action EditorSelectLine")
|
||||
else:
|
||||
actions.user.idea(f"range {line_start} {line_end}")
|
||||
|
||||
def extend_camel_left():
|
||||
actions.user.idea("action EditorPreviousWordInDifferentHumpsModeWithSelection")
|
||||
|
||||
def extend_camel_right():
|
||||
actions.user.idea("action EditorNextWordInDifferentHumpsModeWithSelection")
|
||||
|
||||
def camel_left():
|
||||
actions.user.idea("action EditorPreviousWordInDifferentHumpsMode")
|
||||
|
||||
def camel_right():
|
||||
actions.user.idea("action EditorNextWordInDifferentHumpsMode")
|
||||
|
||||
def command_search(command: str = ""):
|
||||
actions.user.idea("action GotoAction")
|
||||
if command != "":
|
||||
actions.insert(command)
|
||||
|
||||
def line_clone(line: int):
|
||||
actions.user.idea(f"clone {line}")
|
||||
|
||||
# multi-cursor tag functions
|
||||
def multi_cursor_enable():
|
||||
actions.skip()
|
||||
|
||||
def multi_cursor_disable():
|
||||
actions.key("escape")
|
||||
|
||||
def multi_cursor_add_above():
|
||||
actions.user.idea("action EditorCloneCaretAbove")
|
||||
|
||||
def multi_cursor_add_below():
|
||||
actions.user.idea("action EditorCloneCaretBelow")
|
||||
|
||||
def multi_cursor_select_fewer_occurrences():
|
||||
actions.user.idea("action UnselectPreviousOccurrence")
|
||||
|
||||
def multi_cursor_select_more_occurrences():
|
||||
actions.user.idea("action SelectNextOccurrence")
|
||||
|
||||
# def multi_cursor_skip_occurrence():
|
||||
def multi_cursor_select_all_occurrences():
|
||||
actions.user.idea("action SelectAllOccurrences")
|
||||
|
||||
def multi_cursor_add_to_line_ends():
|
||||
actions.user.idea("action EditorAddCaretPerSelectedLine")
|
||||
|
||||
# splits tag functions
|
||||
# def split_window_right():
|
||||
# actions.user.idea("action OpenInRightSplit")
|
||||
# def split_window_left():
|
||||
# def split_window_down():
|
||||
# def split_window_up():
|
||||
def split_window_vertically():
|
||||
actions.user.idea("action SplitVertically")
|
||||
|
||||
def split_window_horizontally():
|
||||
actions.user.idea("action SplitHorizontally")
|
||||
|
||||
def split_flip():
|
||||
actions.user.idea("action ChangeSplitOrientation")
|
||||
|
||||
def split_maximize():
|
||||
actions.key("ctrl-shift-f12")
|
||||
|
||||
def split_reset():
|
||||
actions.key("shift-f12")
|
||||
|
||||
# def split_window():
|
||||
def split_clear():
|
||||
actions.user.idea("action Unsplit")
|
||||
|
||||
def split_clear_all():
|
||||
actions.user.idea("action UnsplitAll")
|
||||
|
||||
def split_next():
|
||||
actions.user.idea("action NextSplitter")
|
||||
|
||||
# def split_last():
|
||||
# def split_number(index: int):
|
||||
@@ -0,0 +1,288 @@
|
||||
# Requires https://plugins.jetbrains.com/plugin/10504-voice-code-idea
|
||||
app: jetbrains
|
||||
-
|
||||
tag(): user.line_commands
|
||||
tag(): user.multiple_cursors
|
||||
tag(): user.splits
|
||||
tag(): user.tabs
|
||||
tag(): user.command_search
|
||||
tag(): user.command_client
|
||||
|
||||
# multiple_cursors.py support end
|
||||
|
||||
# Auto complete
|
||||
complete: user.idea("action CodeCompletion")
|
||||
perfect: user.idea("action CodeCompletion,action CodeCompletion")
|
||||
smart: user.idea("action SmartTypeCompletion")
|
||||
(done | finish): user.idea("action EditorCompleteStatement")
|
||||
# Copying
|
||||
grab <number>: user.idea_grab(number)
|
||||
action [<user.text>]: user.deprecate_command("2024-09-02", "action", "please")
|
||||
# Refactoring
|
||||
refactor: user.idea("action Refactorings.QuickListPopupAction")
|
||||
refactor <user.text>:
|
||||
user.idea("action Refactorings.QuickListPopupAction")
|
||||
insert(text)
|
||||
extract variable: user.idea("action IntroduceVariable")
|
||||
extract field: user.idea("action IntroduceField")
|
||||
extract constant: user.idea("action IntroduceConstant")
|
||||
extract parameter: user.idea("action IntroduceParameter")
|
||||
extract interface: user.idea("action ExtractInterface")
|
||||
extract method: user.idea("action ExtractMethod")
|
||||
refactor in line: user.idea("action Inline")
|
||||
refactor move: user.idea("action Move")
|
||||
refactor rename: user.idea("action RenameElement")
|
||||
rename file: user.idea("action RenameFile")
|
||||
fix (format | formatting): user.idea("action ReformatCode")
|
||||
fix imports: user.idea("action OptimizeImports")
|
||||
#navigation
|
||||
(go declaration | follow): user.idea("action GotoDeclaration")
|
||||
go implementation: user.idea("action GotoImplementation")
|
||||
go usage: user.idea("action FindUsages")
|
||||
go type: user.idea("action GotoTypeDeclaration")
|
||||
go test: user.idea("action GotoTest")
|
||||
go back: user.idea("action Back")
|
||||
go forward: user.idea("action Forward")
|
||||
# Search
|
||||
find (everywhere | all): user.idea("action SearchEverywhere")
|
||||
find (everywhere | all) <user.text> [over]:
|
||||
user.idea("action SearchEverywhere")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
(search | find) class: user.idea("action GotoClass")
|
||||
(search | find) file: user.idea("action GotoFile")
|
||||
(search | find) path: user.idea("action FindInPath")
|
||||
(search | find) symbol: user.idea("action GotoSymbol")
|
||||
(search | find) symbol <user.text>$:
|
||||
user.idea("action GotoSymbol")
|
||||
insert(text)
|
||||
key("enter")
|
||||
recent: user.idea("action RecentFiles")
|
||||
|
||||
surround [this] with <user.text> [over]:
|
||||
user.idea("action SurroundWith")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
# Making these longer to reduce collisions with real code dictation.
|
||||
insert generated <user.text> [over]:
|
||||
user.idea("action Generate")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
insert template <user.text> [over]:
|
||||
user.idea("action InsertLiveTemplate")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
create (template | snippet): user.idea("action SaveAsTemplate")
|
||||
# Recording
|
||||
toggle recording: user.idea("action StartStopMacroRecording")
|
||||
change (recording | recordings): user.idea("action EditMacros")
|
||||
play recording: user.idea("action PlaybackLastMacro")
|
||||
play recording <user.text> [over]:
|
||||
user.idea("action PlaySavedMacrosAction")
|
||||
insert(text)
|
||||
sleep(500ms)
|
||||
Key("enter")
|
||||
# Marks
|
||||
go mark: user.idea("action ShowBookmarks")
|
||||
toggle mark: user.idea("action ToggleBookmark")
|
||||
go next mark: user.idea("action GotoNextBookmark")
|
||||
go last mark: user.idea("action GotoPreviousBookmark")
|
||||
toggle mark <number>: user.idea("action ToggleBookmark{number}")
|
||||
go mark <number>: user.idea("action GotoBookmark{number}")
|
||||
# Folding
|
||||
expand deep: user.idea("action ExpandRegionRecursively")
|
||||
expand all: user.idea("action ExpandAllRegions")
|
||||
collapse deep: user.idea("action CollapseRegionRecursively")
|
||||
collapse all: user.idea("action CollapseAllRegions")
|
||||
# miscellaneous
|
||||
# XXX These might be better than the structural ones depending on language.
|
||||
go next (method | function): user.idea("action MethodDown")
|
||||
go last (method | function): user.idea("action MethodUp")
|
||||
# Clipboard
|
||||
clippings: user.idea("action PasteMultiple")
|
||||
copy path: user.idea("action CopyPaths")
|
||||
copy reference: user.idea("action CopyReference")
|
||||
copy pretty: user.idea("action CopyAsRichText")
|
||||
# File Creation
|
||||
create sibling: user.idea("action NewElementSamePlace")
|
||||
create sibling <user.text> [over]:
|
||||
user.idea("action NewElementSamePlace")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
create file: user.idea("action NewElement")
|
||||
create file <user.text> [over]:
|
||||
user.idea("action NewElement")
|
||||
sleep(500ms)
|
||||
insert(text)
|
||||
# Task Management
|
||||
go task: user.idea("action tasks.goto")
|
||||
go browser task: user.idea("action tasks.open.in.browser")
|
||||
switch task: user.idea("action tasks.switch")
|
||||
clear task: user.idea("action tasks.close")
|
||||
configure servers: user.idea("action tasks.configure.servers")
|
||||
# Git / Github (not using verb-noun-adjective pattern, mirroring terminal commands.)
|
||||
git pull: user.idea("action Vcs.UpdateProject")
|
||||
git commit: user.idea("action CheckinProject")
|
||||
git push: user.idea("action CheckinProject")
|
||||
git log: user.idea("action Vcs.ShowTabbedFileHistory")
|
||||
git browse: user.idea("action Github.Open.In.Browser")
|
||||
git (gets | gist): user.idea("action Github.Create.Gist")
|
||||
git (pull request | request): user.idea("action Github.Create.Pull.Request")
|
||||
git (view | show | list) (requests | request):
|
||||
user.idea("action Github.View.Pull.Request")
|
||||
git (annotate | blame): user.idea("action Annotate")
|
||||
git menu: user.idea("action Vcs.QuickListPopupAction")
|
||||
# Tool windows:
|
||||
# Toggling various tool windows
|
||||
toggle project: user.idea("action ActivateProjectToolWindow")
|
||||
toggle find: user.idea("action ActivateFindToolWindow")
|
||||
toggle run: user.idea("action ActivateRunToolWindow")
|
||||
toggle debug: user.idea("action ActivateDebugToolWindow")
|
||||
toggle events: user.idea("action ActivateEventLogToolWindow")
|
||||
toggle terminal: user.idea("action ActivateTerminalToolWindow")
|
||||
toggle git: user.idea("action ActivateVersionControlToolWindow")
|
||||
toggle structure: user.idea("action ActivateStructureToolWindow")
|
||||
toggle database: user.idea("action ActivateDatabaseToolWindow")
|
||||
toggle database changes: user.idea("action ActivateDatabaseChangesToolWindow")
|
||||
toggle make: user.idea("action ActivatemakeToolWindow")
|
||||
toggle to do: user.idea("action ActivateTODOToolWindow")
|
||||
toggle docker: user.idea("action ActivateDockerToolWindow")
|
||||
toggle favorites: user.idea("action ActivateFavoritesToolWindow")
|
||||
toggle last: user.idea("action JumpToLastWindow")
|
||||
# Pin/dock/float
|
||||
toggle pinned: user.idea("action TogglePinnedMode")
|
||||
toggle docked: user.idea("action ToggleDockMode")
|
||||
toggle floating: user.idea("action ToggleFloatingMode")
|
||||
toggle windowed: user.idea("action ToggleWindowedMode")
|
||||
toggle split: user.idea("action ToggleSideMode")
|
||||
# Settings, not windows
|
||||
toggle tool buttons: user.idea("action ViewToolButtons")
|
||||
toggle toolbar: user.idea("action ViewToolBar")
|
||||
toggle status [bar]: user.idea("action ViewStatusBar")
|
||||
toggle navigation [bar]: user.idea("action ViewNavigationBar")
|
||||
# Active editor settings
|
||||
toggle power save: user.idea("action TogglePowerSave")
|
||||
toggle whitespace: user.idea("action EditorToggleShowWhitespaces")
|
||||
toggle indents: user.idea("action EditorToggleShowIndentLines")
|
||||
toggle line numbers: user.idea("action EditorToggleShowLineNumbers")
|
||||
toggle (bread crumbs | breadcrumbs): user.idea("action EditorToggleShowBreadcrumbs")
|
||||
toggle gutter icons: user.idea("action EditorToggleShowGutterIcons")
|
||||
toggle wrap: user.idea("action EditorToggleUseSoftWraps")
|
||||
toggle parameters: user.idea("action ToggleInlineHintsAction")
|
||||
# Toggleable views
|
||||
toggle fullscreen: user.idea("action ToggleFullScreen")
|
||||
toggle distraction [free mode]: user.idea("action ToggleDistractionFreeMode")
|
||||
toggle presentation [mode]: user.idea("action TogglePresentationMode")
|
||||
# Toggle additionals
|
||||
toggle comment: code.toggle_comment()
|
||||
# Quick popups
|
||||
change scheme: user.idea("action QuickChangeScheme")
|
||||
# Always javadoc
|
||||
(toggle | pop) (doc | documentation): user.idea("action QuickJavaDoc")
|
||||
(pop deaf | toggle definition): user.idea("action QuickImplementations")
|
||||
pop type: user.idea("action ExpressionTypeInfo")
|
||||
pop parameters: user.idea("action ParameterInfo")
|
||||
# Breakpoints / debugging
|
||||
go breakpoints: user.idea("action ViewBreakpoints")
|
||||
toggle [line] breakpoint: user.idea("action ToggleLineBreakpoint")
|
||||
toggle method breakpoint: user.idea("action ToggleMethodBreakpoint")
|
||||
run menu: user.idea("action ChooseRunConfiguration")
|
||||
run test: user.idea("action RunClass")
|
||||
run test again: user.idea("action Rerun")
|
||||
debug test: user.idea("action DebugClass")
|
||||
step over: user.idea("action StepOver")
|
||||
step into: user.idea("action StepInto")
|
||||
step smart: user.idea("action SmartStepInto")
|
||||
step to line: user.idea("action RunToCursor")
|
||||
continue: user.idea("action Resume")
|
||||
# Grow / Shrink
|
||||
(grow | shrink) window right: user.idea("action ResizeToolWindowRight")
|
||||
(grow | shrink) window left: user.idea("action ResizeToolWindowLeft")
|
||||
(grow | shrink) window up: user.idea("action ResizeToolWindowUp")
|
||||
(grow | shrink) window down: user.idea("action ResizeToolWindowDown")
|
||||
# Movement
|
||||
go next (error | air): user.idea("action GotoNextError")
|
||||
go last (error | air): user.idea("action GotoPreviousError")
|
||||
fix next (error | air):
|
||||
user.idea("action GotoNextError")
|
||||
user.idea("action ShowIntentionActions")
|
||||
fix last (error | air):
|
||||
user.idea("action GotoPreviousError")
|
||||
user.idea("action ShowIntentionActions")
|
||||
# Special Selects
|
||||
select less: user.idea("action EditorUnSelectWord")
|
||||
select (more | this): user.idea("action EditorSelectWord")
|
||||
#jet brains-specific line commands. see line_commands.talon for generic ones
|
||||
expand <number> until <number>:
|
||||
user.select_range(number_1, number_2)
|
||||
user.idea("action ExpandRegion")
|
||||
collapse <number> until <number>:
|
||||
user.select_range(number_1, number_2)
|
||||
user.idea("action CollapseRegion")
|
||||
paste <number> until <number>:
|
||||
user.select_range(number_1, number_2)
|
||||
user.idea("action EditorPaste")
|
||||
refactor <number> until <number>:
|
||||
user.select_range(number_1, number_2)
|
||||
user.idea("action Refactorings.QuickListPopupAction")
|
||||
clone <number>: user.line_clone(number)
|
||||
|
||||
#find/replace
|
||||
clear last <user.text> [over]: user.idea("find prev {text}, action EditorBackSpace")
|
||||
clear next <user.text> [over]: user.idea("find next {text}, action EditorBackSpace")
|
||||
comment last <user.text> [over]:
|
||||
user.idea("find prev {text}, action CommentByLineComment")
|
||||
comment next <user.text> [over]:
|
||||
user.idea("find next {text}, action CommentByLineComment")
|
||||
go last <user.text> [over]: user.idea("find prev {text}, action EditorRight")
|
||||
go next <user.text> [over]: user.idea("find next {text}, action EditorRight")
|
||||
go <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text}, action EditorRight")
|
||||
paste last <user.text> [over]:
|
||||
user.idea("find prev {text}, action EditorRight, action EditorPaste")
|
||||
paste next <user.text> [over]:
|
||||
user.idea("find next {text}, action EditorRight, action EditorPaste")
|
||||
refactor <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text}, action Refactorings.QuickListPopupAction")
|
||||
refactor last <user.text> [over]:
|
||||
user.idea("find prev {text}, action Refactorings.QuickListPopupAction")
|
||||
refactor next <user.text> [over]:
|
||||
user.idea("find next {text}, action Refactorings.QuickListPopupAction")
|
||||
rename <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text}, action RenameElement")
|
||||
rename next <user.text> [over]: user.idea("find next {text}, action RenameElement")
|
||||
rename last <user.text> [over]: user.idea("find prev {text}, action RenameElement")
|
||||
complete <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text},action CodeCompletion")
|
||||
complete next <user.text> [over]: user.idea("find next {text},action CodeCompletion")
|
||||
complete last <user.text> [over]: user.idea("find prev {text},action CodeCompletion")
|
||||
quick fix <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text},action ShowIntentionActions")
|
||||
quick fix next <user.text> [over]:
|
||||
user.idea("find next {text},action ShowIntentionActions")
|
||||
quick fix last <user.text> [over]:
|
||||
user.idea("find prev {text},action ShowIntentionActions")
|
||||
replace last <user.text> [over]: user.idea("find prev {text}, action EditorPaste")
|
||||
replace next <user.text> [over]: user.idea("find next {text}, action EditorPaste")
|
||||
|
||||
follow <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text},action GotoDeclaration")
|
||||
follow next <user.text> [over]: user.idea("find next {text},action GotoDeclaration")
|
||||
follow last <user.text> [over]: user.idea("find prev {text},action GotoDeclaration")
|
||||
|
||||
reference <number> <user.text> [over]:
|
||||
user.idea("goto {number} 0,find next {text},action FindUsages")
|
||||
reference next <user.text> [over]: user.idea("find next {text},action FindUsages")
|
||||
reference last <user.text> [over]: user.idea("find prev {text},action FindUsages")
|
||||
|
||||
select last <user.text> [over]: user.idea("find prev {text}")
|
||||
select next <user.text> [over]: user.idea("find next {text}")
|
||||
select <number> <user.text> [over]: user.idea("goto {number} 0,find next {text}")
|
||||
|
||||
select camel left: user.extend_camel_left()
|
||||
select camel right: user.extend_camel_right()
|
||||
go camel left: user.camel_left()
|
||||
go camel right: user.camel_right()
|
||||
|
||||
# requires plug-in: black-pycharm
|
||||
blacken: user.idea("action BLACKReformatCode")
|
||||
@@ -0,0 +1,65 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app.name: konsole
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class user_actions:
|
||||
# tabs-tag functions implementations
|
||||
def tab_jump(number):
|
||||
actions.key(f"alt-{number}")
|
||||
|
||||
# tab_final is not supported by konsole by default
|
||||
# but short cut can be configured
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class app_actions:
|
||||
# tabs-tag functions implementations
|
||||
def tab_open():
|
||||
actions.key("ctrl-shift-t")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("shift-left")
|
||||
|
||||
def tab_next():
|
||||
actions.key("shift-right")
|
||||
|
||||
def tab_close():
|
||||
actions.key("ctrl-shift-w")
|
||||
|
||||
def tab_reopen():
|
||||
# TODO: decide whether this notification is good style
|
||||
# (if this function wouldn't be defined here a wrong default would be activated)
|
||||
actions.app.notify("tab reopen is not possible in kde konsole")
|
||||
|
||||
def window_open():
|
||||
actions.key("ctrl-shift-n")
|
||||
|
||||
|
||||
# this overwrites the unfitting parts of linux/edit.py
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def page_down():
|
||||
actions.key("shift-pagedown")
|
||||
|
||||
def page_up():
|
||||
actions.key("shift-pageup")
|
||||
|
||||
def paste():
|
||||
actions.key("ctrl-shift-v")
|
||||
|
||||
def copy():
|
||||
actions.key("ctrl-shift-c")
|
||||
|
||||
def find(text: str = None):
|
||||
actions.key("ctrl-shift-f")
|
||||
if str:
|
||||
actions.insert(text)
|
||||
|
||||
# TODO: fix select line and other selection (like shift-right)
|
||||
# see: https://unix.stackexchange.com/questions/485536/kde-konsole-swallows-shift-left-and-shift-right
|
||||
# also fix extend_left and co
|
||||
@@ -0,0 +1,17 @@
|
||||
os: linux
|
||||
and app.name: konsole
|
||||
-
|
||||
# makes the commands in terminal.talon available
|
||||
tag(): terminal
|
||||
|
||||
# activates the implementation of the commands/functions in terminal.talon
|
||||
tag(): user.generic_unix_shell
|
||||
|
||||
# makes commands for certain applications available
|
||||
# you can deactivate them if you do not use the application
|
||||
tag(): user.git
|
||||
tag(): user.anaconda
|
||||
# tag(): user.kubectl
|
||||
|
||||
tag(): user.tabs
|
||||
# TODO: add file_manager support
|
||||
@@ -0,0 +1,22 @@
|
||||
app: keepass
|
||||
-
|
||||
# Database
|
||||
open database: key(ctrl-o)
|
||||
save database: key(ctrl-s)
|
||||
close database: key(ctrl-w)
|
||||
lock database: key(ctrl-l)
|
||||
quit: key(ctrl-q)
|
||||
|
||||
# Entries
|
||||
[add] new entry: key(ctrl-n)
|
||||
clone entry: key(ctrl-k)
|
||||
(view | edit) entry: key(ctrl-e)
|
||||
delete entry: key(ctrl-d)
|
||||
copy user [name]: key(ctrl-b)
|
||||
copy password: key(ctrl-c)
|
||||
open (earl | url | link): key(ctrl-u)
|
||||
copy (earl | url | link): key(ctrl-alt-u)
|
||||
find: key(ctrl-f)
|
||||
find <user.text>:
|
||||
key(ctrl-f)
|
||||
insert("{text}")
|
||||
@@ -0,0 +1,11 @@
|
||||
from talon import Module
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.kindle = r"""
|
||||
os: windows
|
||||
and app.name: Kindle
|
||||
os: windows
|
||||
and app.exe: /^kindle\.exe$/i
|
||||
"""
|
||||
# TODO: mac context and implementation
|
||||
@@ -0,0 +1,4 @@
|
||||
app: kindle
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
@@ -0,0 +1,24 @@
|
||||
from talon import Context, actions
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = """
|
||||
os: windows
|
||||
app: kindle
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_next():
|
||||
actions.key("down")
|
||||
|
||||
def page_previous():
|
||||
actions.key("up")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-g")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
@@ -0,0 +1,26 @@
|
||||
from talon import Context, Module
|
||||
|
||||
mod = Module()
|
||||
mod.tag("kubectl", desc="tag for enabling kubectl commands in your terminal")
|
||||
kubectl = "kubectl"
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
tag: user.kubectl
|
||||
"""
|
||||
|
||||
mod.list("kubectl_action", desc="actions performed by kubectl")
|
||||
ctx.lists["self.kubectl_action"] = ("get", "delete", "describe", "label")
|
||||
|
||||
mod.list("kubectl_object", desc="objects performed by kubectl")
|
||||
ctx.lists["self.kubectl_object"] = (
|
||||
"nodes",
|
||||
"jobs",
|
||||
"pods",
|
||||
"namespaces",
|
||||
"services",
|
||||
"events",
|
||||
"deployments",
|
||||
"replicasets",
|
||||
"daemonsets",
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
tag: terminal
|
||||
and tag: user.kubectl
|
||||
-
|
||||
cube [control]: "kubectl "
|
||||
|
||||
cube create: "kubectl create "
|
||||
cube expose: "kubectl expose "
|
||||
cube run: "kubectl run "
|
||||
cube set: "kubectl set "
|
||||
cube run container: "kubectl run-container "
|
||||
|
||||
cube explain: "kubectl explain "
|
||||
cube get: "kubectl get "
|
||||
cube edit: "kubectl edit "
|
||||
cube delete: "kubectl delete "
|
||||
|
||||
cube rollout: "kubectl rollout "
|
||||
cube rolling update: "kubectl rolling-update "
|
||||
cube scale: "kubectl scale "
|
||||
cube auto scale: "kubectl autoscale "
|
||||
|
||||
cube certificate: "kubectl certificate "
|
||||
cube top: "kubectl top "
|
||||
cube drain: "kubectl drain "
|
||||
cube taint: "kubectl taint "
|
||||
cube (cord | cordon): "kubectl cordon "
|
||||
cube (uncord | uncordon): "kubectl uncordon "
|
||||
cube cluster (info | information): "kubectl cluster-info "
|
||||
|
||||
cube describe: "kubectl describe "
|
||||
cube logs: "kubectl logs "
|
||||
cube attach: "kubectl attach "
|
||||
cube exec: "kubectl exec "
|
||||
cube port forward: "kubectl port-forward "
|
||||
cube proxy: "kubectl proxy "
|
||||
cube copy: "kubectl cp "
|
||||
cube auth: "kubectl auth "
|
||||
|
||||
cube diff: "kubectl diff "
|
||||
cube apply: "kubectl apply "
|
||||
cube patch: "kubectl patch "
|
||||
cube replace: "kubectl replace "
|
||||
cube wait: "kubectl wait "
|
||||
cube convert: "kubectl convert "
|
||||
cube customize: "kubectl kustomize "
|
||||
|
||||
cube label: "kubectl label "
|
||||
cube annotate: "kubectl annotate "
|
||||
cube completion: "kubectl completion "
|
||||
|
||||
cube (interface | API): "kubectl api "
|
||||
cube interface resources: "kubectl api-resources "
|
||||
cube interface versions: "kubectl api-versions "
|
||||
cube config: "kubectl config "
|
||||
cube help: "kubectl help "
|
||||
cube plugin: "kubectl plugin "
|
||||
cube version: "kubectl version "
|
||||
|
||||
cube {user.kubectl_action} [{user.kubectl_object}]:
|
||||
insert("kubectl {kubectl_action} ")
|
||||
insert(kubectl_object or "")
|
||||
|
||||
cube detach:
|
||||
key("ctrl-p")
|
||||
key("ctrl-q")
|
||||
cube shell: user.insert_between("kubectl exec -it ", " -- /bin/bash")
|
||||
@@ -0,0 +1,44 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
apps = mod.apps
|
||||
apps.meld = """
|
||||
os: windows
|
||||
and app.name: Visual diff and merge tool
|
||||
os: windows
|
||||
and app.exe: meld.exe
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: meld
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def tab_open():
|
||||
actions.key("ctrl-n")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-alt-pageup")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-alt-pagedown")
|
||||
|
||||
def tab_reopen():
|
||||
print("Meld does not support this action.")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_jump(number):
|
||||
if number < 10:
|
||||
actions.key(f"alt-{number}")
|
||||
|
||||
def tab_final():
|
||||
print("Meld does not support this action.")
|
||||
|
||||
def tab_duplicate():
|
||||
print("Meld does not support this action.")
|
||||
@@ -0,0 +1,6 @@
|
||||
app: meld
|
||||
-
|
||||
tag(): user.tabs
|
||||
|
||||
change next: key(alt-down)
|
||||
change (previous | last): key(alt-up)
|
||||
@@ -0,0 +1,144 @@
|
||||
import subprocess
|
||||
|
||||
from talon import Context, Module, actions, settings, ui
|
||||
|
||||
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.generic_unix_shell",
|
||||
"user.file_manager",
|
||||
"user.git",
|
||||
"user.kubectl",
|
||||
]
|
||||
|
||||
directories_to_remap = {}
|
||||
directories_to_exclude = {}
|
||||
|
||||
mod.setting(
|
||||
"cygpath",
|
||||
type=str,
|
||||
default="C:\\cygwin64\\bin\\cygpath.exe",
|
||||
desc="Path to cygpath.exe",
|
||||
)
|
||||
|
||||
|
||||
def get_win_path(cyg_path):
|
||||
path = ""
|
||||
try:
|
||||
si = subprocess.STARTUPINFO()
|
||||
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
path = (
|
||||
subprocess.check_output(
|
||||
[settings.get("user.cygpath"), "-w", cyg_path], startupinfo=si
|
||||
)
|
||||
.strip(b"\n")
|
||||
.decode()
|
||||
)
|
||||
except:
|
||||
path = ""
|
||||
return path
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def paste():
|
||||
actions.key("shift-insert")
|
||||
|
||||
def copy():
|
||||
actions.key("ctrl-insert")
|
||||
|
||||
def delete_line():
|
||||
actions.key("ctrl-u")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def file_manager_open_parent():
|
||||
actions.insert("cd ..")
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_current_path():
|
||||
path = ui.active_window().title
|
||||
path = get_win_path(path)
|
||||
|
||||
if path in directories_to_remap:
|
||||
path = directories_to_remap[title]
|
||||
|
||||
if path in directories_to_exclude:
|
||||
path = ""
|
||||
return path
|
||||
|
||||
def file_manager_show_properties():
|
||||
"""Shows the properties for the file"""
|
||||
|
||||
def file_manager_open_directory(path: str):
|
||||
"""opens the directory that's already visible in the view"""
|
||||
actions.insert("cd ")
|
||||
path = f'"{path}"'
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_select_directory(path: str):
|
||||
"""selects the directory"""
|
||||
actions.insert(path)
|
||||
|
||||
def file_manager_new_folder(name: str):
|
||||
"""Creates a new folder in a gui filemanager or inserts the command to do so for terminals"""
|
||||
name = f'"{name}"'
|
||||
|
||||
actions.insert("mkdir " + name)
|
||||
|
||||
def file_manager_open_file(path: str):
|
||||
"""opens the file"""
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_select_file(path: str):
|
||||
"""selects the file"""
|
||||
actions.insert(path)
|
||||
|
||||
def file_manager_open_volume(volume: str):
|
||||
"""file_manager_open_volume"""
|
||||
actions.user.file_manager_open_directory(volume)
|
||||
|
||||
def terminal_list_directories():
|
||||
actions.insert("ls")
|
||||
actions.key("enter")
|
||||
|
||||
def terminal_list_all_directories():
|
||||
actions.insert("ls -a")
|
||||
actions.key("enter")
|
||||
|
||||
def terminal_change_directory(path: str):
|
||||
actions.insert(f"cd {path}")
|
||||
if path:
|
||||
actions.key("enter")
|
||||
|
||||
def terminal_change_directory_root():
|
||||
"""Root of current drive"""
|
||||
actions.insert("cd /")
|
||||
actions.key("enter")
|
||||
|
||||
def terminal_clear_screen():
|
||||
"""Clear screen"""
|
||||
actions.key("ctrl-l")
|
||||
|
||||
def terminal_run_last():
|
||||
actions.key("up enter")
|
||||
|
||||
def terminal_kill_all():
|
||||
actions.key("ctrl-c")
|
||||
actions.insert("y")
|
||||
actions.key("enter")
|
||||
@@ -0,0 +1,66 @@
|
||||
from talon import Context, Module, actions, clip, ui
|
||||
|
||||
# App definition
|
||||
mod = Module()
|
||||
mod.apps.nautilus = """
|
||||
os: linux
|
||||
and app.exe: nautilus
|
||||
os: linux
|
||||
and app.name: Org.gnome.Nautilus
|
||||
os: linux
|
||||
and app.name: Caja
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
app: nautilus
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
# app.tabs
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.tabs
|
||||
def tab_jump(number: int):
|
||||
actions.key(f"alt-{number}")
|
||||
|
||||
# user.navigation
|
||||
def go_back():
|
||||
actions.key("alt-left")
|
||||
|
||||
def go_forward():
|
||||
actions.key("alt-right")
|
||||
|
||||
# user.file_manager
|
||||
def file_manager_open_parent():
|
||||
actions.key("alt-up")
|
||||
|
||||
def file_manager_show_properties():
|
||||
actions.key("ctrl-i")
|
||||
|
||||
def file_manager_open_directory(path: str):
|
||||
actions.key("ctrl-l")
|
||||
actions.insert(path)
|
||||
actions.key("enter")
|
||||
|
||||
def file_manager_new_folder(name: str = None):
|
||||
actions.key("ctrl-shift-n")
|
||||
if name:
|
||||
actions.insert(name)
|
||||
|
||||
def file_manager_terminal_here():
|
||||
actions.key("ctrl-l")
|
||||
with clip.capture() as path:
|
||||
actions.edit.copy()
|
||||
ui.launch(path="gnome-terminal", args=[f"--working-directory={path.get()}"])
|
||||
@@ -0,0 +1,5 @@
|
||||
app: nautilus
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.tabs
|
||||
tag(): user.file_manager
|
||||
@@ -0,0 +1,43 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.nitro_reader_five = r"""
|
||||
os: windows
|
||||
and app.name: Nitro Reader 5
|
||||
os: windows
|
||||
and app.exe: /^nitropdfreader\.exe$/i
|
||||
"""
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = """
|
||||
app: nitro_reader_five
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("app")
|
||||
class app_actions:
|
||||
# app.tabs
|
||||
def tab_open():
|
||||
actions.key("ctrl-shift-o")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_next():
|
||||
actions.key("right")
|
||||
|
||||
def page_previous():
|
||||
actions.key("left")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-g")
|
||||
actions.edit.select_line()
|
||||
actions.insert(str(number))
|
||||
actions.key("enter alt:2")
|
||||
|
||||
def page_final():
|
||||
actions.key("end")
|
||||
@@ -0,0 +1,5 @@
|
||||
app: nitro_reader_five
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
tag(): user.tabs
|
||||
@@ -0,0 +1,148 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
mod = Module()
|
||||
ctx = Context()
|
||||
|
||||
apps = mod.apps
|
||||
apps.notepad_plus_plus = r"""
|
||||
os: windows
|
||||
and app.name: Notepad++ : a free (GNU) source code editor
|
||||
os: windows
|
||||
and app.name: Notepad++ : a free (GPL) source code editor
|
||||
os: windows
|
||||
and app.exe: /^notepad\+\+\.exe$/i
|
||||
"""
|
||||
|
||||
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_open():
|
||||
actions.key("ctrl-n")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
|
||||
@ctx.action_class("code")
|
||||
class CodeActions:
|
||||
def toggle_comment():
|
||||
actions.key("ctrl-q")
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
def line_clone():
|
||||
actions.key("ctrl-d")
|
||||
|
||||
def line_swap_up():
|
||||
actions.key("ctrl-shift-up")
|
||||
|
||||
def line_swap_down():
|
||||
actions.key("ctrl-shift-down")
|
||||
|
||||
def indent_more():
|
||||
actions.key("tab")
|
||||
|
||||
def indent_less():
|
||||
actions.key("shift-tab")
|
||||
|
||||
def jump_line(n: int):
|
||||
actions.key("ctrl-g")
|
||||
actions.insert(str(n))
|
||||
actions.key("enter")
|
||||
|
||||
def find_next():
|
||||
actions.key("enter")
|
||||
|
||||
def find_previous():
|
||||
actions.key("shift-enter")
|
||||
|
||||
|
||||
@ctx.action_class("win")
|
||||
class win_actions:
|
||||
def filename():
|
||||
title = actions.win.title()
|
||||
result = title.split(" - ")[0]
|
||||
if "." in result:
|
||||
# print(result.split("\\")[-1])
|
||||
return result.split("\\")[-1]
|
||||
return ""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def select_next_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("enter esc")
|
||||
actions.sleep("100ms")
|
||||
|
||||
def select_previous_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("shift-enter esc")
|
||||
actions.sleep("100ms")
|
||||
|
||||
def tab_jump(number: int):
|
||||
if number < 10:
|
||||
actions.key(f"ctrl-keypad_{number}")
|
||||
|
||||
def tab_final():
|
||||
"""Jumps to the final tab"""
|
||||
print("Notepad doesn't support this...")
|
||||
# actions.key("ctrl-numpad_0")
|
||||
|
||||
# find_and_replace.py support begin
|
||||
|
||||
def find_everywhere(text: str):
|
||||
"""Triggers find across project"""
|
||||
|
||||
actions.key("ctrl-shift-f")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def find_toggle_match_by_case():
|
||||
"""Toggles find match by case sensitivity"""
|
||||
actions.key("alt-c")
|
||||
|
||||
def find_toggle_match_by_word():
|
||||
"""Toggles find match by whole words"""
|
||||
actions.key("alt-w")
|
||||
|
||||
def find_toggle_match_by_regex():
|
||||
"""Toggles find match by regex"""
|
||||
actions.key("alt-g")
|
||||
|
||||
def replace(text: str):
|
||||
"""Search and replaces in the active editor"""
|
||||
actions.key("esc ctrl-h")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_everywhere(text: str):
|
||||
"""Search and replaces in the entire project"""
|
||||
actions.key("esc ctrl-shift-f")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_confirm():
|
||||
"""Confirm replace at current position"""
|
||||
actions.key("alt-r")
|
||||
|
||||
def replace_confirm_all():
|
||||
"""Confirm replace all"""
|
||||
actions.key("alt-a")
|
||||
|
||||
# find_and_replace.py support end
|
||||
@@ -0,0 +1,22 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
ctx = Context()
|
||||
mod = Module()
|
||||
|
||||
mod.apps.notepad = r"""
|
||||
os: windows
|
||||
and app.exe: notepad.exe
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: notepad
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("win")
|
||||
class win_actions:
|
||||
def filename():
|
||||
filename = actions.win.title().split(" - ")[0]
|
||||
if "." in filename:
|
||||
return filename
|
||||
return ""
|
||||
@@ -0,0 +1,5 @@
|
||||
app: notepad
|
||||
-
|
||||
|
||||
tag(): user.tabs
|
||||
tag(): user.find_and_replace
|
||||
@@ -0,0 +1,16 @@
|
||||
from talon import Context, Module
|
||||
|
||||
mod = Module()
|
||||
mod.apps.obsidian = "app.name: Obsidian"
|
||||
|
||||
lang_ctx = Context()
|
||||
lang_ctx.matches = r"""
|
||||
app: obsidian
|
||||
not tag: user.code_language_forced
|
||||
"""
|
||||
|
||||
|
||||
@lang_ctx.action_class("code")
|
||||
class CodeActions:
|
||||
def language():
|
||||
return "markdown"
|
||||
@@ -0,0 +1,3 @@
|
||||
app: obsidian
|
||||
-
|
||||
tag(): user.tabs
|
||||
@@ -0,0 +1,49 @@
|
||||
from talon import Context, Module, actions
|
||||
|
||||
# --- App definition ---
|
||||
mod = Module()
|
||||
mod.apps.okular = r"""
|
||||
os: windows
|
||||
and app.name: okular.exe
|
||||
os: windows
|
||||
and app.exe: /^okular\.exe$/i
|
||||
"""
|
||||
mod.apps.okular = """
|
||||
os: linux
|
||||
and app.name: okular
|
||||
"""
|
||||
# TODO: mac context and implementation
|
||||
|
||||
# Context matching
|
||||
ctx = Context()
|
||||
ctx.matches = """
|
||||
os: windows
|
||||
os: linux
|
||||
app: okular
|
||||
"""
|
||||
|
||||
|
||||
# --- Implement actions ---
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# user.pages
|
||||
def page_current():
|
||||
actions.key("ctrl-g")
|
||||
page = actions.edit.selected_text()
|
||||
actions.key("escape")
|
||||
return int(page)
|
||||
|
||||
def page_next():
|
||||
actions.key("l")
|
||||
|
||||
def page_previous():
|
||||
actions.key("h")
|
||||
|
||||
def page_jump(number: int):
|
||||
actions.key("ctrl-g")
|
||||
actions.sleep("100ms")
|
||||
actions.insert(str(number))
|
||||
actions.key("enter")
|
||||
|
||||
def page_final():
|
||||
actions.key("ctrl-end")
|
||||
@@ -0,0 +1,4 @@
|
||||
app: okular
|
||||
-
|
||||
# Set tags
|
||||
tag(): user.pages
|
||||
@@ -0,0 +1,18 @@
|
||||
from talon import Module
|
||||
|
||||
mod = Module()
|
||||
apps = mod.apps
|
||||
apps.opera = "app.name: Opera"
|
||||
apps.opera = "app.name: Opera Internet Browser"
|
||||
apps.opera = """
|
||||
os: mac
|
||||
and app.bundle: com.operasoftware.Opera
|
||||
"""
|
||||
apps.opera = r"""
|
||||
os: windows
|
||||
and app.exe: /^opera\.exe$/i
|
||||
"""
|
||||
apps.opera = """
|
||||
os: linux
|
||||
and app.exe: opera
|
||||
"""
|
||||
@@ -0,0 +1,4 @@
|
||||
app: opera
|
||||
-
|
||||
tag(): browser
|
||||
tag(): user.tabs
|
||||
@@ -0,0 +1,73 @@
|
||||
from talon import Context, actions
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
os: mac
|
||||
app: opera
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_duplicate():
|
||||
actions.browser.focus_address()
|
||||
actions.sleep("180ms")
|
||||
possibly_edited_url = actions.edit.selected_text()
|
||||
actions.key("esc:2")
|
||||
actions.browser.focus_address()
|
||||
actions.sleep("180ms")
|
||||
url_address = actions.edit.selected_text()
|
||||
actions.user.paste(possibly_edited_url)
|
||||
actions.app.tab_open()
|
||||
actions.user.paste(url_address)
|
||||
actions.key("enter")
|
||||
|
||||
def tab_final():
|
||||
raise NotImplementedError(
|
||||
"Opera doesn't have a default shortcut for this functionality but it can be configured"
|
||||
)
|
||||
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def tab_next():
|
||||
actions.key("cmd-alt-right")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("cmd-alt-left")
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def bookmark_tabs():
|
||||
raise NotImplementedError("Opera doesn't support this functionality")
|
||||
|
||||
def go_home():
|
||||
raise NotImplementedError("Opera doesn't support this functionality")
|
||||
|
||||
def go_back():
|
||||
actions.browser.focus_page()
|
||||
actions.next()
|
||||
|
||||
def go_forward():
|
||||
actions.browser.focus_page()
|
||||
actions.next()
|
||||
|
||||
def show_downloads():
|
||||
actions.key("cmd-j")
|
||||
|
||||
def show_extensions():
|
||||
actions.key("cmd-shift-e")
|
||||
|
||||
def show_history():
|
||||
actions.key("cmd-shift-h")
|
||||
|
||||
def focus_page():
|
||||
actions.key("cmd-alt-l")
|
||||
|
||||
def reload_hard():
|
||||
actions.key("shift-5")
|
||||
@@ -0,0 +1,86 @@
|
||||
from talon import Context, actions, app
|
||||
|
||||
ctx = Context()
|
||||
ctx.matches = r"""
|
||||
os: windows
|
||||
os: linux
|
||||
app: opera
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
def tab_duplicate():
|
||||
actions.browser.focus_address()
|
||||
actions.sleep("180ms")
|
||||
possibly_edited_url = actions.edit.selected_text()
|
||||
actions.key("esc:2")
|
||||
actions.browser.focus_address()
|
||||
actions.sleep("180ms")
|
||||
url_address = actions.edit.selected_text()
|
||||
actions.user.paste(possibly_edited_url)
|
||||
actions.app.tab_open()
|
||||
actions.user.paste(url_address)
|
||||
actions.key("enter")
|
||||
|
||||
def tab_jump(number: int):
|
||||
if number < 9:
|
||||
actions.key(f"ctrl-{number}")
|
||||
|
||||
def tab_final():
|
||||
raise NotImplementedError(
|
||||
"Opera doesn't have a default shortcut for this functionality but it can be configured"
|
||||
)
|
||||
|
||||
def tab_close_wrapper():
|
||||
actions.sleep("180ms")
|
||||
actions.app.tab_close()
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
def preferences():
|
||||
actions.key("alt-p")
|
||||
|
||||
def tab_next():
|
||||
actions.key("ctrl-pagedown")
|
||||
|
||||
def tab_previous():
|
||||
actions.key("ctrl-pageup")
|
||||
|
||||
|
||||
@ctx.action_class("browser")
|
||||
class BrowserActions:
|
||||
def bookmarks_bar():
|
||||
raise NotImplementedError(
|
||||
"Opera doesn't have a default shortcut for this functionality but it can be configured"
|
||||
)
|
||||
|
||||
def bookmark_tabs():
|
||||
raise NotImplementedError("Opera doesn't support this functionality")
|
||||
|
||||
def go_home():
|
||||
raise NotImplementedError("Opera doesn't support this functionality")
|
||||
|
||||
def go_back():
|
||||
actions.browser.focus_page()
|
||||
actions.next()
|
||||
|
||||
def go_forward():
|
||||
actions.browser.focus_page()
|
||||
actions.next()
|
||||
|
||||
def bookmarks():
|
||||
actions.key("ctrl-shift-b")
|
||||
|
||||
def show_downloads():
|
||||
actions.key("ctrl-j")
|
||||
|
||||
def show_extensions():
|
||||
actions.key("ctrl-shift-e")
|
||||
|
||||
def focus_page():
|
||||
actions.key("f9")
|
||||
|
||||
def reload_hard():
|
||||
actions.key("shift-5")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user