Skip to content

Support insertSnippet action #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions cursorless-snippets/functionDeclaration.cursorless-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"functionDeclaration": {
"definitions": [
{
"scope": {
"langIds": [
"typescript",
"typescriptreact",
"javascript",
"javascriptreact"
]
},
"body": [
"function $name($parameterList) {",
"\t$body",
"}"
],
"variables": {
"name": {
"formatter": "camelCase"
}
}
},
{
"scope": {
"langIds": [
"python"
]
},
"body": [
"def $name($parameterList):",
"\t$body"
],
"variables": {
"name": {
"formatter": "snakeCase"
}
}
}
],
"description": "Function declaration",
"variables": {
"body": {
"wrapperScopeType": "statement"
}
},
"insertionScopeTypes": [
"namedFunction",
"statement",
"line"
]
}
}
5 changes: 4 additions & 1 deletion cursorless-snippets/ifElseStatement.cursorless-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
"alternative": {
"wrapperScopeType": "statement"
}
}
},
"insertionScopeTypes": [
"statement"
]
}
}
5 changes: 4 additions & 1 deletion cursorless-snippets/ifStatement.cursorless-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"consequence": {
"wrapperScopeType": "statement"
}
}
},
"insertionScopeTypes": [
"statement"
]
}
}
5 changes: 4 additions & 1 deletion cursorless-snippets/tryCatchStatement.cursorless-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
"exceptBody": {
"wrapperScopeType": "statement"
}
}
},
"insertionScopeTypes": [
"statement"
]
}
}
1 change: 1 addition & 0 deletions cursorless-talon/src/actions/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def vscode_command_no_wait(command_id: str, target: dict, command_options: dict
"swap_action": {"swap": "swapTargets"},
"move_bring_action": {"bring": "replaceWithTarget", "move": "moveToTarget"},
"wrap_action": {"wrap": "wrapWithPairedDelimiter", "repack": "rewrap"},
"insert_snippet_action": {"snippet": "insertSnippet"},
"reformat_action": {"format": "applyFormatter"},
}

Expand Down
40 changes: 1 addition & 39 deletions cursorless-talon/src/actions/wrap.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
from typing import Any

from talon import Context, Module, actions, app
from talon import Module, actions

from ..csv_overrides import init_csv_and_watch_changes
from ..paired_delimiter import paired_delimiters_map

mod = Module()

mod.tag(
"cursorless_experimental_snippets",
desc="tag for enabling experimental snippet support",
)

mod.list("cursorless_wrap_action", desc="Cursorless wrap action")
mod.list("cursorless_wrapper_snippet", desc="Cursorless wrapper snippet")

experimental_snippets_ctx = Context()
experimental_snippets_ctx.matches = r"""
tag: user.cursorless_experimental_snippets
"""


# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
wrapper_snippets = {
"else": "ifElseStatement.alternative",
"if else": "ifElseStatement.consequence",
"if": "ifStatement.consequence",
"try": "tryCatchStatement.body",
"link": "link.text",
}


@mod.capture(
Expand Down Expand Up @@ -72,18 +49,3 @@ def cursorless_wrap(action_type: str, targets: dict, cursorless_wrapper: dict):
actions.user.cursorless_single_target_command_with_arg_list(
action, targets, cursorless_wrapper["extra_args"]
)


def on_ready():
init_csv_and_watch_changes(
"experimental/wrapper_snippets",
{
"wrapper_snippet": wrapper_snippets,
},
allow_unknown_values=True,
default_list_name="wrapper_snippet",
ctx=experimental_snippets_ctx,
)


app.register("ready", on_ready)
37 changes: 20 additions & 17 deletions cursorless-talon/src/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from talon import Module, actions, speech_system

from .primitive_target import IMPLICIT_TARGET

mod = Module()

last_phrase = None
Expand Down Expand Up @@ -47,17 +49,7 @@ def cursorless_single_target_command_no_wait(
)

def cursorless_single_target_command_with_arg_list(
action: str, target: str, args: list[Any]
):
"""Execute single-target cursorless command with argument list"""
actions.user.cursorless_single_target_command(
action,
target,
*args,
)

def cursorless_single_target_command_with_arg_list(
action: str, target: str, args: list[Any]
action: str, target: dict, args: list[Any]
):
"""Execute single-target cursorless command with argument list"""
actions.user.cursorless_single_target_command(
Expand All @@ -83,12 +75,23 @@ def cursorless_single_target_command_get(
),
)

def cursorless_implicit_target_command(
action: str,
arg1: Any = NotSet,
arg2: Any = NotSet,
arg3: Any = NotSet,
):
"""Execute cursorless command with implicit target"""
actions.user.cursorless_single_target_command(
action, IMPLICIT_TARGET, arg1, arg2, arg3
)

def cursorless_multiple_target_command(
action: str,
targets: list[dict],
arg1: any = NotSet,
arg2: any = NotSet,
arg3: any = NotSet,
arg1: Any = NotSet,
arg2: Any = NotSet,
arg3: Any = NotSet,
):
"""Execute multi-target cursorless command"""
actions.user.vscode_with_plugin_and_wait(
Expand All @@ -103,9 +106,9 @@ def cursorless_multiple_target_command(
def cursorless_multiple_target_command_no_wait(
action: str,
targets: list[dict],
arg1: any = NotSet,
arg2: any = NotSet,
arg3: any = NotSet,
arg1: Any = NotSet,
arg2: Any = NotSet,
arg3: Any = NotSet,
):
"""Execute multi-target cursorless command"""
actions.user.vscode_with_plugin(
Expand Down
12 changes: 12 additions & 0 deletions cursorless-talon/src/cursorless-snippets.talon
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
app: vscode
tag: user.cursorless_experimental_snippets
-

{user.cursorless_insert_snippet_action} <user.cursorless_insertion_snippet>:
user.cursorless_implicit_target_command(cursorless_insert_snippet_action, cursorless_insertion_snippet)

{user.cursorless_insert_snippet_action} <user.cursorless_insertion_snippet> <user.cursorless_positional_target>:
user.cursorless_single_target_command(cursorless_insert_snippet_action, cursorless_positional_target, cursorless_insertion_snippet)

{user.cursorless_insert_snippet_action} {user.cursorless_insertion_snippet_single_phrase} <user.text> [{user.cursorless_phrase_terminator}]:
user.cursorless_insert_snippet_with_phrase(cursorless_insert_snippet_action, cursorless_insertion_snippet_single_phrase, text)
119 changes: 119 additions & 0 deletions cursorless-talon/src/snippets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from talon import Context, Module, actions, app

from .csv_overrides import init_csv_and_watch_changes

mod = Module()
mod.list("cursorless_insert_snippet_action", desc="Cursorless insert snippet action")

mod.tag(
"cursorless_experimental_snippets",
desc="tag for enabling experimental snippet support",
)

mod.list("cursorless_wrapper_snippet", desc="Cursorless wrapper snippet")
mod.list(
"cursorless_insertion_snippet_no_phrase",
desc="Cursorless insertion snippets that don't accept a phrase",
)
mod.list(
"cursorless_insertion_snippet_single_phrase",
desc="Cursorless insertion snippet that can accept a single phrase",
)
mod.list("cursorless_phrase_terminator", "Contains term used to terminate a phrase")


@mod.capture(
rule="{user.cursorless_insertion_snippet_no_phrase} | {user.cursorless_insertion_snippet_single_phrase}"
)
def cursorless_insertion_snippet(m) -> str:
try:
return m.cursorless_insertion_snippet_no_phrase
except AttributeError:
pass

return m.cursorless_insertion_snippet_single_phrase.split(".")[0]


experimental_snippets_ctx = Context()
experimental_snippets_ctx.matches = r"""
tag: user.cursorless_experimental_snippets
"""


# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
wrapper_snippets = {
"else": "ifElseStatement.alternative",
"funk": "functionDeclaration.body",
"if else": "ifElseStatement.consequence",
"if": "ifStatement.consequence",
"try": "tryCatchStatement.body",
"link": "link.text",
}

# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
insertion_snippets_no_phrase = {
"if": "ifStatement",
"if else": "ifElseStatement",
"try": "tryCatchStatement",
}

# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
insertion_snippets_single_phrase = {
"funk": "functionDeclaration.name",
"link": "link.text",
}


@mod.action_class
class Actions:
def cursorless_insert_snippet_with_phrase(
action: str, snippet_description: str, text: str
):
"""Perform cursorless wrap action"""
snippet_name, snippet_variable = snippet_description.split(".")
actions.user.cursorless_implicit_target_command(
action, snippet_name, {snippet_variable: text}
)


def on_ready():
init_csv_and_watch_changes(
"experimental/wrapper_snippets",
{
"wrapper_snippet": wrapper_snippets,
},
allow_unknown_values=True,
default_list_name="wrapper_snippet",
ctx=experimental_snippets_ctx,
)
init_csv_and_watch_changes(
"experimental/insertion_snippets",
{
"insertion_snippet_no_phrase": insertion_snippets_no_phrase,
},
allow_unknown_values=True,
default_list_name="insertion_snippet_no_phrase",
ctx=experimental_snippets_ctx,
)
init_csv_and_watch_changes(
"experimental/insertion_snippets_single_phrase",
{
"insertion_snippet_single_phrase": insertion_snippets_single_phrase,
},
allow_unknown_values=True,
default_list_name="insertion_snippet_single_phrase",
ctx=experimental_snippets_ctx,
)
init_csv_and_watch_changes(
"experimental/miscellaneous",
{
"phrase_terminator": {"over": "phraseTerminator"},
},
ctx=experimental_snippets_ctx,
)


app.register("ready", on_ready)
4 changes: 2 additions & 2 deletions docs/user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,9 @@ The rewrap command, mapped to `"repack"` by default, can be used to swap a given

See [paired delimiters](#paired-delimiters) for a list of possible wrappers.

#### \[experimental\] Wrap with snippet
### \[experimental\] Snippets

See [experimental documentation](experimental/wrapper-snippets.md).
See [experimental documentation](experimental/snippets.md).

### Show definition/reference/quick fix

Expand Down
Loading