diff options
author | Anton Khirnov <anton@khirnov.net> | 2021-11-29 16:38:37 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2021-11-29 16:38:37 +0100 |
commit | 503ab8de493481355e8e8b0dc1fbe9fa049353bb (patch) | |
tree | 5accdfc22036ebf91474a87b59decaed248c72fa | |
parent | dcd75a8bdb9b723a77713bc722f63e750019d445 (diff) |
buffers/search: allow displaying results in reverse
Not hooked up to any commands, so not actually usable yet.
Note that oldest_first and newest_first sort orders are not inverses of
each other, because oldest_first uses the oldest message in the thread
for sorting, while newest_first uses the newest one.
This option applies on top of that sorting to display results from the
end to the beginning. This requires reading the whole result list first,
so can be slow for queries with many results.
-rw-r--r-- | alot/buffers/search.py | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/alot/buffers/search.py b/alot/buffers/search.py index 3adce6ed..45d20b30 100644 --- a/alot/buffers/search.py +++ b/alot/buffers/search.py @@ -21,6 +21,7 @@ class IterWalker(urwid.ListWalker): _threads = None _wgt_factory = None + _reverse = None _iter_done = False @@ -31,9 +32,10 @@ class IterWalker(urwid.ListWalker): _focus = None - def __init__(self, threads, wgt_factory): + def __init__(self, threads, wgt_factory, reverse): self._threads = threads self._wgt_factory = wgt_factory + self._reverse = reverse self._tids = [] self._wgts = {} @@ -47,26 +49,33 @@ class IterWalker(urwid.ListWalker): self._get_next_item() return len(self._tids) + def _map_pos(self, pos): + if self._reverse: + pos = len(self) - 1 - pos + return pos + def __getitem__(self, pos): self._check_pos(pos) if not pos in self._wgts: # make sure an exception while constructing the widget does not get # swallowed by urwid try: - self._wgts[pos] = self._wgt_factory(self._tids[pos]) + self._wgts[pos] = self._wgt_factory(self._tids[self._map_pos(pos)]) except (KeyError, IndexError, TypeError) as e: raise ValueError('Exception while constructing threadline widget') from e return self._wgts[pos] def _check_pos(self, pos): - if pos < 0: + tgt_pos = self._map_pos(pos) + + if tgt_pos < 0: raise IndexError - while not self._iter_done and pos >= len(self._tids): + while not self._iter_done and tgt_pos >= len(self._tids): self._get_next_item() - if pos >= len(self._tids): + if tgt_pos >= len(self._tids): raise IndexError return pos @@ -98,15 +107,19 @@ class SearchBuffer(Buffer): modename = 'search' + sort_order = None + reverse = None + _message_count = None _thread_count = None - def __init__(self, ui, initialquery='', sort_order=None): + def __init__(self, ui, initialquery='', sort_order=None, reverse = False): self.dbman = ui.dbman self.ui = ui self.querystring = initialquery default_order = SORT_NAME[settings.get('search_threads_sort_order')] self.sort_order = sort_order or default_order + self.reverse = reverse self.rebuild() super().__init__() @@ -169,7 +182,7 @@ class SearchBuffer(Buffer): exclude_tags) wgt_factory = partial(ThreadlineWidget, dbman = self.dbman, query = self.querystring) - threadlist = IterWalker(threads, wgt_factory) + threadlist = IterWalker(threads, wgt_factory, self.reverse) # check that the query is well-formed try: |