init commit

This commit is contained in:
unknown
2025-08-19 08:06:37 -04:00
commit 2957b5515a
743 changed files with 45495 additions and 0 deletions
+405
View File
@@ -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):
+288
View File
@@ -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")