summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-11-29 16:38:37 +0100
committerAnton Khirnov <anton@khirnov.net>2021-11-29 16:38:37 +0100
commit503ab8de493481355e8e8b0dc1fbe9fa049353bb (patch)
tree5accdfc22036ebf91474a87b59decaed248c72fa
parentdcd75a8bdb9b723a77713bc722f63e750019d445 (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.py27
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: