Skip to content

Commit

Permalink
Experimental private Cursorless Talon api (#1784)
Browse files Browse the repository at this point in the history
- Private experimental api; one version of #492
- Currently used by [`wax_talon`](https://github.com/pokey/wax_talon);
see
pokey/wax_talon@4bd7d9b
for example usage
- Depends on #1880 for
Python 3.10 `match` statements

## Checklist

- [x] 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)
- [x] I have not broken the cheatsheet

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
  • Loading branch information
pokey and pre-commit-ci-lite[bot] authored Dec 19, 2023
1 parent 8f37186 commit 655e722
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/private_api/extract_decorated_marks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import Any

from ..actions.bring_move import BringMoveTargets
from ..actions.swap import SwapTargets
from ..targets.target_types import (
ImplicitDestination,
ImplicitTarget,
ListDestination,
ListTarget,
PrimitiveDestination,
PrimitiveTarget,
RangeTarget,
)


def extract_decorated_marks(capture: Any) -> list[Any]:
match capture:
case PrimitiveTarget(mark=mark):
if mark is None or mark["type"] != "decoratedSymbol":
return []
return [mark]
case ImplicitTarget():
return []
case RangeTarget(anchor=anchor, active=active):
return extract_decorated_marks(anchor) + extract_decorated_marks(active)
case ListTarget(elements=elements):
return [
mark for target in elements for mark in extract_decorated_marks(target)
]
case PrimitiveDestination(target=target):
return extract_decorated_marks(target)
case ImplicitDestination():
return []
case ListDestination(destinations=destinations):
return [
mark
for destination in destinations
for mark in extract_decorated_marks(destination)
]
case BringMoveTargets(source=source, destination=destination):
return extract_decorated_marks(source) + extract_decorated_marks(
destination
)
case SwapTargets(target1=target1, target2=target2):
return extract_decorated_marks(target1) + extract_decorated_marks(target2)
case _:
raise TypeError(f"Unknown capture type: {type(capture)}")
66 changes: 66 additions & 0 deletions src/private_api/private_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import Any, Optional, Union

from talon import Module, actions

from ..targets.target_types import (
CursorlessTarget,
ListTarget,
PrimitiveTarget,
RangeTarget,
)
from .extract_decorated_marks import extract_decorated_marks

mod = Module()


@mod.action_class
class MiscActions:
def cursorless_private_extract_decorated_marks(capture: Any) -> list[dict]:
"""Cursorless private api: Extract all decorated marks from a Talon capture"""
return extract_decorated_marks(capture)


@mod.action_class
class TargetBuilderActions:
"""Cursorless private api low-level target builder actions"""

def cursorless_private_build_primitive_target(
modifiers: list[dict], mark: Optional[dict]
) -> PrimitiveTarget:
"""Cursorless private api low-level target builder: Create a primitive target"""
return PrimitiveTarget(mark, modifiers)

def cursorless_private_build_list_target(
elements: list[Union[PrimitiveTarget, RangeTarget]]
) -> Union[PrimitiveTarget, ListTarget]:
"""Cursorless private api low-level target builder: Create a list target"""
if len(elements) == 1:
return elements[0]

return ListTarget(elements)


@mod.action_class
class TargetActions:
def cursorless_private_target_nothing() -> PrimitiveTarget:
"""Cursorless private api: Creates the "nothing" target"""
return PrimitiveTarget({"type": "nothing"}, [])


@mod.action_class
class ActionActions:
def cursorless_private_action_highlight(
target: CursorlessTarget, highlightId: Optional[str] = None
) -> None:
"""Cursorless private api: Highlights a target"""
payload = {
"name": "highlight",
"target": target,
}

if highlightId is not None:
payload["highlightId"] = highlightId

actions.user.private_cursorless_command_and_wait(
payload,
)

0 comments on commit 655e722

Please sign in to comment.