Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of modulo line numbers #105

Merged
merged 5 commits into from
Nov 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 24 additions & 53 deletions src/marks/lines_number.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,45 @@
from talon import Context, Module
from dataclasses import dataclass

mod = Module()
ctx = Context()

mod.list("cursorless_line_direction", desc="Supported directions for line modifier")

directions = {
"row": {"isRelative": False, "transformation": lambda number: number - 1},
"up": {"isRelative": True, "transformation": lambda number: -number},
"down": {"isRelative": True, "transformation": lambda number: number},
}

ctx.lists["self.cursorless_line_direction"] = directions.keys()
@dataclass
class CustomizableTerm:
defaultSpokenForm: str
cursorlessIdentifier: str
type: str
formatter: callable


def parse_line(line: dict):
direction = directions[line["direction"]]
line_number = line["lineNumber"]
return {
"lineNumber": direction["transformation"](line_number),
"isRelative": direction["isRelative"],
}

# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://github.com/pokey/cursorless-talon/blob/main/docs/customization.md
directions = [
CustomizableTerm("row", "lineNumberModulo100", "modulo100", lambda number: number - 1),
CustomizableTerm("up", "lineNumberRelativeUp", "relative", lambda number: -number),
CustomizableTerm("down", "lineNumberRelativeDown", "relative", lambda number: number),
]

@mod.capture(rule="{user.cursorless_line_direction} <number>")
def cursorless_line_number_anchor(m) -> str:
return {"direction": m.cursorless_line_direction, "lineNumber": m.number}
directions_map = {d.cursorlessIdentifier: d for d in directions}
DEFAULT_DIRECTIONS = {d.defaultSpokenForm: d.cursorlessIdentifier for d in directions}


@mod.capture(rule="past [{user.cursorless_line_direction}] <number>")
def cursorless_line_number_active(m) -> str:
try:
direction = m.cursorless_line_direction
except AttributeError:
direction = None
return {"direction": direction, "lineNumber": m.number}


# For now this capture is not used because it's too complex and increase compilation time too much
@mod.capture(
rule="<user.cursorless_line_number_anchor> [<user.cursorless_line_number_active>]"
)
@mod.capture(rule="{user.cursorless_line_direction} <number_small>")
def cursorless_line_number(m) -> str:
anchor = m.cursorless_line_number_anchor
try:
active = m.cursorless_line_number_active
# Infer missing direction from anchor
if active["direction"] == None:
active["direction"] = anchor["direction"]
except AttributeError:
active = anchor
return {
"selectionType": "line",
"mark": {
"type": "lineNumber",
"anchor": parse_line(anchor),
"active": parse_line(active),
},
direction = directions_map[m.cursorless_line_direction]
line_number = m.number_small
line = {
"lineNumber": direction.formatter(line_number),
"type": direction.type,
}


# This is the simplified version that we are using for now that only implements a subset of the features
@mod.capture(rule="(up | down) <number_small>")
def cursorless_line_number_simple(m) -> str:
position = {"direction": m[0], "lineNumber": m.number_small}
return {
"selectionType": "line",
"mark": {
"type": "lineNumber",
"anchor": parse_line(position),
"active": parse_line(position),
"anchor": line,
"active": line,
},
}
8 changes: 4 additions & 4 deletions src/marks/mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ..conventions import get_cursorless_list_name
from talon import Module, actions, app, Context, fs, cron
from ..csv_overrides import init_csv_and_watch_changes
from .lines_number import DEFAULT_DIRECTIONS

mod = Module()
ctx = Context()
Expand Down Expand Up @@ -84,9 +85,7 @@ class CustomizableTerm:
rule=(
"<user.cursorless_decorated_symbol> | "
"{user.cursorless_special_mark} |"
# Because of problems with performance we have to have a simple version for now
# "<user.cursorless_line_number>" # row, up, down
"<user.cursorless_line_number_simple>" # up, down
"<user.cursorless_line_number>" # row (ie absolute mod 100), up, down
)
)
def cursorless_mark(m) -> str:
Expand All @@ -98,7 +97,7 @@ def cursorless_mark(m) -> str:
return special_marks_map[m.cursorless_special_mark].value
except AttributeError:
pass
return m.cursorless_line_number_simple
return m.cursorless_line_number


DEFAULT_COLOR_ENABLEMENT = {
Expand Down Expand Up @@ -170,6 +169,7 @@ def on_ready():
"special_marks",
{
"special_mark": special_marks_defaults,
"line_direction": DEFAULT_DIRECTIONS,
},
)

Expand Down