Skip to content

Commit fb74380

Browse files
Merge branch 'main' into migrateNotebookCell
2 parents 56ad4c5 + 85fd827 commit fb74380

File tree

79 files changed

+1505
-413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1505
-413
lines changed

cursorless-everywhere-talon/cursorless_everywhere_talon.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
tag: user.cursorless_everywhere_talon
1515
"""
1616

17+
ctx.tags = ["user.cursorless"]
18+
1719

1820
@ctx.action_class("user")
1921
class UserActions:
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from talon import Context, Module, actions
2+
3+
from .cursorless_everywhere_types import (
4+
EditorEdit,
5+
EditorState,
6+
SelectionOffsets,
7+
)
8+
9+
mod = Module()
10+
11+
mod.tag(
12+
"cursorless_everywhere_talon_browser",
13+
desc="Enable RPC to browser extension when using cursorless everywhere in Talon",
14+
)
15+
16+
ctx = Context()
17+
ctx.matches = r"""
18+
tag: user.cursorless_everywhere_talon_browser
19+
"""
20+
21+
RPC_COMMAND = "talonCommand"
22+
23+
24+
@ctx.action_class("user")
25+
class Actions:
26+
def cursorless_everywhere_get_editor_state() -> EditorState:
27+
command = {
28+
"id": "getEditorState",
29+
}
30+
res = rpc_get(command)
31+
if use_fallback(res):
32+
return actions.next()
33+
return res
34+
35+
def cursorless_everywhere_set_selections(
36+
selections: list[SelectionOffsets], # pyright: ignore [reportGeneralTypeIssues]
37+
):
38+
command = {
39+
"id": "setSelections",
40+
"selections": [
41+
js_object_to_python_dict(s, ["anchor", "active"])
42+
for s in js_array_to_python_list(selections)
43+
],
44+
}
45+
res = rpc_get(command)
46+
if use_fallback(res):
47+
actions.next(selections)
48+
49+
def cursorless_everywhere_edit_text(
50+
edit: EditorEdit, # pyright: ignore [reportGeneralTypeIssues]
51+
):
52+
command = {
53+
"id": "editText",
54+
"text": edit["text"],
55+
"changes": [
56+
js_object_to_python_dict(c, ["text", "rangeOffset", "rangeLength"])
57+
for c in js_array_to_python_list(edit["changes"])
58+
],
59+
}
60+
res = rpc_get(command)
61+
if use_fallback(res):
62+
actions.next(edit)
63+
64+
65+
def rpc_get(command: dict):
66+
return actions.user.run_rpc_command_get(RPC_COMMAND, command)
67+
68+
69+
def use_fallback(result: dict) -> bool:
70+
return result.get("fallback", False)
71+
72+
73+
def js_array_to_python_list(array) -> list:
74+
result = []
75+
for i in range(array.length):
76+
result.append(array[i])
77+
return result
78+
79+
80+
def js_object_to_python_dict(object, keys: list[str]) -> dict:
81+
result = {}
82+
for key in keys:
83+
result[key] = object[key]
84+
return result
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Please file pull requests to the cursorless-talon subdirectory in the https://github.com/cursorless-dev/cursorless repo
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from talon import app, registry
2+
3+
required_captures = [
4+
"number_small",
5+
"user.any_alphanumeric_key",
6+
"user.formatters",
7+
"user.ordinals_small",
8+
]
9+
10+
required_actions = [
11+
"user.homophones_get",
12+
"user.reformat_text",
13+
]
14+
15+
16+
def on_ready():
17+
missing_captures = [
18+
capture for capture in required_captures if capture not in registry.captures
19+
]
20+
missing_actions = [
21+
action for action in required_actions if action not in registry.actions
22+
]
23+
errors = []
24+
if missing_captures:
25+
errors.append(f"Missing captures: {', '.join(missing_captures)}")
26+
if missing_actions:
27+
errors.append(f"Missing actions: {', '.join(missing_actions)}")
28+
if errors:
29+
print("Cursorless community requirements:")
30+
print("\n".join(errors))
31+
app.notify(
32+
"Cursorless: Please install the community repository",
33+
body="https://github.com/talonhub/community",
34+
)
35+
36+
37+
app.register("ready", on_ready)

cursorless-talon/src/cursorless.talon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ tutorial (previous | last): user.private_cursorless_tutorial_previous()
4545
tutorial restart: user.private_cursorless_tutorial_restart()
4646
tutorial resume: user.private_cursorless_tutorial_resume()
4747
tutorial (list | close): user.private_cursorless_tutorial_list()
48-
tutorial <user.private_cursorless_number_small>:
49-
user.private_cursorless_tutorial_start_by_number(private_cursorless_number_small)
48+
tutorial <number_small>:
49+
user.private_cursorless_tutorial_start_by_number(number_small)

cursorless-talon/src/get_grapheme_spoken_form_entries.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import typing
33
from collections import defaultdict
44
from typing import Iterator, Mapping
5-
from uu import Error
65

76
from talon import app, registry, scope
87

@@ -55,7 +54,7 @@ def generate_lists_from_capture(capture_name) -> Iterator[str]:
5554
try:
5655
# NB: [-1] because the last capture is the active one
5756
rule = registry.captures[capture_name][-1].rule.rule
58-
except Error:
57+
except Exception:
5958
app.notify("Error constructing spoken forms for graphemes")
6059
print(f"Error getting rule for capture {capture_name}")
6160
return
@@ -86,7 +85,7 @@ def get_id_to_talon_list(list_name: str) -> dict[str, str]:
8685
try:
8786
# NB: [-1] because the last list is the active one
8887
return typing.cast(dict[str, str], registry.lists[list_name][-1]).copy()
89-
except Error:
88+
except Exception:
9089
app.notify(f"Error getting list {list_name}")
9190
return {}
9291

cursorless-talon/src/marks/lines_number.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ class CustomizableTerm:
3131

3232
@mod.capture(
3333
rule=(
34-
"{user.cursorless_line_direction} <user.private_cursorless_number_small> "
35-
"[<user.cursorless_range_connective> <user.private_cursorless_number_small>]"
34+
"{user.cursorless_line_direction} <number_small> "
35+
"[<user.cursorless_range_connective> <number_small>]"
3636
)
3737
)
3838
def cursorless_line_number(m) -> LineNumber:
3939
direction = directions_map[m.cursorless_line_direction]
40-
numbers: list[int] = m.private_cursorless_number_small_list
40+
numbers: list[int] = m.number_small_list
4141
anchor = create_line_number_mark(direction.type, direction.formatter(numbers[0]))
4242
if len(numbers) > 1:
4343
active = create_line_number_mark(

cursorless-talon/src/modifiers/ordinal_scope.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@
1313
@mod.capture(
1414
rule="<user.ordinals_small> | [<user.ordinals_small>] {user.cursorless_last_modifier}"
1515
)
16-
def ordinal_or_last(m) -> int:
16+
def cursorless_ordinal_or_last(m) -> int:
1717
"""An ordinal or the word 'last'"""
1818
if m[-1] == "last":
1919
return -getattr(m, "ordinals_small", 1)
2020
return m.ordinals_small - 1
2121

2222

2323
@mod.capture(
24-
rule="<user.ordinal_or_last> [<user.cursorless_range_connective> <user.ordinal_or_last>] <user.cursorless_scope_type>"
24+
rule="<user.cursorless_ordinal_or_last> [<user.cursorless_range_connective> <user.cursorless_ordinal_or_last>] <user.cursorless_scope_type>"
2525
)
2626
def cursorless_ordinal_range(m) -> dict[str, Any]:
2727
"""Ordinal range"""
2828
anchor = create_ordinal_scope_modifier(
29-
m.cursorless_scope_type, m.ordinal_or_last_list[0]
29+
m.cursorless_scope_type, m.cursorless_ordinal_or_last_list[0]
3030
)
31-
if len(m.ordinal_or_last_list) > 1:
31+
if len(m.cursorless_ordinal_or_last_list) > 1:
3232
active = create_ordinal_scope_modifier(
33-
m.cursorless_scope_type, m.ordinal_or_last_list[1]
33+
m.cursorless_scope_type, m.cursorless_ordinal_or_last_list[1]
3434
)
3535
range_connective: RangeConnective = m.cursorless_range_connective
3636
return {
@@ -47,7 +47,7 @@ def cursorless_ordinal_range(m) -> dict[str, Any]:
4747
rule=(
4848
"[{user.cursorless_every_scope_modifier}] "
4949
"({user.cursorless_first_modifier} | {user.cursorless_last_modifier}) "
50-
"<user.private_cursorless_number_small> <user.cursorless_scope_type_plural>"
50+
"<number_small> <user.cursorless_scope_type_plural>"
5151
),
5252
)
5353
def cursorless_first_last(m) -> dict[str, Any]:
@@ -57,13 +57,13 @@ def cursorless_first_last(m) -> dict[str, Any]:
5757
return create_ordinal_scope_modifier(
5858
m.cursorless_scope_type_plural,
5959
0,
60-
m.private_cursorless_number_small,
60+
m.number_small,
6161
is_every,
6262
)
6363
return create_ordinal_scope_modifier(
6464
m.cursorless_scope_type_plural,
65-
-m.private_cursorless_number_small,
66-
m.private_cursorless_number_small,
65+
-m.number_small,
66+
m.number_small,
6767
is_every,
6868
)
6969

cursorless-talon/src/modifiers/relative_scope.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,28 @@ def cursorless_relative_scope_singular(m) -> dict[str, Any]:
3131

3232

3333
@mod.capture(
34-
rule="[{user.cursorless_every_scope_modifier}] <user.cursorless_relative_direction> <user.private_cursorless_number_small> <user.cursorless_scope_type_plural>"
34+
rule="[{user.cursorless_every_scope_modifier}] <user.cursorless_relative_direction> <number_small> <user.cursorless_scope_type_plural>"
3535
)
3636
def cursorless_relative_scope_plural(m) -> dict[str, Any]:
3737
"""Relative previous/next plural scope. `next three funks`"""
3838
return create_relative_scope_modifier(
3939
m.cursorless_scope_type_plural,
4040
1,
41-
m.private_cursorless_number_small,
41+
m.number_small,
4242
m.cursorless_relative_direction,
4343
hasattr(m, "cursorless_every_scope_modifier"),
4444
)
4545

4646

4747
@mod.capture(
48-
rule="[{user.cursorless_every_scope_modifier}] <user.private_cursorless_number_small> <user.cursorless_scope_type_plural> [{user.cursorless_forward_backward_modifier}]"
48+
rule="[{user.cursorless_every_scope_modifier}] <number_small> <user.cursorless_scope_type_plural> [{user.cursorless_forward_backward_modifier}]"
4949
)
5050
def cursorless_relative_scope_count(m) -> dict[str, Any]:
5151
"""Relative count scope. `three funks`"""
5252
return create_relative_scope_modifier(
5353
m.cursorless_scope_type_plural,
5454
0,
55-
m.private_cursorless_number_small,
55+
m.number_small,
5656
getattr(m, "cursorless_forward_backward_modifier", "forward"),
5757
hasattr(m, "cursorless_every_scope_modifier"),
5858
)
Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,20 @@
11
"""
2-
This file allows us to use a custom `number_small` capture. See #1021 for more
3-
info.
2+
DEPRECATED @ 2024-12-21
3+
This file allows us to use a custom `number_small` capture. See #1021 for more info.
44
"""
55

6-
from talon import Context, Module
6+
from talon import Module, app, registry
77

88
mod = Module()
9-
mod.tag(
10-
"cursorless_custom_number_small",
11-
"This tag causes Cursorless to use the global <number_small> capture",
12-
)
139

14-
ctx = Context()
15-
ctx.matches = """
16-
not tag: user.cursorless_custom_number_small
17-
"""
18-
19-
20-
@mod.capture(rule="<number_small>")
21-
def private_cursorless_number_small(m) -> int:
22-
return m.number_small
23-
24-
25-
digit_list = "zero one two three four five six seven eight nine".split()
26-
teens = "ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split()
27-
tens = "twenty thirty forty fifty sixty seventy eighty ninety".split()
10+
mod.tag("cursorless_custom_number_small", "DEPRECATED!")
2811

29-
number_small_list = [*digit_list, *teens]
30-
for ten in tens:
31-
number_small_list.append(ten)
32-
number_small_list.extend(f"{ten} {digit}" for digit in digit_list[1:])
33-
number_small_map = {n: i for i, n in enumerate(number_small_list)}
3412

35-
mod.list("private_cursorless_number_small", desc="List of small numbers")
36-
# FIXME: Remove type ignore once Talon supports list types
37-
# See https://github.com/talonvoice/talon/issues/654
38-
ctx.lists["self.private_cursorless_number_small"] = number_small_map.keys() # pyright: ignore [reportArgumentType]
13+
def on_ready():
14+
if "user.cursorless_custom_number_small" in registry.tags:
15+
print(
16+
"WARNING tag: 'user.cursorless_custom_number_small' is deprecated and should not be used anymore, as Cursorless now uses community number_small"
17+
)
3918

4019

41-
@ctx.capture(
42-
"user.private_cursorless_number_small",
43-
rule="{user.private_cursorless_number_small}",
44-
)
45-
def override_private_cursorless_number_small(m) -> int:
46-
return number_small_map[m.private_cursorless_number_small]
20+
app.register("ready", on_ready)

0 commit comments

Comments
 (0)