Skip to content

Commit d113d88

Browse files
Added support for browser rpc (#2704)
When using Cursorless everywhere in Talon js the accessibility is not good enough for browsers. I'm working on my own browser extension to mitigate this. What this pull request is doing is adding a new Cursorless everywhere context. When the new tag is set Cursorless everywhere will use the command client instead of access ability. ## Checklist - [/] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [/] 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) - [/] I have not broken the cheatsheet
1 parent c5824a1 commit d113d88

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

cursorless-everywhere-talon/cursorless_everywhere_talon.py

+2
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:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from talon import Context, Module, actions
2+
3+
from .cursorless_everywhere_types import EditorEdit, EditorState, SelectionOffsets
4+
5+
mod = Module()
6+
7+
mod.tag(
8+
"cursorless_everywhere_talon_browser",
9+
desc="Enable RPC to browser extension when using cursorless everywhere in Talon",
10+
)
11+
12+
ctx = Context()
13+
ctx.matches = r"""
14+
tag: user.cursorless_everywhere_talon_browser
15+
"""
16+
17+
RPC_COMMAND = "talonCommand"
18+
19+
20+
@ctx.action_class("user")
21+
class Actions:
22+
def cursorless_everywhere_get_editor_state() -> EditorState:
23+
command = {
24+
"id": "getEditorState",
25+
}
26+
res = rpc_get(command)
27+
if use_fallback(res):
28+
return actions.next()
29+
return res
30+
31+
def cursorless_everywhere_set_selections(
32+
selections: list[SelectionOffsets], # pyright: ignore [reportGeneralTypeIssues]
33+
):
34+
command = {
35+
"id": "setSelections",
36+
"selections": get_serializable_selections(selections),
37+
}
38+
res = rpc_get(command)
39+
if use_fallback(res):
40+
actions.next(selections)
41+
42+
def cursorless_everywhere_edit_text(
43+
edit: EditorEdit, # pyright: ignore [reportGeneralTypeIssues]
44+
):
45+
command = {
46+
"id": "setText",
47+
"text": edit["text"],
48+
}
49+
res = rpc_get(command)
50+
if use_fallback(res):
51+
actions.next(edit)
52+
53+
54+
def rpc_get(command: dict):
55+
return actions.user.run_rpc_command_get(RPC_COMMAND, command)
56+
57+
58+
def use_fallback(result: dict) -> bool:
59+
return result.get("fallback", False)
60+
61+
62+
# What is passed from cursorless everywhere js is a javascript object, which is not serializable for python.
63+
def get_serializable_selections(selections: list[SelectionOffsets]):
64+
result: list[SelectionOffsets] = []
65+
for i in range(selections.length): # pyright: ignore [reportAttributeAccessIssue]
66+
selection = selections[i]
67+
result.append(
68+
{
69+
"anchor": selection["anchor"],
70+
"active": selection["active"],
71+
}
72+
)
73+
return result

0 commit comments

Comments
 (0)