diff --git a/cursorless-talon-dev/src/cursorless_test.talon b/cursorless-talon-dev/src/cursorless_test.talon index 55e0c3fd04..e7a4c00c59 100644 --- a/cursorless-talon-dev/src/cursorless_test.talon +++ b/cursorless-talon-dev/src/cursorless_test.talon @@ -7,10 +7,20 @@ test api command : user.cursorless_command("setSelection", cursorless_target) test api command bring : user.cursorless_command("replaceWithTarget", cursorless_target) +test api get text : + user.cursorless_get_text(cursorless_target) +test api get text list on : + user.cursorless_get_text_list(cursorless_target) +test api get text hide decorations : + user.cursorless_get_text(cursorless_target, true) +test api get text hide decorations list on : + user.cursorless_get_text_list(cursorless_target, true) + test api insert : user.cursorless_insert(cursorless_destination, word) test api insert and : user.cursorless_insert(cursorless_destination, word_list) + test api insert snippet: user.cursorless_insert_snippet("Hello, $foo! My name is $bar!") test api insert snippet : diff --git a/cursorless-talon/src/actions/get_text.py b/cursorless-talon/src/actions/get_text.py index 8ee8849da8..e95f35de90 100644 --- a/cursorless-talon/src/actions/get_text.py +++ b/cursorless-talon/src/actions/get_text.py @@ -1,9 +1,36 @@ from typing import Optional -from talon import actions +from talon import Module, actions from ..targets.target_types import CursorlessTarget +mod = Module() + + +@mod.action_class +class Actions: + def cursorless_get_text( + target: CursorlessTarget, + hide_decorations: bool = False, + ) -> str: + """Get target text. If hide_decorations is True, don't show decorations""" + return cursorless_get_text_action( + target, + show_decorations=not hide_decorations, + ensure_single_target=True, + )[0] + + def cursorless_get_text_list( + target: CursorlessTarget, + hide_decorations: bool = False, + ) -> list[str]: + """Get texts for multiple targets. If hide_decorations is True, don't show decorations""" + return cursorless_get_text_action( + target, + show_decorations=not hide_decorations, + ensure_single_target=False, + ) + def cursorless_get_text_action( target: CursorlessTarget, diff --git a/docs/user/customization.md b/docs/user/customization.md index 06913dd5eb..c9039286d7 100644 --- a/docs/user/customization.md +++ b/docs/user/customization.md @@ -117,6 +117,10 @@ Cursorless exposes a couple talon actions and captures that you can use to defin - `user.cursorless_ide_command(command_id: str, target: cursorless_target)`: Performs a built-in IDE command on the given target eg: `user.cursorless_ide_command("editor.action.addCommentLine", cursorless_target)` +- `user.cursorless_get_text(target: CursorlessTarget, hide_decorations: bool = False) -> str` + Get text from target. If `hide_decorations` is `true`, will not show decorations. +- `user.cursorless_get_text_list(target: CursorlessTarget, hide_decorations: bool = False) -> list[str]` + Get texts from multiple targets. If `hide_decorations` is `true`, will not show decorations. - `user.cursorless_insert(destination: CursorlessDestination, text: Union[str, List[str]])`: Insert text at destination. eg: `user.cursorless_insert(cursorless_destination, "hello")` diff --git a/packages/cursorless-engine/src/test/fixtures/spokenFormTest.ts b/packages/cursorless-engine/src/test/fixtures/spokenFormTest.ts index ac048ed91e..8251ddf13b 100644 --- a/packages/cursorless-engine/src/test/fixtures/spokenFormTest.ts +++ b/packages/cursorless-engine/src/test/fixtures/spokenFormTest.ts @@ -24,10 +24,11 @@ export interface SpokenFormTest { export function spokenFormTest( spokenForm: string, action: ActionDescriptor, + mockedGetValue?: unknown, ): SpokenFormTest { return { spokenForm, - mockedGetValue: undefined, + mockedGetValue, commands: [command(spokenForm, action)], }; } diff --git a/packages/cursorless-engine/src/test/fixtures/talonApi.fixture.ts b/packages/cursorless-engine/src/test/fixtures/talonApi.fixture.ts index 956fb52739..2fbb8a1b89 100644 --- a/packages/cursorless-engine/src/test/fixtures/talonApi.fixture.ts +++ b/packages/cursorless-engine/src/test/fixtures/talonApi.fixture.ts @@ -1,5 +1,6 @@ import { ActionDescriptor, + GetTextActionOptions, PartialPrimitiveTargetDescriptor, } from "@cursorless/common"; import { spokenFormTest } from "./spokenFormTest"; @@ -135,6 +136,14 @@ const alternateHighlightNothingAction: ActionDescriptor = { highlightId: "highlight1", }; +function getTextAction(options: GetTextActionOptions): ActionDescriptor { + return { + name: "getText", + options, + target: decoratedPrimitiveTarget("a"), + }; +} + /** * These test our Talon api using dummy spoken forms defined in * cursorless-talon-dev/src/cursorless_test.talon @@ -158,6 +167,26 @@ export const talonApiFixture = [ "test api wrap with snippet by name this", wrapWithSnippetByNameAction, ), + spokenFormTest( + "test api get text air", + getTextAction({ showDecorations: true, ensureSingleTarget: true }), + ["apple"], + ), + spokenFormTest( + "test api get text list on air", + getTextAction({ showDecorations: true, ensureSingleTarget: false }), + ["apple"], + ), + spokenFormTest( + "test api get text hide decorations air", + getTextAction({ showDecorations: false, ensureSingleTarget: true }), + ["apple"], + ), + spokenFormTest( + "test api get text hide decorations list on air", + getTextAction({ showDecorations: false, ensureSingleTarget: false }), + ["apple"], + ), spokenFormTest( "test api extract decorated marks air past bat", alternateHighlightAirAndBatAction,