From 3b850b027f98a30154955bb915d648d1992b724c Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Mon, 11 Dec 2023 20:04:36 +0100 Subject: [PATCH] Added glyph scope (#2050) `chuck glyph dollar red air` Fixes #54 ## Checklist - [x] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [x] I have updated the [docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and [cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet) - [x] I have not broken the cheatsheet --------- Co-authored-by: Pokey Rule <755842+pokey@users.noreply.github.com> --- src/cheatsheet/sections/scopes.py | 27 ++++++++++++++++++++------- src/modifiers/glyph_scope.py | 30 ++++++++++++++++++++++++++++++ src/modifiers/scopes.py | 28 +++++++++++++++++++++------- src/spoken_forms.json | 3 +++ src/spoken_forms.py | 3 ++- 5 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 src/modifiers/glyph_scope.py diff --git a/src/cheatsheet/sections/scopes.py b/src/cheatsheet/sections/scopes.py index b7133c9a72..9c610891fe 100644 --- a/src/cheatsheet/sections/scopes.py +++ b/src/cheatsheet/sections/scopes.py @@ -1,12 +1,25 @@ -from ..get_list import get_lists +from ..get_list import get_lists, get_raw_list def get_scopes(): - return get_lists( - ["scope_type"], - "scopeType", + complex_scopes = get_raw_list("glyph_scope_type") + return [ + *get_lists( + ["scope_type"], + "scopeType", + { + "argumentOrParameter": "Argument", + "boundedNonWhitespaceSequence": "Non whitespace sequence stopped by surrounding pair delimeters", + }, + ), { - "argumentOrParameter": "Argument", - "boundedNonWhitespaceSequence": "Non whitespace sequence stopped by surrounding pair delimeters", + "id": "glyph", + "type": "scopeType", + "variations": [ + { + "spokenForm": f"{complex_scopes['glyph']} ", + "description": "Instance of single character ", + }, + ], }, - ) + ] diff --git a/src/modifiers/glyph_scope.py b/src/modifiers/glyph_scope.py new file mode 100644 index 0000000000..beff4c35ed --- /dev/null +++ b/src/modifiers/glyph_scope.py @@ -0,0 +1,30 @@ +from talon import Module + +mod = Module() + +mod.list( + "cursorless_glyph_scope_type", + desc="Cursorless glyph scope type", +) +mod.list( + "cursorless_glyph_scope_type_plural", + desc="Plural version of Cursorless glyph scope type", +) + + +@mod.capture(rule="{user.cursorless_glyph_scope_type} ") +def cursorless_glyph_scope_type(m) -> dict[str, str]: + return { + "type": "glyph", + "character": m.any_alphanumeric_key, + } + + +@mod.capture( + rule="{user.cursorless_glyph_scope_type_plural} " +) +def cursorless_glyph_scope_type_plural(m) -> dict[str, str]: + return { + "type": "glyph", + "character": m.any_alphanumeric_key, + } diff --git a/src/modifiers/scopes.py b/src/modifiers/scopes.py index 02b98da19e..ee1efb9b2c 100644 --- a/src/modifiers/scopes.py +++ b/src/modifiers/scopes.py @@ -15,25 +15,39 @@ @mod.capture( - rule="{user.cursorless_scope_type} | {user.cursorless_custom_regex_scope_type}" + rule="{user.cursorless_scope_type} | | {user.cursorless_custom_regex_scope_type}" ) def cursorless_scope_type(m) -> dict[str, str]: """Cursorless scope type singular""" try: return {"type": m.cursorless_scope_type} except AttributeError: - return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type} + pass + + try: + return m.cursorless_glyph_scope_type + except AttributeError: + pass + + return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type} @mod.capture( - rule="{user.cursorless_scope_type_plural} | {user.cursorless_custom_regex_scope_type_plural}" + rule="{user.cursorless_scope_type_plural} | | {user.cursorless_custom_regex_scope_type_plural}" ) def cursorless_scope_type_plural(m) -> dict[str, str]: """Cursorless scope type plural""" try: return {"type": m.cursorless_scope_type_plural} except AttributeError: - return { - "type": "customRegex", - "regex": m.cursorless_custom_regex_scope_type_plural, - } + pass + + try: + return m.cursorless_glyph_scope_type_plural + except AttributeError: + pass + + return { + "type": "customRegex", + "regex": m.cursorless_custom_regex_scope_type_plural, + } diff --git a/src/spoken_forms.json b/src/spoken_forms.json index 062f4b3291..eec6aac6e2 100644 --- a/src/spoken_forms.json +++ b/src/spoken_forms.json @@ -171,6 +171,9 @@ }, "surrounding_pair_scope_type": { "string": "string" + }, + "glyph_scope_type": { + "glyph": "glyph" } }, "paired_delimiters.csv": { diff --git a/src/spoken_forms.py b/src/spoken_forms.py index aeed1593f0..30ad16498d 100644 --- a/src/spoken_forms.py +++ b/src/spoken_forms.py @@ -68,6 +68,7 @@ def ret(filename: str, *args: P.args, **kwargs: P.kwargs) -> R: "wrapper_only_paired_delimiter": "pairedDelimiter", "surrounding_pair_scope_type": "pairedDelimiter", "scope_type": "simpleScopeTypeType", + "glyph_scope_type": "complexScopeTypeType", "custom_regex_scope_type": "customRegex", } @@ -125,7 +126,7 @@ def handle_new_values(csv_name: str, values: list[SpokenFormEntry]): handle_csv("experimental/miscellaneous.csv"), handle_csv( "modifier_scope_types.csv", - pluralize_lists=["scope_type"], + pluralize_lists=["scope_type", "glyph_scope_type"], extra_allowed_values=[ "private.fieldAccess", "private.switchStatementSubject",