diff options
author | Anton Khirnov <anton@khirnov.net> | 2020-04-19 18:27:49 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2020-04-19 18:27:49 +0200 |
commit | 708f33e83c9cf8a128f0765d49cc38ee6ca0066d (patch) | |
tree | 37c04f318187d59e0b336e4a1ac597a850a59448 /alot | |
parent | ab5af955801972f313f6b7fb541d790b7a1a22bb (diff) |
buffers/search: with walker.py
It is only ever called from here, separating them makes little sense.
Diffstat (limited to 'alot')
-rw-r--r-- | alot/buffers/search.py | 90 | ||||
-rw-r--r-- | alot/commands/search.py | 8 | ||||
-rw-r--r-- | alot/walker.py | 84 |
3 files changed, 82 insertions, 100 deletions
diff --git a/alot/buffers/search.py b/alot/buffers/search.py index b078b109..17023c16 100644 --- a/alot/buffers/search.py +++ b/alot/buffers/search.py @@ -2,13 +2,92 @@ # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file import urwid +import logging from notmuch import NotmuchError from .buffer import Buffer from ..settings.const import settings -from ..walker import PipeWalker from ..widgets.search import ThreadlineWidget +class PipeWalker(urwid.ListWalker): + """urwid.ListWalker that reads next items from a pipe and wraps them in + `containerclass` widgets for displaying + + Attributes that should be considered publicly readable: + :attr lines: the lines obtained from the pipe + :type lines: list(`containerclass`) + """ + def __init__(self, pipe, containerclass, reverse=False, **kwargs): + self.pipe = pipe + self.kwargs = kwargs + self.containerclass = containerclass + self.lines = [] + self.focus = 0 + self.empty = False + self.direction = -1 if reverse else 1 + + def __len__(self): + while not self.empty: + self._get_next_item() + return len(self.lines) + + def get_focus(self): + return self._get_at_pos(self.focus) + + def set_focus(self, focus): + self.focus = focus + self._modified() + + def get_next(self, start_from): + return self._get_at_pos(start_from + self.direction) + + def get_prev(self, start_from): + return self._get_at_pos(start_from - self.direction) + + def remove(self, obj): + next_focus = self.focus % len(self.lines) + if self.focus == len(self.lines) - 1 and self.empty: + next_focus = self.focus - 1 + + self.lines.remove(obj) + if self.lines: + self.set_focus(next_focus) + self._modified() + + def _get_at_pos(self, pos): + if pos < 0: # pos too low + return (None, None) + elif pos > len(self.lines): # pos too high + return (None, None) + elif len(self.lines) > pos: # pos already cached + return (self.lines[pos], pos) + else: # pos not cached yet, look at next item from iterator + if self.empty: # iterator is empty + return (None, None) + else: + widget = self._get_next_item() + if widget: + return (widget, pos) + else: + return (None, None) + + def _get_next_item(self): + if self.empty: + return None + try: + # the next line blocks until it can read from the pipe or + # EOFError is raised. No races here. + next_obj = self.pipe.recv() + next_widget = self.containerclass(next_obj, **self.kwargs) + self.lines.append(next_widget) + except EOFError: + logging.debug('EMPTY PIPE') + next_widget = None + self.empty = True + return next_widget + + def get_lines(self): + return self.lines class SearchBuffer(Buffer): """shows a result list of threads for a query""" @@ -98,14 +177,7 @@ class SearchBuffer(Buffer): thread = threadlinewidget.get_thread() return thread - def consume_pipe(self): - while not self.threadlist.empty: - self.threadlist._get_next_item() - def focus_first(self): self.body.set_focus(0) - def focus_last(self): - self.consume_pipe() - num_lines = len(self.threadlist.get_lines()) - self.body.set_focus(num_lines - 1) + self.body.set_focus(len(self.threadlist) - 1) diff --git a/alot/commands/search.py b/alot/commands/search.py index a20b2220..3741f4c2 100644 --- a/alot/commands/search.py +++ b/alot/commands/search.py @@ -189,13 +189,7 @@ class TagCommand(Command): hitcount_after = ui.dbman.count_messages(testquery) # update total result count if not self.allm: - if hitcount_after == 0: - logging.debug('remove thread from result list: %s', thread) - if threadline_widget in searchbuffer.threadlist: - # remove this thread from result list - searchbuffer.threadlist.remove(threadline_widget) - else: - threadline_widget.rebuild() + threadline_widget.rebuild() searchbuffer.result_count = searchbuffer.dbman.count_messages( searchbuffer.querystring) else: diff --git a/alot/walker.py b/alot/walker.py deleted file mode 100644 index e4264103..00000000 --- a/alot/walker.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (C) 2011-2012 Patrick Totzke <patricktotzke@gmail.com> -# This file is released under the GNU GPL, version 3 or a later revision. -# For further details see the COPYING file -import logging -import urwid - - -class PipeWalker(urwid.ListWalker): - """urwid.ListWalker that reads next items from a pipe and wraps them in - `containerclass` widgets for displaying - - Attributes that should be considered publicly readable: - :attr lines: the lines obtained from the pipe - :type lines: list(`containerclass`) - """ - def __init__(self, pipe, containerclass, reverse=False, **kwargs): - self.pipe = pipe - self.kwargs = kwargs - self.containerclass = containerclass - self.lines = [] - self.focus = 0 - self.empty = False - self.direction = -1 if reverse else 1 - - def __contains__(self, name): - return self.lines.__contains__(name) - - def get_focus(self): - return self._get_at_pos(self.focus) - - def set_focus(self, focus): - self.focus = focus - self._modified() - - def get_next(self, start_from): - return self._get_at_pos(start_from + self.direction) - - def get_prev(self, start_from): - return self._get_at_pos(start_from - self.direction) - - def remove(self, obj): - next_focus = self.focus % len(self.lines) - if self.focus == len(self.lines) - 1 and self.empty: - next_focus = self.focus - 1 - - self.lines.remove(obj) - if self.lines: - self.set_focus(next_focus) - self._modified() - - def _get_at_pos(self, pos): - if pos < 0: # pos too low - return (None, None) - elif pos > len(self.lines): # pos too high - return (None, None) - elif len(self.lines) > pos: # pos already cached - return (self.lines[pos], pos) - else: # pos not cached yet, look at next item from iterator - if self.empty: # iterator is empty - return (None, None) - else: - widget = self._get_next_item() - if widget: - return (widget, pos) - else: - return (None, None) - - def _get_next_item(self): - if self.empty: - return None - try: - # the next line blocks until it can read from the pipe or - # EOFError is raised. No races here. - next_obj = self.pipe.recv() - next_widget = self.containerclass(next_obj, **self.kwargs) - self.lines.append(next_widget) - except EOFError: - logging.debug('EMPTY PIPE') - next_widget = None - self.empty = True - return next_widget - - def get_lines(self): - return self.lines |