Skip to content

Commit

Permalink
loop
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Oct 23, 2024
1 parent d005b54 commit ac85f28
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 29 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

### Added

- Added `immediate` parameter to scroll methods https://github.com/Textualize/textual/pull/5164
- Added `textual._loop.loop_from_index` https://github.com/Textualize/textual/pull/5164

## [0.84.0] - 2024-10-22

### Fixed
Expand Down
37 changes: 12 additions & 25 deletions src/textual/_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def loop_first_last(values: Iterable[T]) -> Iterable[tuple[bool, bool, T]]:


def loop_from_index(
values: Sequence[T], index: int, direction: Literal[+1, -1] = +1
values: Sequence[T], index: int, direction: Literal[+1, -1] = +1, wrap: bool = True
) -> Iterable[tuple[int, T]]:
"""Iterate over values in a sequence from a given starting index, wrapping the index
if it would go out of bounds.
Expand All @@ -55,32 +55,19 @@ def loop_from_index(
values: A sequence of values.
index: Starting index.
direction: Direction to move index (+1 for forward, -1 for backward).
bool: Should the index wrap when out of bounds?
Yields:
A tuple of index and value from the sequence.
"""
count = len(values)
for _ in range(count):
index = (index + direction) % count
yield (index, values[index])


def loop_from_index_no_wrap(
values: Sequence[T], index: int, direction: Literal[+1, -1] = +1
) -> Iterable[tuple[int, T]]:
"""Iterate over values in a sequence from a given starting index, without wrapping the index.
Args:
values: A sequence of values.
index: Starting index.
direction: Direction to move index (+1 for forward, -1 for backward).
Yields:
A tuple of index and value from the sequence.
"""
count = len(values)
maxima = (-1, count)
for _ in range(count):
if (index := index + direction) in maxima:
break
yield (index, values[index])
if wrap:
maxima = (-1, count)
for _ in range(count):
if (index := index + direction) in maxima:
break
yield (index, values[index])
else:
for _ in range(count):
index = (index + direction) % count
yield (index, values[index])
8 changes: 4 additions & 4 deletions src/textual/widgets/_list_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from typing_extensions import TypeGuard

from textual._loop import loop_from_index_no_wrap
from textual._loop import loop_from_index
from textual.await_remove import AwaitRemove
from textual.binding import Binding, BindingType
from textual.containers import VerticalScroll
Expand Down Expand Up @@ -280,7 +280,7 @@ def action_cursor_down(self) -> None:
self.index = 0
else:
index = self.index
for index, item in loop_from_index_no_wrap(self._nodes, self.index):
for index, item in loop_from_index(self._nodes, self.index, wrap=False):
if not item.disabled:
self.index = index
break
Expand All @@ -291,8 +291,8 @@ def action_cursor_up(self) -> None:
if self._nodes:
self.index = len(self._nodes) - 1
else:
for index, item in loop_from_index_no_wrap(
self._nodes, self.index, direction=-1
for index, item in loop_from_index(
self._nodes, self.index, direction=-1, wrap=False
):
if not item.disabled:
self.index = index
Expand Down

0 comments on commit ac85f28

Please sign in to comment.