| name | talon-development |
| description | Expert guidance for Talon voice control development. Use when creating voice commands, defining actions, writing .talon files, testing Talon config, or debugging Talon issues. |
Talon Development Guide
This skill provides guidance for developing Talon voice control configurations.
Improving This Skill
When you discover new Talon patterns, best practices, or learn something not covered here, update this skill:
- Add new patterns or examples to the relevant section
- Correct any outdated information
- Add new sections for uncovered topics
- Update TESTING.md with new testing techniques
The goal is for this skill to grow into a comprehensive local reference.
Key Resources
Talon Code Search
Search across hundreds of Talon repositories for real-world examples:
https://search.talonvoice.com/api/v1/search/?q=<query>&fold_case=auto®ex=false
Returns JSON with matching code snippets and file locations. Use this to find how others implement patterns.
Set regex=true to use RE2 regex patterns in the query (e.g., q=cron\.(after|interval)).
Reference Repositories
Look up patterns and examples in these repositories. Code in active repositories is more reliable than potentially outdated documentation.
| Repository | Purpose |
|---|---|
| talonhub/community | Main community voice command set. The standard reference for Talon patterns. |
| cursorless-dev/cursorless | Voice-controlled structural code editing. Advanced Talon integration example. |
Documentation
| Resource | Notes |
|---|---|
| talonvoice.com/docs | Official API documentation. Covers Module, Context, actions, captures, settings. |
| talon.wiki | Community wiki. Good for getting started, hardware recommendations. |
Note: Online documentation may be outdated. When in doubt, check actual code in repositories or use the code search.
Testing
See TESTING.md for command-line testing instructions, including:
- Using
test_talon.sh - Testing actions with
cron.after() - Test code templates and patterns
- Debugging failed tests
Programmatic Access
See PROGRAMMATIC_ACCESS.md for interacting with a running Talon instance:
- Why direct REPL access isn't available
- Write-and-reload pattern for executing code
- File-based RPC (VSCode integration)
Eye Tracking
See settings/eye_tracking_api.md for the eye tracking API reference.
Project Structure
user/ # Talon user directory
├── apps/ # App-specific commands
│ ├── generic/ # Cross-app abstractions (code_editor, browser)
│ └── [app].py/.talon # App-specific implementations
├── misc/ # General utilities and commands
├── plugins/ # Reusable plugins (vimfinity, etc.)
├── settings/ # Talon settings files
├── utils/ # Python utility modules
└── test_talon.sh # Testing script
File Types
.talon Files (Voice Commands)
Define voice commands and their actions:
# Context header (optional - restricts when commands are active)
app: vscode
-
# Commands below the dash
hello world: insert("Hello, World!")
go to definition: user.find_definition()
search <user.text>: user.search(text)
Context examples:
# Match by app
app: vscode
-
# Match by tag
tag: user.code_editor
-
# Match by OS
os: windows
-
# Multiple conditions (AND)
app: vscode
mode: command
-
.py Files (Actions and Logic)
Define actions, modules, contexts, and complex logic:
from talon import Module, Context, actions
module = Module()
# Define a tag that can be enabled/disabled
module.tag("code_editor", desc="Active in code editors")
# Define actions
@module.action_class
class Actions:
def my_action(arg: str) -> str:
"""Action docstring - shown in help."""
return f"Result: {arg}"
Common Patterns
Module + Context Pattern
Used to define abstract actions with app-specific implementations:
# In apps/generic/code_editor.py
from talon import Module, Context, actions
module = Module()
module.tag("code_editor", desc="Active in code editors")
@module.action_class
class Actions:
def find_definition() -> None:
"""Navigate to definition."""
pass # Abstract - no default implementation
# In apps/vscode.py
from talon import Context, actions
ctx = Context()
ctx.matches = r"""
app: vscode
"""
# Enable the tag when VSCode is active
ctx.tags = ["user.code_editor"]
@ctx.action_class("user")
class UserActions:
def find_definition():
actions.key("f12") # VSCode-specific implementation
Lists and Captures
module = Module()
# Define a list
module.list("browsers", desc="Web browsers")
ctx = Context()
ctx.lists["user.browsers"] = {
"chrome": "chrome",
"firefox": "firefox",
"edge": "msedge",
}
# Use in .talon:
# open <user.browsers>: user.open_app(browsers)
Settings
from talon import Module, settings
module = Module()
module.setting(
"my_timeout",
type=int,
default=5000,
desc="Timeout in milliseconds",
)
# Use it:
timeout = settings.get("user.my_timeout")
Import Patterns
# Standard Talon imports
from talon import Module, Context, actions, settings, app, clip, cron, ctrl
# For UI automation
from talon import ui
# For key simulation
actions.key("ctrl-c")
actions.insert("text")
# Internal Talon plugins (fragile - use local imports)
def my_action():
from talon_plugins import menu
menu.open_repl(None)
Quick Reference
Common Actions
actions.key("ctrl-c") # Press keys
actions.insert("text") # Type text
actions.edit.copy() # Standard edit actions
actions.user.my_action() # User-defined actions
actions.app.path() # Get current file path
Common Talon Syntax
# Simple command
hello: insert("world")
# With capture
say <phrase>: insert(phrase)
# With list
open <user.apps>: user.open_app(apps)
# Optional words
[please] save: edit.save()
# Alternative words
(quit | exit): app.quit()
# Repeater
press enter <number> times: key("enter:number")
Best Practices
Do
- Keep voice commands short and memorable
- Use abstract actions in
generic/with app-specific overrides - Group related commands in the same file
- Add docstrings to all actions
- Test changes before committing
- Use tags to control command availability
- Search talonhub/community for examples before inventing patterns
Don't
- Put complex logic in
.talonfiles (use Python) - Create overlapping voice commands
- Forget to remove test code
- Use blocking operations without
cron - Hardcode app-specific keys in generic actions
- Trust potentially outdated documentation over working code
File Locations by Purpose
| Purpose | Location |
|---|---|
| App-specific commands | apps/[app].py + apps/[app].talon |
| Cross-app abstractions | apps/generic/ |
| General utilities | misc/ |
| Reusable plugins | plugins/ |
| Utility Python modules | utils/ |
| Settings | settings/ |