init commit
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# VS Code support
|
||||
|
||||
Installing several Talon community-developed VS Code extensions will improve your experience.
|
||||
|
||||
The [VS Code Talon extension pack](https://marketplace.visualstudio.com/items?itemName=pokey.talon) enables a couple advanced commands and improves the speed/robustness of Talon issuing VS Code commands.
|
||||
|
||||
The [Andreas Talon](https://marketplace.visualstudio.com/items?itemName=AndreasArvidsson.andreas-talon) extension (dependent on the command server in the extension pack) adds additional commands and useful features for editing your Talon configuration in VS Code.
|
||||
|
||||
## Cursorless
|
||||
|
||||
If you'd like to use Cursorless, [follow the instructions on the Cursorless site](https://www.cursorless.org/docs/user/installation/).
|
||||
|
||||
## Terminal
|
||||
|
||||
By default, Talon cannot recognize that you have the VS Code integrated terminal focused, so the `terminal` tag is never active in VS Code. Your goal is for the VS Code window title to reflect whether a terminal is focused, then to match the title in your Talon configuration. You can do so in two ways.
|
||||
|
||||
Note that the full window title may not be displayed at the top of VS Code windows. To be sure you are seeing the whole title, say _help scope_ and watch Misc > `win.title` in the scope window that appears.
|
||||
|
||||
### Option 1: Add focused view to window title
|
||||
|
||||
Change the [`window.title`](vscode://settings/window.title) setting to:
|
||||
|
||||
```
|
||||
${activeEditorShort}${separator}${rootName}${separator}${profileName}${separator}focus:[${focusedView}]
|
||||
```
|
||||
|
||||
This causes VS Code to include `focus:[Terminal]` in the window title whenever the terminal is focused (e.g. by saying _panel terminal_). [Community's VS Code support looks for this string in the window title](vscode_terminal.talon#L5) and activates the terminal tag.
|
||||
|
||||
If you have existing customizations to your window title you want to keep, ensure that `focus:[${focusedView}]` appears somewhere within your custom `window.title`.
|
||||
|
||||
To enable terminal commands, create a file in your Talon user directory that matches the terminal tag in VS Code, and activates any tags for commands you have installed/want to use, for example:
|
||||
|
||||
```talon
|
||||
app: vscode
|
||||
tag: terminal
|
||||
-
|
||||
tag(): user.generic_unix_shell
|
||||
tag(): user.git
|
||||
tag(): user.kubectl
|
||||
tag(): user.readline
|
||||
```
|
||||
|
||||
### Option 2: Open VS Code integrated terminals as editors
|
||||
|
||||
This option lets you enable different voice commands based on _what_ is running in the terminal — for example, if you use both PowerShell and WSL in VS Code integrated terminals.
|
||||
|
||||
Change the [`terminal.integrated.defaultLocation`](vscode://settings/terminal.integrated.defaultLocation) setting to `editor`. Then, create a terminal with the voice command _terminal new_.
|
||||
|
||||
In an otherwise-default VS Code setup, the first part of the window title as displayed in _help scope_ is the currently-running process, e.g. `zsh` or `powershell`; this is also displayed in the tab title. You can customize the terminal tab title/part of the window title with the [`terminal.integrated.tabs.title`](vscode://settings/terminal.integrated.tabs.title) setting.
|
||||
|
||||
To enable terminal commands, create one or more files in your Talon user directory that match the first portion of the window title, and activates **both** the `terminal` tag and any tags for commands you have installed/want to use. For example:
|
||||
|
||||
```talon
|
||||
app: vscode
|
||||
win.title: /^zsh /
|
||||
-
|
||||
tag(): terminal
|
||||
tag(): user.generic_unix_shell
|
||||
tag(): user.git
|
||||
tag(): user.readline
|
||||
```
|
||||
|
||||
```talon
|
||||
app: vscode
|
||||
win.title: /^powershell /
|
||||
-
|
||||
tag(): terminal
|
||||
tag(): user.generic_windows_shell
|
||||
tag(): user.git
|
||||
```
|
||||
@@ -0,0 +1,438 @@
|
||||
from talon import Context, Module, actions, app
|
||||
|
||||
is_mac = app.platform == "mac"
|
||||
|
||||
ctx = Context()
|
||||
ctx_editor = Context()
|
||||
mac_ctx = Context()
|
||||
mod = Module()
|
||||
# com.todesktop.230313mzl4w4u92 is for Cursor - https://www.cursor.com/
|
||||
mod.apps.vscode = """
|
||||
os: mac
|
||||
and app.bundle: com.microsoft.VSCode
|
||||
os: mac
|
||||
and app.bundle: com.microsoft.VSCodeInsiders
|
||||
os: mac
|
||||
and app.bundle: com.vscodium
|
||||
os: mac
|
||||
and app.bundle: co.posit.positron
|
||||
os: mac
|
||||
and app.bundle: com.visualstudio.code.oss
|
||||
os: mac
|
||||
and app.bundle: com.todesktop.230313mzl4w4u92
|
||||
os: mac
|
||||
and app.bundle: com.exafunction.windsurf
|
||||
"""
|
||||
mod.apps.vscode = """
|
||||
os: linux
|
||||
and app.name: Code
|
||||
os: linux
|
||||
and app.name: code-oss
|
||||
os: linux
|
||||
and app.name: code-insiders
|
||||
os: linux
|
||||
and app.name: VSCodium
|
||||
os: linux
|
||||
and app.name: Codium
|
||||
os: linux
|
||||
and app.name: Cursor
|
||||
os: linux
|
||||
and app.name: Positron
|
||||
"""
|
||||
mod.apps.vscode = r"""
|
||||
os: windows
|
||||
and app.name: Visual Studio Code
|
||||
os: windows
|
||||
and app.name: Visual Studio Code Insiders
|
||||
os: windows
|
||||
and app.name: Visual Studio Code - Insiders
|
||||
os: windows
|
||||
and app.exe: /^code\.exe$/i
|
||||
os: windows
|
||||
and app.exe: /^code-insiders\.exe$/i
|
||||
os: windows
|
||||
and app.name: VSCodium
|
||||
os: windows
|
||||
and app.exe: /^vscodium\.exe$/i
|
||||
os: windows
|
||||
and app.name: Azure Data Studio
|
||||
os: windows
|
||||
and app.exe: /^azuredatastudio\.exe$/i
|
||||
os: windows
|
||||
and app.exe: positron.exe
|
||||
os: windows
|
||||
and app.exe: /^cursor\.exe$/i
|
||||
os: windows
|
||||
and app.exe: /^positron\.exe$/i
|
||||
"""
|
||||
|
||||
ctx.matches = r"""
|
||||
app: vscode
|
||||
"""
|
||||
ctx_editor.matches = r"""
|
||||
app: vscode
|
||||
and win.title: /focus:\[Text Editor\]/
|
||||
"""
|
||||
mac_ctx.matches = r"""
|
||||
os: mac
|
||||
app: vscode
|
||||
"""
|
||||
|
||||
|
||||
@ctx.action_class("app")
|
||||
class AppActions:
|
||||
# talon app actions
|
||||
def tab_open():
|
||||
actions.user.vscode("workbench.action.files.newUntitledFile")
|
||||
|
||||
def tab_close():
|
||||
actions.user.vscode("workbench.action.closeActiveEditor")
|
||||
|
||||
def tab_next():
|
||||
actions.user.vscode("workbench.action.nextEditorInGroup")
|
||||
|
||||
def tab_previous():
|
||||
actions.user.vscode("workbench.action.previousEditorInGroup")
|
||||
|
||||
def tab_reopen():
|
||||
actions.user.vscode("workbench.action.reopenClosedEditor")
|
||||
|
||||
def window_close():
|
||||
actions.user.vscode("workbench.action.closeWindow")
|
||||
|
||||
def window_open():
|
||||
actions.user.vscode("workbench.action.newWindow")
|
||||
|
||||
|
||||
@ctx.action_class("code")
|
||||
class CodeActions:
|
||||
# talon code actions
|
||||
def toggle_comment():
|
||||
actions.user.vscode("editor.action.commentLine")
|
||||
|
||||
|
||||
# In the editor, use RPC commands to avoid conflicting with the editor's keybindings.
|
||||
# Only do this for editor, so that e.g. modal windows can still be pasted into with
|
||||
# ctrl-v.
|
||||
@ctx_editor.action_class("edit")
|
||||
class EditActions:
|
||||
def undo():
|
||||
actions.user.vscode("undo")
|
||||
|
||||
def redo():
|
||||
actions.user.vscode("redo")
|
||||
|
||||
def copy():
|
||||
actions.user.vscode("editor.action.clipboardCopyAction")
|
||||
|
||||
def paste():
|
||||
actions.user.vscode("editor.action.clipboardPasteAction")
|
||||
|
||||
def find(text: str = None):
|
||||
if text:
|
||||
actions.user.run_rpc_command(
|
||||
"editor.actions.findWithArgs", {"searchString": text}
|
||||
)
|
||||
else:
|
||||
actions.user.vscode("actions.find")
|
||||
|
||||
|
||||
@ctx.action_class("edit")
|
||||
class EditActions:
|
||||
# talon edit actions
|
||||
def indent_more():
|
||||
actions.user.vscode("editor.action.indentLines")
|
||||
|
||||
def indent_less():
|
||||
actions.user.vscode("editor.action.outdentLines")
|
||||
|
||||
def save_all():
|
||||
actions.user.vscode("workbench.action.files.saveAll")
|
||||
|
||||
def save():
|
||||
actions.user.vscode("workbench.action.files.save")
|
||||
|
||||
def find_next():
|
||||
actions.user.vscode("editor.action.nextMatchFindAction")
|
||||
|
||||
def find_previous():
|
||||
actions.user.vscode("editor.action.previousMatchFindAction")
|
||||
|
||||
def line_swap_up():
|
||||
actions.key("alt-up")
|
||||
|
||||
def line_swap_down():
|
||||
actions.key("alt-down")
|
||||
|
||||
def line_clone():
|
||||
actions.key("shift-alt-down")
|
||||
|
||||
def line_insert_down():
|
||||
actions.user.vscode("editor.action.insertLineAfter")
|
||||
|
||||
def line_insert_up():
|
||||
actions.user.vscode("editor.action.insertLineBefore")
|
||||
|
||||
def jump_line(n: int):
|
||||
actions.user.vscode("workbench.action.gotoLine")
|
||||
actions.insert(str(n))
|
||||
actions.key("enter")
|
||||
actions.edit.line_start()
|
||||
|
||||
def zoom_reset():
|
||||
actions.user.vscode("workbench.action.zoomReset")
|
||||
|
||||
|
||||
@ctx.action_class("win")
|
||||
class WinActions:
|
||||
def filename():
|
||||
title = actions.win.title()
|
||||
# this doesn't seem to be necessary on VSCode for Mac
|
||||
# if title == "":
|
||||
# title = ui.active_window().doc
|
||||
|
||||
if is_mac:
|
||||
result = title.split(" — ")[0]
|
||||
else:
|
||||
result = title.split(" - ")[0]
|
||||
|
||||
if "." in result:
|
||||
return result
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def vscode_terminal(number: int):
|
||||
"""Activate a terminal by number"""
|
||||
actions.user.vscode(f"workbench.action.terminal.focusAtIndex{number}")
|
||||
|
||||
def command_palette():
|
||||
"""Show command palette"""
|
||||
actions.key("ctrl-shift-p")
|
||||
|
||||
|
||||
@mac_ctx.action_class("edit")
|
||||
class MacEditActions:
|
||||
def find(text: str = None):
|
||||
actions.key("cmd-f")
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
|
||||
@mac_ctx.action_class("user")
|
||||
class MacUserActions:
|
||||
def command_palette():
|
||||
actions.key("cmd-shift-p")
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class UserActions:
|
||||
# splits.py support begin
|
||||
def split_clear_all():
|
||||
actions.user.vscode("workbench.action.editorLayoutSingle")
|
||||
|
||||
def split_clear():
|
||||
actions.user.vscode("workbench.action.joinTwoGroups")
|
||||
|
||||
def split_flip():
|
||||
actions.user.vscode("workbench.action.toggleEditorGroupLayout")
|
||||
|
||||
def split_maximize():
|
||||
actions.user.vscode("workbench.action.toggleMaximizeEditorGroup")
|
||||
|
||||
def split_reset():
|
||||
actions.user.vscode("workbench.action.evenEditorWidths")
|
||||
|
||||
def split_last():
|
||||
actions.user.vscode("workbench.action.focusLeftGroup")
|
||||
|
||||
def split_next():
|
||||
actions.user.vscode("workbench.action.focusRightGroup")
|
||||
|
||||
def split_window_down():
|
||||
actions.user.vscode("workbench.action.moveEditorToBelowGroup")
|
||||
|
||||
def split_window_horizontally():
|
||||
actions.user.vscode("workbench.action.splitEditorOrthogonal")
|
||||
|
||||
def split_window_left():
|
||||
actions.user.vscode("workbench.action.moveEditorToLeftGroup")
|
||||
|
||||
def split_window_right():
|
||||
actions.user.vscode("workbench.action.moveEditorToRightGroup")
|
||||
|
||||
def split_window_up():
|
||||
actions.user.vscode("workbench.action.moveEditorToAboveGroup")
|
||||
|
||||
def split_window_vertically():
|
||||
actions.user.vscode("workbench.action.splitEditor")
|
||||
|
||||
def split_window():
|
||||
actions.user.vscode("workbench.action.splitEditor")
|
||||
|
||||
def split_number(index: int):
|
||||
supported_ordinals = [
|
||||
"First",
|
||||
"Second",
|
||||
"Third",
|
||||
"Fourth",
|
||||
"Fifth",
|
||||
"Sixth",
|
||||
"Seventh",
|
||||
"Eighth",
|
||||
]
|
||||
|
||||
if 0 <= index - 1 < len(supported_ordinals):
|
||||
actions.user.vscode(
|
||||
f"workbench.action.focus{supported_ordinals[index - 1]}EditorGroup"
|
||||
)
|
||||
|
||||
# splits.py support end
|
||||
|
||||
# multiple_cursor.py support begin
|
||||
# note: vscode has no explicit mode for multiple cursors
|
||||
def multi_cursor_add_above():
|
||||
actions.user.vscode("editor.action.insertCursorAbove")
|
||||
|
||||
def multi_cursor_add_below():
|
||||
actions.user.vscode("editor.action.insertCursorBelow")
|
||||
|
||||
def multi_cursor_add_to_line_ends():
|
||||
actions.user.vscode("editor.action.insertCursorAtEndOfEachLineSelected")
|
||||
|
||||
def multi_cursor_disable():
|
||||
actions.key("escape")
|
||||
|
||||
def multi_cursor_enable():
|
||||
actions.skip()
|
||||
|
||||
def multi_cursor_select_all_occurrences():
|
||||
actions.user.vscode("editor.action.selectHighlights")
|
||||
|
||||
def multi_cursor_select_fewer_occurrences():
|
||||
actions.user.vscode("cursorUndo")
|
||||
|
||||
def multi_cursor_select_more_occurrences():
|
||||
actions.user.vscode("editor.action.addSelectionToNextFindMatch")
|
||||
|
||||
def multi_cursor_skip_occurrence():
|
||||
actions.user.vscode("editor.action.moveSelectionToNextFindMatch")
|
||||
|
||||
# multiple_cursor.py support end
|
||||
|
||||
def command_search(command: str = ""):
|
||||
actions.user.vscode("workbench.action.showCommands")
|
||||
if command != "":
|
||||
actions.insert(command)
|
||||
|
||||
# tabs.py support begin
|
||||
def tab_jump(number: int):
|
||||
if number < 10:
|
||||
if is_mac:
|
||||
actions.user.vscode_with_plugin(
|
||||
f"workbench.action.openEditorAtIndex{number}"
|
||||
)
|
||||
else:
|
||||
actions.key(f"alt-{number}")
|
||||
else:
|
||||
actions.user.vscode_with_plugin(
|
||||
"workbench.action.openEditorAtIndex", number
|
||||
)
|
||||
|
||||
def tab_final():
|
||||
if is_mac:
|
||||
actions.user.vscode("workbench.action.lastEditorInGroup")
|
||||
else:
|
||||
actions.key("alt-0")
|
||||
|
||||
def tab_duplicate():
|
||||
# Duplicates the current tab into a new tab group
|
||||
# vscode does not allow duplicate tabs in the same tab group, and so is implemented through splits
|
||||
actions.user.split_window_vertically()
|
||||
|
||||
# tabs.py support end
|
||||
|
||||
# find_and_replace.py support begin
|
||||
|
||||
def find_everywhere(text: str):
|
||||
"""Triggers find across project"""
|
||||
if is_mac:
|
||||
actions.key("cmd-shift-f")
|
||||
else:
|
||||
actions.key("ctrl-shift-f")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def find_toggle_match_by_case():
|
||||
"""Toggles find match by case sensitivity"""
|
||||
if is_mac:
|
||||
actions.key("alt-cmd-c")
|
||||
else:
|
||||
actions.key("alt-c")
|
||||
|
||||
def find_toggle_match_by_word():
|
||||
"""Toggles find match by whole words"""
|
||||
if is_mac:
|
||||
actions.key("cmd-alt-w")
|
||||
else:
|
||||
actions.key("alt-w")
|
||||
|
||||
def find_toggle_match_by_regex():
|
||||
"""Toggles find match by regex"""
|
||||
if is_mac:
|
||||
actions.key("cmd-alt-r")
|
||||
else:
|
||||
actions.key("alt-r")
|
||||
|
||||
def replace(text: str):
|
||||
"""Search and replaces in the active editor"""
|
||||
if is_mac:
|
||||
actions.key("alt-cmd-f")
|
||||
else:
|
||||
actions.key("ctrl-h")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_everywhere(text: str):
|
||||
"""Search and replaces in the entire project"""
|
||||
if is_mac:
|
||||
actions.key("cmd-shift-h")
|
||||
else:
|
||||
actions.key("ctrl-shift-h")
|
||||
|
||||
if text:
|
||||
actions.insert(text)
|
||||
|
||||
def replace_confirm():
|
||||
"""Confirm replace at current position"""
|
||||
if is_mac:
|
||||
actions.key("shift-cmd-1")
|
||||
else:
|
||||
actions.key("ctrl-shift-1")
|
||||
|
||||
def replace_confirm_all():
|
||||
"""Confirm replace all"""
|
||||
if is_mac:
|
||||
actions.key("cmd-enter")
|
||||
else:
|
||||
actions.key("ctrl-alt-enter")
|
||||
|
||||
def select_previous_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("shift-enter esc")
|
||||
|
||||
def select_next_occurrence(text: str):
|
||||
actions.edit.find(text)
|
||||
actions.sleep("100ms")
|
||||
actions.key("esc")
|
||||
|
||||
def insert_snippet(body: str):
|
||||
actions.user.run_rpc_command("editor.action.insertSnippet", {"snippet": body})
|
||||
|
||||
def move_cursor_to_next_snippet_stop():
|
||||
actions.user.vscode("jumpToNextSnippetPlaceholder")
|
||||
@@ -0,0 +1,289 @@
|
||||
#custom vscode commands go here
|
||||
app: vscode
|
||||
-
|
||||
tag(): user.find_and_replace
|
||||
tag(): user.line_commands
|
||||
tag(): user.multiple_cursors
|
||||
tag(): user.splits
|
||||
tag(): user.tabs
|
||||
tag(): user.command_search
|
||||
|
||||
window reload: user.vscode("workbench.action.reloadWindow")
|
||||
window close: user.vscode("workbench.action.closeWindow")
|
||||
#multiple_cursor.py support end
|
||||
|
||||
go view [<user.text>]:
|
||||
user.vscode("workbench.action.openView")
|
||||
insert(user.text or "")
|
||||
|
||||
# Sidebar
|
||||
bar explore: user.vscode("workbench.view.explorer")
|
||||
bar extensions: user.vscode("workbench.view.extensions")
|
||||
bar outline: user.vscode("outline.focus")
|
||||
bar run: user.vscode("workbench.view.debug")
|
||||
bar search: user.vscode("workbench.view.search")
|
||||
bar source: user.vscode("workbench.view.scm")
|
||||
bar test: user.vscode("workbench.view.testing.focus")
|
||||
bar switch: user.vscode("workbench.action.toggleSidebarVisibility")
|
||||
|
||||
# Symbol search
|
||||
symbol hunt [<user.text>]:
|
||||
user.vscode("workbench.action.gotoSymbol")
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
|
||||
symbol hunt all [<user.text>]:
|
||||
user.vscode("workbench.action.showAllSymbols")
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
|
||||
# Panels
|
||||
panel control: user.vscode("workbench.panel.repl.view.focus")
|
||||
panel output: user.vscode("workbench.panel.output.focus")
|
||||
panel problems: user.vscode("workbench.panel.markers.view.focus")
|
||||
panel switch: user.vscode("workbench.action.togglePanel")
|
||||
panel terminal: user.vscode("workbench.action.terminal.focus")
|
||||
focus editor: user.vscode("workbench.action.focusActiveEditorGroup")
|
||||
|
||||
# Settings
|
||||
show settings: user.vscode("workbench.action.openGlobalSettings")
|
||||
show settings json: user.vscode("workbench.action.openSettingsJson")
|
||||
show settings folder: user.vscode("workbench.action.openFolderSettings")
|
||||
show settings folder json: user.vscode("workbench.action.openFolderSettingsFile")
|
||||
show settings workspace: user.vscode("workbench.action.openWorkspaceSettings")
|
||||
show settings workspace json: user.vscode("workbench.action.openWorkspaceSettingsFile")
|
||||
show shortcuts: user.vscode("workbench.action.openGlobalKeybindings")
|
||||
show shortcuts json: user.vscode("workbench.action.openGlobalKeybindingsFile")
|
||||
show snippets: user.vscode("workbench.action.openSnippets")
|
||||
|
||||
# VSCode Snippets
|
||||
snip (last | previous): user.vscode("jumpToPrevSnippetPlaceholder")
|
||||
|
||||
# Display
|
||||
centered switch: user.vscode("workbench.action.toggleCenteredLayout")
|
||||
fullscreen switch: user.vscode("workbench.action.toggleFullScreen")
|
||||
theme switch: user.vscode("workbench.action.selectTheme")
|
||||
wrap switch: user.vscode("editor.action.toggleWordWrap")
|
||||
zen switch: user.vscode("workbench.action.toggleZenMode")
|
||||
|
||||
# File Commands
|
||||
file hunt [<user.text>]:
|
||||
user.vscode("workbench.action.quickOpen")
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
file hunt (pace | paste):
|
||||
user.vscode("workbench.action.quickOpen")
|
||||
sleep(50ms)
|
||||
edit.paste()
|
||||
file copy name: user.vscode("fileutils.copyFileName")
|
||||
file copy path: user.vscode("copyFilePath")
|
||||
file copy local [path]: user.vscode("copyRelativeFilePath")
|
||||
file create sibling: user.vscode_and_wait("explorer.newFile")
|
||||
file create: user.vscode("workbench.action.files.newUntitledFile")
|
||||
file create relative: user.vscode("fileutils.newFile")
|
||||
file create root: user.vscode("fileutils.newFileAtRoot")
|
||||
file rename:
|
||||
user.vscode("fileutils.renameFile")
|
||||
sleep(150ms)
|
||||
file move:
|
||||
user.vscode("fileutils.moveFile")
|
||||
sleep(150ms)
|
||||
file clone:
|
||||
user.vscode("fileutils.duplicateFile")
|
||||
sleep(150ms)
|
||||
file delete:
|
||||
user.vscode("fileutils.removeFile")
|
||||
sleep(150ms)
|
||||
file open folder: user.vscode("revealFileInOS")
|
||||
file reveal: user.vscode("workbench.files.action.showActiveFileInExplorer")
|
||||
save ugly: user.vscode("workbench.action.files.saveWithoutFormatting")
|
||||
|
||||
# Language Features
|
||||
suggest show: user.vscode("editor.action.triggerSuggest")
|
||||
hint show: user.vscode("editor.action.triggerParameterHints")
|
||||
definition show: user.vscode("editor.action.revealDefinition")
|
||||
definition peek: user.vscode("editor.action.peekDefinition")
|
||||
definition side: user.vscode("editor.action.revealDefinitionAside")
|
||||
references show: user.vscode("editor.action.goToReferences")
|
||||
hierarchy peek: user.vscode("editor.showCallHierarchy")
|
||||
references find: user.vscode("references-view.find")
|
||||
format that: user.vscode("editor.action.formatDocument")
|
||||
format selection: user.vscode("editor.action.formatSelection")
|
||||
imports fix: user.vscode("editor.action.organizeImports")
|
||||
problem next: user.vscode("editor.action.marker.nextInFiles")
|
||||
problem last: user.vscode("editor.action.marker.prevInFiles")
|
||||
problem fix: user.vscode("problems.action.showQuickFixes")
|
||||
rename that: user.vscode("editor.action.rename")
|
||||
refactor that: user.vscode("editor.action.refactor")
|
||||
whitespace trim: user.vscode("editor.action.trimTrailingWhitespace")
|
||||
language switch: user.vscode("workbench.action.editor.changeLanguageMode")
|
||||
refactor rename: user.vscode("editor.action.rename")
|
||||
refactor this: user.vscode("editor.action.refactor")
|
||||
|
||||
#code navigation
|
||||
(go declaration | follow): user.vscode("editor.action.revealDefinition")
|
||||
go back: user.vscode("workbench.action.navigateBack")
|
||||
go forward: user.vscode("workbench.action.navigateForward")
|
||||
go implementation: user.vscode("editor.action.goToImplementation")
|
||||
go type: user.vscode("editor.action.goToTypeDefinition")
|
||||
go usage: user.vscode("references-view.find")
|
||||
go recent [<user.text>]:
|
||||
user.vscode("workbench.action.openRecent")
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
sleep(250ms)
|
||||
go edit: user.vscode("workbench.action.navigateToLastEditLocation")
|
||||
|
||||
# Bookmarks. Requires Bookmarks plugin
|
||||
bar marks: user.vscode("workbench.view.extension.bookmarks")
|
||||
go marks:
|
||||
user.deprecate_command("2023-06-06", "go marks", "bar marks")
|
||||
user.vscode("workbench.view.extension.bookmarks")
|
||||
toggle mark: user.vscode("bookmarks.toggle")
|
||||
go next mark: user.vscode("bookmarks.jumpToNext")
|
||||
go last mark: user.vscode("bookmarks.jumpToPrevious")
|
||||
|
||||
close other tabs: user.vscode("workbench.action.closeOtherEditors")
|
||||
close all tabs: user.vscode("workbench.action.closeAllEditors")
|
||||
close tabs way right: user.vscode("workbench.action.closeEditorsToTheRight")
|
||||
close tabs way left: user.vscode("workbench.action.closeEditorsToTheLeft")
|
||||
|
||||
# Folding
|
||||
fold that: user.vscode("editor.fold")
|
||||
unfold that: user.vscode("editor.unfold")
|
||||
fold those: user.vscode("editor.foldAllMarkerRegions")
|
||||
unfold those: user.vscode("editor.unfoldRecursively")
|
||||
fold all: user.vscode("editor.foldAll")
|
||||
unfold all: user.vscode("editor.unfoldAll")
|
||||
fold comments: user.vscode("editor.foldAllBlockComments")
|
||||
fold one: user.vscode("editor.foldLevel1")
|
||||
fold two: user.vscode("editor.foldLevel2")
|
||||
fold three: user.vscode("editor.foldLevel3")
|
||||
fold four: user.vscode("editor.foldLevel4")
|
||||
fold five: user.vscode("editor.foldLevel5")
|
||||
fold six: user.vscode("editor.foldLevel6")
|
||||
fold seven: user.vscode("editor.foldLevel7")
|
||||
|
||||
# Git / Github (not using verb-noun-adjective pattern, mirroring terminal commands.)
|
||||
git branch: user.vscode("git.branchFrom")
|
||||
git branch this: user.vscode("git.branch")
|
||||
git checkout [<user.text>]:
|
||||
user.vscode("git.checkout")
|
||||
sleep(50ms)
|
||||
insert(text or "")
|
||||
git commit [<user.text>]:
|
||||
user.vscode("git.commitStaged")
|
||||
sleep(100ms)
|
||||
user.insert_formatted(text or "", "CAPITALIZE_FIRST_WORD")
|
||||
git commit undo: user.vscode("git.undoCommit")
|
||||
git commit amend: user.vscode("git.commitStagedAmend")
|
||||
git diff: user.vscode("git.openChange")
|
||||
git fetch: user.vscode("git.fetch")
|
||||
git fetch all: user.vscode("git.fetchAll")
|
||||
git ignore: user.vscode("git.ignore")
|
||||
git merge: user.vscode("git.merge")
|
||||
git output: user.vscode("git.showOutput")
|
||||
git pull: user.vscode("git.pullRebase")
|
||||
git push: user.vscode("git.push")
|
||||
git push force: user.vscode("git.pushForce")
|
||||
git rebase abort: user.vscode("git.rebaseAbort")
|
||||
git reveal: user.vscode("git.revealInExplorer")
|
||||
git revert: user.vscode("git.revertChange")
|
||||
git stash: user.vscode("git.stash")
|
||||
git stash pop: user.vscode("git.stashPop")
|
||||
git status: user.vscode("workbench.scm.focus")
|
||||
git stage: user.vscode("git.stage")
|
||||
git stage all: user.vscode("git.stageAll")
|
||||
git sync: user.vscode("git.sync")
|
||||
git unstage: user.vscode("git.unstage")
|
||||
git unstage all: user.vscode("git.unstageAll")
|
||||
pull request: user.vscode("pr.create")
|
||||
# Use keyboard shortcuts because VSCode relies on when clause contexts to choose the appropriate
|
||||
# action: https://code.visualstudio.com/api/references/when-clause-contexts
|
||||
change next: key(alt-f5)
|
||||
change last: key(shift-alt-f5)
|
||||
|
||||
# Testing
|
||||
test run: user.vscode("testing.runAtCursor")
|
||||
test run file: user.vscode("testing.runCurrentFile")
|
||||
test run all: user.vscode("testing.runAll")
|
||||
test run failed: user.vscode("testing.reRunFailTests")
|
||||
test run last: user.vscode("testing.reRunLastRun")
|
||||
|
||||
test debug: user.vscode("testing.debugAtCursor")
|
||||
test debug file: user.vscode("testing.debugCurrentFile")
|
||||
test debug all: user.vscode("testing.debugAll")
|
||||
test debug failed: user.vscode("testing.debugFailTests")
|
||||
test debug last: user.vscode("testing.debugLastRun")
|
||||
|
||||
test cancel: user.vscode("testing.cancelRun")
|
||||
|
||||
# Debugging
|
||||
break point: user.vscode("editor.debug.action.toggleBreakpoint")
|
||||
step over: user.vscode("workbench.action.debug.stepOver")
|
||||
debug step into: user.vscode("workbench.action.debug.stepInto")
|
||||
debug step out [of]: user.vscode("workbench.action.debug.stepOut")
|
||||
debug start: user.vscode("workbench.action.debug.start")
|
||||
debug pause: user.vscode("workbench.action.debug.pause")
|
||||
debug stopper: user.vscode("workbench.action.debug.stop")
|
||||
debug continue: user.vscode("workbench.action.debug.continue")
|
||||
debug restart: user.vscode("workbench.action.debug.restart")
|
||||
debug console: user.vscode("workbench.debug.action.toggleRepl")
|
||||
debug clean: user.vscode("workbench.debug.panel.action.clearReplAction")
|
||||
|
||||
# Terminal
|
||||
terminal external: user.vscode("workbench.action.terminal.openNativeConsole")
|
||||
terminal new: user.vscode("workbench.action.terminal.new")
|
||||
terminal next: user.vscode("workbench.action.terminal.focusNext")
|
||||
terminal last: user.vscode("workbench.action.terminal.focusPrevious")
|
||||
terminal split: user.vscode("workbench.action.terminal.split")
|
||||
terminal zoom: user.vscode("workbench.action.toggleMaximizedPanel")
|
||||
terminal trash: user.vscode("workbench.action.terminal.kill")
|
||||
terminal toggle: user.vscode_and_wait("workbench.action.terminal.toggleTerminal")
|
||||
terminal scroll up: user.vscode("workbench.action.terminal.scrollUp")
|
||||
terminal scroll down: user.vscode("workbench.action.terminal.scrollDown")
|
||||
terminal <number_small>: user.vscode_terminal(number_small)
|
||||
|
||||
task run [<user.text>]:
|
||||
user.vscode("workbench.action.tasks.runTask")
|
||||
insert(user.text or "")
|
||||
#TODO: should this be added to linecommands?
|
||||
copy line down: user.vscode("editor.action.copyLinesDownAction")
|
||||
copy line up: user.vscode("editor.action.copyLinesUpAction")
|
||||
|
||||
#Expand/Shrink AST Selection
|
||||
select less: user.vscode("editor.action.smartSelect.shrink")
|
||||
select (more | this): user.vscode("editor.action.smartSelect.expand")
|
||||
|
||||
minimap: user.vscode("editor.action.toggleMinimap")
|
||||
maximize: user.vscode("workbench.action.minimizeOtherEditors")
|
||||
restore: user.vscode("workbench.action.evenEditorWidths")
|
||||
|
||||
#breadcrumb
|
||||
select breadcrumb: user.vscode("breadcrumbs.focusAndSelect")
|
||||
# Use `alt-left` and `alt-right` to navigate the bread crumb
|
||||
|
||||
replace here:
|
||||
user.replace("")
|
||||
key(cmd-alt-l)
|
||||
|
||||
hover show: user.vscode("editor.action.showHover")
|
||||
|
||||
join lines: user.vscode("editor.action.joinLines")
|
||||
|
||||
full screen: user.vscode("workbench.action.toggleFullScreen")
|
||||
|
||||
curse undo: user.vscode("cursorUndo")
|
||||
curse redo: user.vscode("cursorRedo")
|
||||
|
||||
select word: user.vscode("editor.action.addSelectionToNextFindMatch")
|
||||
skip word: user.vscode("editor.action.moveSelectionToNextFindMatch")
|
||||
|
||||
# jupyter
|
||||
cell next: user.vscode("notebook.focusNextEditor")
|
||||
cell last: user.vscode("notebook.focusPreviousEditor")
|
||||
cell run above: user.vscode("notebook.cell.executeCellsAbove")
|
||||
cell run: user.vscode("notebook.cell.execute")
|
||||
|
||||
install local: user.vscode("workbench.extensions.action.installVSIX")
|
||||
preview markdown: user.vscode("markdown.showPreview")
|
||||
@@ -0,0 +1,107 @@
|
||||
from typing import Any
|
||||
|
||||
from talon import Context, Module, actions
|
||||
|
||||
from ...core.command_client.command_client import NotSet, run_command
|
||||
from ...core.command_client.rpc_client.types import NoFileServerException
|
||||
|
||||
mod = Module()
|
||||
|
||||
ctx = Context()
|
||||
linux_ctx = Context()
|
||||
|
||||
ctx.matches = r"""
|
||||
app: vscode
|
||||
"""
|
||||
linux_ctx.matches = r"""
|
||||
os: linux
|
||||
app: vscode
|
||||
"""
|
||||
|
||||
ctx.tags = ["user.command_client"]
|
||||
|
||||
|
||||
def command_server_or_client_fallback(command_id: str, wait: bool):
|
||||
"""Execute command via command server, falling back to command palette if directory not present."""
|
||||
try:
|
||||
run_command(command_id, wait_for_finish=wait)
|
||||
except NoFileServerException:
|
||||
actions.user.command_palette()
|
||||
actions.user.paste(command_id)
|
||||
actions.key("enter")
|
||||
print(
|
||||
"Command server directory not found; falling back to command palette. For better performance, install the VSCode extension for Talon: https://marketplace.visualstudio.com/items?itemName=pokey.talon"
|
||||
)
|
||||
|
||||
|
||||
@ctx.action_class("user")
|
||||
class VsCodeAction:
|
||||
def command_server_directory() -> str:
|
||||
return "vscode-command-server"
|
||||
|
||||
|
||||
@mod.action_class
|
||||
class Actions:
|
||||
def vscode(command_id: str):
|
||||
"""Execute command via vscode command server, if available, or fallback
|
||||
to command palette."""
|
||||
command_server_or_client_fallback(command_id, False)
|
||||
|
||||
def vscode_and_wait(command_id: str):
|
||||
"""Execute command via vscode command server, if available, and wait
|
||||
for command to finish. If command server not available, uses command
|
||||
palette and doesn't guarantee that it will wait for command to
|
||||
finish."""
|
||||
command_server_or_client_fallback(command_id, True)
|
||||
|
||||
# These commands are shims, to provide backwards compatibility, they may be removed in the fuuture.
|
||||
# Prefer the run_command... version in command_client.
|
||||
def vscode_with_plugin(
|
||||
command_id: str,
|
||||
arg1: Any = NotSet,
|
||||
arg2: Any = NotSet,
|
||||
arg3: Any = NotSet,
|
||||
arg4: Any = NotSet,
|
||||
arg5: Any = NotSet,
|
||||
):
|
||||
"""Execute command via vscode command server."""
|
||||
actions.user.run_rpc_command(
|
||||
command_id,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
arg4,
|
||||
arg5,
|
||||
)
|
||||
|
||||
def vscode_with_plugin_and_wait(
|
||||
command_id: str,
|
||||
arg1: Any = NotSet,
|
||||
arg2: Any = NotSet,
|
||||
arg3: Any = NotSet,
|
||||
arg4: Any = NotSet,
|
||||
arg5: Any = NotSet,
|
||||
):
|
||||
"""Execute command via vscode command server and wait for command to finish."""
|
||||
actions.user.run_rpc_command_and_wait(command_id, arg1, arg2, arg3, arg4, arg5)
|
||||
|
||||
def vscode_get(
|
||||
command_id: str,
|
||||
arg1: Any = NotSet,
|
||||
arg2: Any = NotSet,
|
||||
arg3: Any = NotSet,
|
||||
arg4: Any = NotSet,
|
||||
arg5: Any = NotSet,
|
||||
) -> Any:
|
||||
"""Execute command via vscode command server and return command output."""
|
||||
return actions.user.run_rpc_command_get(
|
||||
command_id, arg1, arg2, arg3, arg4, arg5
|
||||
)
|
||||
|
||||
|
||||
@linux_ctx.action_class("user")
|
||||
class LinuxUserActions:
|
||||
def trigger_command_server_command_execution():
|
||||
# Work around bug with upper f-keys in VSCode on Linux. See
|
||||
# https://github.com/pokey/command-server/issues/9#issuecomment-963733930
|
||||
actions.key("ctrl-shift-alt-p")
|
||||
@@ -0,0 +1,7 @@
|
||||
app: vscode
|
||||
# Looks for special string in window title.
|
||||
# NOTE: This requires you to add a special setting to your VSCode settings.json
|
||||
# See [our vscode docs](./README.md#terminal)
|
||||
win.title: /focus:\[Terminal\]/
|
||||
-
|
||||
tag(): terminal
|
||||
Reference in New Issue
Block a user