91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
from typing import Any
|
|
|
|
from talon import Module
|
|
|
|
from ..targets.range_target import RangeConnective
|
|
|
|
mod = Module()
|
|
|
|
mod.list("cursorless_first_modifier", desc="Cursorless first modifiers")
|
|
mod.list("cursorless_last_modifier", desc="Cursorless last modifiers")
|
|
|
|
|
|
@mod.capture(
|
|
rule="<user.ordinals_small> | [<user.ordinals_small>] {user.cursorless_last_modifier}"
|
|
)
|
|
def ordinal_or_last(m) -> int:
|
|
"""An ordinal or the word 'last'"""
|
|
if m[-1] == "last":
|
|
return -getattr(m, "ordinals_small", 1)
|
|
return m.ordinals_small - 1
|
|
|
|
|
|
@mod.capture(
|
|
rule="<user.ordinal_or_last> [<user.cursorless_range_connective> <user.ordinal_or_last>] <user.cursorless_scope_type>"
|
|
)
|
|
def cursorless_ordinal_range(m) -> dict[str, Any]:
|
|
"""Ordinal range"""
|
|
anchor = create_ordinal_scope_modifier(
|
|
m.cursorless_scope_type, m.ordinal_or_last_list[0]
|
|
)
|
|
if len(m.ordinal_or_last_list) > 1:
|
|
active = create_ordinal_scope_modifier(
|
|
m.cursorless_scope_type, m.ordinal_or_last_list[1]
|
|
)
|
|
range_connective: RangeConnective = m.cursorless_range_connective
|
|
return {
|
|
"type": "range",
|
|
"anchor": anchor,
|
|
"active": active,
|
|
"excludeAnchor": range_connective.excludeAnchor,
|
|
"excludeActive": range_connective.excludeActive,
|
|
}
|
|
return anchor
|
|
|
|
|
|
@mod.capture(
|
|
rule=(
|
|
"[{user.cursorless_every_scope_modifier}] "
|
|
"({user.cursorless_first_modifier} | {user.cursorless_last_modifier}) "
|
|
"<user.private_cursorless_number_small> <user.cursorless_scope_type_plural>"
|
|
),
|
|
)
|
|
def cursorless_first_last(m) -> dict[str, Any]:
|
|
"""First/last `n` scopes; eg "first three funks"""
|
|
is_every = hasattr(m, "cursorless_every_scope_modifier")
|
|
if hasattr(m, "cursorless_first_modifier"):
|
|
return create_ordinal_scope_modifier(
|
|
m.cursorless_scope_type_plural,
|
|
0,
|
|
m.private_cursorless_number_small,
|
|
is_every,
|
|
)
|
|
return create_ordinal_scope_modifier(
|
|
m.cursorless_scope_type_plural,
|
|
-m.private_cursorless_number_small,
|
|
m.private_cursorless_number_small,
|
|
is_every,
|
|
)
|
|
|
|
|
|
@mod.capture(rule="<user.cursorless_ordinal_range> | <user.cursorless_first_last>")
|
|
def cursorless_ordinal_scope(m) -> dict[str, Any]:
|
|
"""Ordinal ranges such as subwords or characters"""
|
|
return m[0]
|
|
|
|
|
|
def create_ordinal_scope_modifier(
|
|
scope_type: dict,
|
|
start: int,
|
|
length: int = 1,
|
|
is_every: bool = False,
|
|
):
|
|
res = {
|
|
"type": "ordinalScope",
|
|
"scopeType": scope_type,
|
|
"start": start,
|
|
"length": length,
|
|
}
|
|
if is_every:
|
|
res["isEvery"] = True
|
|
return res
|