Skip to content

Commit 3eb377d

Browse files
AndreasArvidssonpokeypre-commit-ci[bot]
authored
Added support for previous and next containing scope type (#960)
* Added support for previous and next containing scope type * Added tests * Reverse changes * Reuse ordinal range for previous/next modifier * Use correct relative index * Added word and character as proper scope types * Select correct target * Always use token range * Cleanup * Clean up * New implementation of ordinal stage * Updated tests * Started working on migration * Made all tests pass * Added comment * Clean up * Added range modifier * Added tests for scope type word and character * Clean up * Created ordinal capture * Added ordinal items tests * cleanup * Added previous/next capture * Clean up * Update cursorless-talon/src/modifiers/ordinals.py Co-authored-by: Pokey Rule <[email protected]> * Use if statement instead of attribute error * Added index file * Update src/processTargets/processTargets.ts Co-authored-by: Pokey Rule <[email protected]> * Update src/typings/targetDescriptor.types.ts Co-authored-by: Pokey Rule <[email protected]> * Update src/typings/targetDescriptor.types.ts Co-authored-by: Pokey Rule <[email protected]> * Update src/typings/targetDescriptor.types.ts Co-authored-by: Pokey Rule <[email protected]> * cleanup * Added tests * Clean up types * Clean up * Added tests * Clean up * Clean up import * Clean up * Move ordinal stages into own directory * Prefer to take scopes to the right * Added additional word tests * Made migration for line number mark * Fixed correct type * Update grapheme regex * Added additional tests * rename * Use name mark * Updated modifier names * Split ordinal and relative scope python files * `lineType` => `lineNumberType` * Tweak token grapheme splitter * Rename variable * Clarify duplicate range stage names * Tweaks to relative scope stage * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added support for non containing relative scope * More clean up to relative scope * Rename * Reduce nesting * Tweaks to sub token stage * Doc strings * More tweaks to RelativeScopeStage * Add comment * Add comments * Improve error message * Add a bunch of tests Co-authored-by: Pokey Rule <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 66f9810 commit 3eb377d

File tree

9 files changed

+103
-103
lines changed

9 files changed

+103
-103
lines changed

src/cheatsheet/sections/scopes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
def get_scopes():
55
return {
66
**get_lists(
7-
["scope_type", "subtoken_scope_type"],
7+
["scope_type"],
88
{"argumentOrParameter": "Argument"},
99
),
1010
"<P>": "Paired delimiter",

src/cheatsheet_html/sections/scopes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
def get_scopes():
55
return get_lists(
6-
["scope_type", "subtoken_scope_type"],
6+
["scope_type"],
77
"scopeType",
88
{"argumentOrParameter": "Argument"},
99
)

src/command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def construct_cursorless_command_argument(
135135
use_pre_phrase_snapshot = False
136136

137137
return {
138-
"version": 2,
138+
"version": 3,
139139
"spokenForm": get_spoken_form(),
140140
"action": {
141141
"name": action,

src/marks/lines_number.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,8 @@ class CustomizableTerm:
3737
@mod.capture(rule="{user.cursorless_line_direction} <number_small>")
3838
def cursorless_line_number(m) -> dict[str, Any]:
3939
direction = directions_map[m.cursorless_line_direction]
40-
line_number = m.number_small
41-
line = {
42-
"lineNumber": direction.formatter(line_number),
43-
"type": direction.type,
44-
}
4540
return {
4641
"type": "lineNumber",
47-
"anchor": line,
48-
"active": line,
42+
"lineNumberType": direction.type,
43+
"lineNumber": direction.formatter(m.number_small),
4944
}

src/modifiers/containing_scope.py

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
"start tag": "xmlStartTag",
5353
"end tag": "xmlEndTag",
5454
# Text-based scope types
55+
"char": "character",
56+
"word": "word",
5557
"block": "paragraph",
5658
"cell": "notebookCell",
5759
"file": "document",
@@ -71,40 +73,26 @@
7173
}
7274

7375

74-
@mod.capture(rule="{user.cursorless_scope_type}")
76+
@mod.capture(
77+
rule="{user.cursorless_scope_type} | {user.cursorless_custom_regex_scope_type}"
78+
)
7579
def cursorless_scope_type(m) -> dict[str, str]:
7680
"""Simple cursorless scope type that only need to specify their type"""
77-
return {"type": m.cursorless_scope_type}
78-
79-
80-
@mod.capture(rule="{user.cursorless_custom_regex_scope_type}")
81-
def cursorless_custom_regex_scope_type(m) -> dict[str, str]:
82-
"""Cursorless custom regular expression scope type"""
83-
return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type}
81+
try:
82+
return {"type": m.cursorless_scope_type}
83+
except AttributeError:
84+
return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type}
8485

8586

86-
@mod.capture(
87-
rule="[every] (<user.cursorless_scope_type> | <user.cursorless_custom_regex_scope_type>)"
88-
)
87+
@mod.capture(rule="[every] <user.cursorless_scope_type>")
8988
def cursorless_containing_scope(m) -> dict[str, Any]:
9089
"""Expand to containing scope"""
91-
try:
92-
scope_type = m.cursorless_scope_type
93-
except AttributeError:
94-
scope_type = m.cursorless_custom_regex_scope_type
9590
return {
9691
"type": "everyScope" if m[0] == "every" else "containingScope",
97-
"scopeType": scope_type,
92+
"scopeType": m.cursorless_scope_type,
9893
}
9994

10095

101-
# NOTE: Please do not change these dicts. Use the CSVs for customization.
102-
# See https://www.cursorless.org/docs/user/customization/
103-
subtoken_scope_types = {
104-
"word": "word",
105-
"char": "character",
106-
}
107-
10896
# NOTE: Please do not change these dicts. Use the CSVs for customization.
10997
# See https://www.cursorless.org/docs/user/customization/
11098
# NB: This is a hack until we support having inside and outside on arbitrary
@@ -119,7 +107,6 @@ def on_ready():
119107
"modifier_scope_types",
120108
{
121109
"scope_type": scope_types,
122-
"subtoken_scope_type": subtoken_scope_types,
123110
"surrounding_pair_scope_type": surrounding_pair_scope_types,
124111
},
125112
)

src/modifiers/modifiers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def cursorless_simple_modifier(m) -> dict[str, str]:
3939
head_tail_swallowed_modifiers = [
4040
"<user.cursorless_simple_modifier>", # bounds, just, leading, trailing
4141
"<user.cursorless_containing_scope>", # funk, state, class
42-
"<user.cursorless_subtoken_scope>", # first past second word
42+
"<user.cursorless_ordinal_scope>", # first past second word
43+
"<user.cursorless_relative_scope>", # next funk
4344
"<user.cursorless_surrounding_pair>", # matching/pair [curly, round]
4445
]
4546

src/modifiers/ordinal_scope.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from typing import Any
2+
3+
from talon import Module
4+
5+
from ..compound_targets import is_active_included, is_anchor_included
6+
7+
mod = Module()
8+
9+
10+
@mod.capture(rule="<user.ordinals_small> | last")
11+
def ordinal_or_last(m) -> int:
12+
"""An ordinal or the word 'last'"""
13+
if m[0] == "last":
14+
return -1
15+
return m.ordinals_small - 1
16+
17+
18+
@mod.capture(
19+
rule="<user.ordinal_or_last> [{user.cursorless_range_connective} <user.ordinal_or_last>] <user.cursorless_scope_type>"
20+
)
21+
def cursorless_ordinal_range(m) -> dict[str, Any]:
22+
"""Ordinal range"""
23+
if len(m.ordinal_or_last_list) > 1:
24+
range_connective = m.cursorless_range_connective
25+
include_anchor = is_anchor_included(range_connective)
26+
include_active = is_active_included(range_connective)
27+
anchor = create_ordinal_scope_modifier(
28+
m.cursorless_scope_type, m.ordinal_or_last_list[0]
29+
)
30+
active = create_ordinal_scope_modifier(
31+
m.cursorless_scope_type, m.ordinal_or_last_list[1]
32+
)
33+
return {
34+
"type": "range",
35+
"anchor": anchor,
36+
"active": active,
37+
"excludeAnchor": not include_anchor,
38+
"excludeActive": not include_active,
39+
}
40+
else:
41+
return create_ordinal_scope_modifier(
42+
m.cursorless_scope_type, m.ordinal_or_last_list[0]
43+
)
44+
45+
46+
@mod.capture(rule="(first | last) <number_small> <user.cursorless_scope_type>")
47+
def cursorless_first_last(m) -> dict[str, Any]:
48+
"""First/last `n` scopes; eg "first three funk"""
49+
if m[0] == "first":
50+
return create_ordinal_scope_modifier(m.cursorless_scope_type, 0, m.number_small)
51+
return create_ordinal_scope_modifier(
52+
m.cursorless_scope_type, -m.number_small, m.number_small
53+
)
54+
55+
56+
@mod.capture(rule="<user.cursorless_ordinal_range> | <user.cursorless_first_last>")
57+
def cursorless_ordinal_scope(m) -> dict[str, Any]:
58+
"""Ordinal ranges such as subwords or characters"""
59+
return m[0]
60+
61+
62+
def create_ordinal_scope_modifier(scope_type: Any, start: int, length: int = 1):
63+
return {
64+
"type": "ordinalScope",
65+
"scopeType": scope_type,
66+
"start": start,
67+
"length": length,
68+
}

src/modifiers/relative_scope.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import Any
2+
3+
from talon import Module
4+
5+
mod = Module()
6+
7+
8+
@mod.capture(rule="(previous | next) <user.cursorless_scope_type>")
9+
def cursorless_relative_scope(m) -> dict[str, Any]:
10+
"""Previous/next scope"""
11+
return {
12+
"type": "relativeScope",
13+
"scopeType": m.cursorless_scope_type,
14+
"offset": 1,
15+
"length": 1,
16+
"direction": "backward" if m[0] == "previous" else "forward",
17+
}

src/modifiers/sub_token.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)