Skip to content

Commit

Permalink
feat: remove Positions class and integrate functionality into Cursor …
Browse files Browse the repository at this point in the history
…class directly
  • Loading branch information
mecaneer23 committed Jun 23, 2024
1 parent 42fdcc0 commit 4f5bfbc
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 94 deletions.
130 changes: 49 additions & 81 deletions src/class_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# from functools import wraps
# from typing import Any, Callable, Iterable, TypeVar
from typing import TypeVar
from typing import Iterator, TypeVar

from src.class_todo import Todos
from src.get_args import UI_TYPE, UiType
Expand All @@ -33,88 +33,57 @@ class _Direction(Enum):
NONE = 2


class Positions:
"""
Store a group of consecutive ints
"""

@classmethod
def from_start(cls, start: int) -> "Positions":
"""Construct a Positions object from a single int"""
return cls(start, start + 1)

def __init__(self, start: int, stop: int) -> None:
self._start = start
self._stop = stop

def get_start(self) -> int:
"""Getter for start"""
return self._start

def get_stop(self) -> int:
"""Getter for stop"""
return self._stop

def __len__(self) -> int:
return self._stop - self._start

def __contains__(self, child: int) -> bool:
return self._start <= child < self._stop

def as_range(self) -> range:
"""Getter for Positions represented as an iterator"""
return range(self._start, self._stop)

def raise_start(self, amount: int) -> None:
"""Raise start by `amount`"""
self._start += amount

def raise_stop(self, amount: int) -> None:
"""Raise stop by `amount`"""
self._stop += amount


class Cursor:
"""
Store potentially multiple consectutive position(s) using a
`Positions` object
"""
"""Store potentially multiple consectutive position(s)"""

def __init__(self, position: int, todos: Todos) -> None:
self._positions: Positions = Positions.from_start(position)
def __init__(self, start: int, todos: Todos) -> None:
self._start = start
self._stop = start + 1
self._direction: _Direction = _Direction.NONE
# self._todos: Todos = todos
_ = todos

def __len__(self) -> int:
return len(self._positions)
return self._stop - self._start

def __str__(self) -> str:
return str(self.get_first())

def __repr__(self) -> str:
return " ".join(map(str, self._positions.as_range()))
return " ".join(map(str, self._as_range()))

def __int__(self) -> int:
return self.get_first()

def __contains__(self, child: int) -> bool:
return child in self._positions
return self._start <= child < self._stop

def __iter__(self) -> Iterator[int]:
return iter(self.get())

def __iter__(self) -> range:
return self.get()
def _as_range(self) -> range:
"""Getter for Cursor represented as an iterator"""
return range(self._start, self._stop)

def get(self) -> range:
"""Return a iterable object holding the current cursor"""
return self._positions.as_range()
return self._as_range()

def get_first(self) -> int:
"""Return the top-most selected position"""
return self._positions.get_start()
return self._start

def get_last(self) -> int:
"""Return the bottom-most selected position"""
return self._positions.get_stop() - 1
return self._stop - 1

def _raise_start(self, amount: int) -> None:
"""Raise start by `amount`"""
self._start += amount

def _raise_stop(self, amount: int) -> None:
"""Raise stop by `amount`"""
self._stop += amount

# @staticmethod
# def _updates_cursor(
Expand All @@ -130,7 +99,7 @@ def get_last(self) -> int:
# def _decorator(func: Callable[..., T]) -> Callable[..., T]:
# @wraps(func)
# def _inner(self: "Cursor", *args: list[Any], **kwargs: dict[Any, Any]) -> T:
# for pos in self._positions:
# for pos in self:
# # if not self._todos[pos].is_folded_parent():
# # break
# count = 0
Expand All @@ -154,19 +123,17 @@ def get_last(self) -> int:

def set_to(self, position: int) -> None:
"""Replace the entire cursor with a new single position"""
self._positions = Positions.from_start(position)
self._start = position
self._stop = position + 1

def override_passthrough(self, passthrough: T, positions: Positions) -> T:
"""
Replace the cursor with a new `Positions`, and pass the
passthrough through the method.
"""
self._positions = positions
return passthrough
def set(self, start: int, stop: int) -> None:
"""Setter for Cursor"""
self._start = start
self._stop = stop

def single_up(self, max_len: int) -> None:
"""Move a cursor with length 1 up by 1"""
if len(self._positions) == max_len:
if len(self) == max_len:
self.set_to(0)
return
if self.get_first() == 0:
Expand All @@ -179,12 +146,12 @@ def slide_up(self) -> None:
"""Shift each value in the cursor up by 1"""
if self.get_first() == 0:
return
self._positions.raise_start(-1)
self._positions.raise_stop(-1)
self._raise_start(-1)
self._raise_stop(-1)

def single_down(self, max_len: int) -> None:
"""Move a cursor with length 1 down by 1"""
if len(self._positions) == max_len:
if len(self) == max_len:
self.set_to(self.get_first())
if self.get_last() >= max_len - 1:
return
Expand All @@ -194,8 +161,8 @@ def slide_down(self, max_len: int) -> None:
"""Shift each value in the cursor down by 1"""
if self.get_last() >= max_len - 1:
return
self._positions.raise_start(1)
self._positions.raise_stop(1)
self._raise_start(1)
self._raise_stop(1)

def to_top(self) -> None:
"""Move the cursor to the top"""
Expand All @@ -207,21 +174,21 @@ def to_bottom(self, len_list: int) -> None:

def _select_next(self) -> None:
"""Extend the cursor down by 1"""
self._positions.raise_stop(1)
self._raise_stop(1)

def _deselect_next(self) -> None:
"""Retract the cursor by 1"""
if len(self._positions) > 1:
self._positions.raise_stop(-1)
if len(self) > 1:
self._raise_stop(-1)

def _deselect_prev(self) -> None:
"""Remove the first position of the cursor"""
if len(self._positions) > 1:
self._positions.raise_start(1)
if len(self) > 1:
self._raise_start(1)

def _select_prev(self) -> None:
"""Extend the cursor up by 1"""
self._positions.raise_start(-1)
self._raise_start(-1)

def get_deletable(self) -> list[int]:
"""
Expand All @@ -230,13 +197,13 @@ def get_deletable(self) -> list[int]:
set to the minimum position of the current
Cursor
"""
return [self.get_first() for _ in self._positions.as_range()]
return [self.get_first() for _ in self._as_range()]

def multiselect_down(self, max_len: int) -> None:
"""Extend the cursor down by 1"""
if self.get_last() >= max_len - 1:
return
if len(self._positions) == 1 or self._direction == _Direction.DOWN:
if len(self) == 1 or self._direction == _Direction.DOWN:
self._select_next()
self._direction = _Direction.DOWN
return
Expand All @@ -246,7 +213,7 @@ def multiselect_up(self) -> None:
"""Extend the cursor up by 1"""
if self.get_first() == 0 and self._direction == _Direction.UP:
return
if len(self._positions) == 1 or self._direction == _Direction.UP:
if len(self) == 1 or self._direction == _Direction.UP:
self._select_prev()
self._direction = _Direction.UP
return
Expand Down Expand Up @@ -323,4 +290,5 @@ def relative_to(

def multiselect_all(self, max_len: int) -> None:
"""Set internal positions to entirity of list"""
self._positions = Positions(0, max_len)
self._start = 0
self._stop = max_len
11 changes: 6 additions & 5 deletions src/class_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

from typing import NamedTuple

from src.class_cursor import Cursor, Positions
from src.class_cursor import Cursor
from src.class_todo import Todo, Todos


class TodoList(NamedTuple):
"""
An object representing the todos
and a cursor (Positions) within the list
and a cursor (start and stop integers) within the list
"""

todos: Todos
cursor: Positions

start: int
stop: int

class _Restorable:
"""
Expand All @@ -39,7 +39,8 @@ def get(self) -> TodoList:

return TodoList(
Todos([Todo(line) for line in self.stored.split(self.SEPARATOR)]),
Positions(self.first, self.last + 1),
self.first,
self.last + 1,
)

def __repr__(self) -> str:
Expand Down
14 changes: 8 additions & 6 deletions todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,17 @@ def _toggle_todo_note(todos: Todos, selected: Cursor) -> None:


def _handle_undo(selected: Cursor, history: UndoRedo) -> Todos:
todos = selected.override_passthrough(*history.undo())
update_file(FILENAME, todos)
return todos
todo_list = history.undo()
selected.set(todo_list.start, todo_list.stop)
update_file(FILENAME, todo_list.todos)
return todo_list.todos


def _handle_redo(selected: Cursor, history: UndoRedo) -> Todos:
todos = selected.override_passthrough(*history.redo())
update_file(FILENAME, todos)
return todos
todo_list = history.redo()
selected.set(todo_list.start, todo_list.stop)
update_file(FILENAME, todo_list.todos)
return todo_list.todos


def _set_fold_state_under(
Expand Down
3 changes: 1 addition & 2 deletions todo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@
- fix: if holding down a key in acurses, make sure it doesn't stay pressed longer than it should (i.e. holding j key) (only reproducible in some terminals)
- fix: acurses preserve terminal from prior to app instantiation
- feat: migrate copied_todo to list of todos and add multiple line paste operation from in app copy
- fix: visual glitch when len(todos) == 1
- feat: remove Positions and integrate functionality into Cursor class directly
- fix: visual glitch when len(todos) == 1

0 comments on commit 4f5bfbc

Please sign in to comment.