diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2012-01-03 01:39:57 +0000 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2012-01-03 01:39:57 +0000 |
commit | 06efef90f270b2113d254f7b800b8f7c0ca44cfc (patch) | |
tree | f61d02ae07f67abeced08bd9654545d2d291bd97 /alot | |
parent | 11958849b95dc77feb2ce1f99f12789d972897cd (diff) | |
parent | 4e45e2f12520bd2dc06549953c3c17993583c244 (diff) |
Merge branch 'feature-sort-145' into testing
Diffstat (limited to 'alot')
-rw-r--r-- | alot/buffers.py | 8 | ||||
-rw-r--r-- | alot/commands/globals.py | 8 | ||||
-rw-r--r-- | alot/commands/search.py | 22 | ||||
-rw-r--r-- | alot/db.py | 17 | ||||
-rw-r--r-- | alot/defaults/alot.rc | 4 | ||||
-rwxr-xr-x | alot/init.py | 18 |
6 files changed, 64 insertions, 13 deletions
diff --git a/alot/buffers.py b/alot/buffers.py index 2aad4a4b..f25b8594 100644 --- a/alot/buffers.py +++ b/alot/buffers.py @@ -134,10 +134,13 @@ class SearchBuffer(Buffer): """ threads = [] - def __init__(self, ui, initialquery=''): + def __init__(self, ui, initialquery='', sort_order=None): self.dbman = ui.dbman self.ui = ui self.querystring = initialquery + default_order = settings.config.get('general', + 'search_threads_sort_order') + self.sort_order = sort_order or default_order self.result_count = 0 self.isinitialized = False self.proc = None # process that fills our pipe @@ -173,7 +176,8 @@ class SearchBuffer(Buffer): self.result_count = self.dbman.count_messages(self.querystring) try: - self.pipe, self.proc = self.dbman.get_threads(self.querystring) + self.pipe, self.proc = self.dbman.get_threads(self.querystring, + self.sort_order) except NotmuchError: self.ui.notify('malformed query string: %s' % self.querystring, 'error') diff --git a/alot/commands/globals.py b/alot/commands/globals.py index 4790d41d..99650353 100644 --- a/alot/commands/globals.py +++ b/alot/commands/globals.py @@ -41,15 +41,18 @@ class ExitCommand(Command): @registerCommand(MODE, 'search', usage='search query', arguments=[ + (['--sort'], {'help':'sort order', 'choices':[ + 'oldest_first', 'newest_first', 'message_id', 'unsorted']}), (['query'], {'nargs':argparse.REMAINDER, 'help':'search string'})]) class SearchCommand(Command): """open a new search buffer""" - def __init__(self, query, **kwargs): + def __init__(self, query, sort=None, **kwargs): """ :param query: notmuch querystring :type query: str """ self.query = ' '.join(query) + self.order = sort Command.__init__(self, **kwargs) def apply(self, ui): @@ -62,7 +65,8 @@ class SearchCommand(Command): if to_be_focused: ui.buffer_focus(to_be_focused) else: - ui.buffer_open(buffers.SearchBuffer(ui, self.query)) + ui.buffer_open(buffers.SearchBuffer(ui, self.query, + sort_order=self.order)) else: ui.notify('empty query string') diff --git a/alot/commands/search.py b/alot/commands/search.py index 4d794dc8..ede8924c 100644 --- a/alot/commands/search.py +++ b/alot/commands/search.py @@ -82,27 +82,39 @@ class ToggleThreadTagCommand(Command): @registerCommand(MODE, 'refine', usage='refine query', arguments=[ + (['--sort'], {'help':'sort order', 'choices':[ + 'oldest_first', 'newest_first', 'message_id', 'unsorted']}), (['query'], {'nargs':argparse.REMAINDER, 'help':'search string'})]) +@registerCommand(MODE, 'sort', usage='set sort order', arguments=[ + (['sort'], {'help':'sort order', 'choices':[ + 'oldest_first', 'newest_first', 'message_id', 'unsorted']}), +]) class RefineCommand(Command): """refine the querystring of this buffer""" - def __init__(self, query=None, **kwargs): + def __init__(self, query=None, sort=None, **kwargs): """ :param query: new querystring given as list of strings as returned by argparse :type query: list of str """ - self.querystring = ' '.join(query) + if query is None: + self.querystring = None + else: + self.querystring = ' '.join(query) + self.sort_order = sort Command.__init__(self, **kwargs) def apply(self, ui): - if self.querystring: + if self.querystring or self.sort_order: sbuffer = ui.current_buffer oldquery = sbuffer.querystring if self.querystring not in [None, oldquery]: sbuffer.querystring = self.querystring sbuffer = ui.current_buffer - sbuffer.rebuild() - ui.update() + if self.sort_order: + sbuffer.sort_order = self.sort_order + sbuffer.rebuild() + ui.update() else: ui.notify('empty query string') @@ -49,6 +49,14 @@ class DBManager(object): lets you look up threads and messages directly to the persistent wrapper classes. """ + _sort_orders = { + 'oldest_first': notmuch.database.Query.SORT.OLDEST_FIRST, + 'newest_first': notmuch.database.Query.SORT.NEWEST_FIRST, + 'unsorted': notmuch.database.Query.SORT.UNSORTED, + 'message_id': notmuch.database.Query.SORT.MESSAGE_ID, + } + """constants representing sort orders""" + def __init__(self, path=None, ro=False): """ :param path: absolute path to the notmuch index @@ -240,18 +248,23 @@ class DBManager(object): sender.close() return receiver, process - def get_threads(self, querystring): + def get_threads(self, querystring, sort='newest_first'): """ asynchronously look up thread ids matching `querystring`. :param querystring: The query string to use for the lookup - :type query: str. + :type querystring: str. + :param sort: Sort order. one of ['oldest_first', 'newest_first', + 'message_id', 'unsorted'] + :type query: str :returns: a pipe together with the process that asynchronously writes to it. :rtype: (:class:`multiprocessing.Pipe`, :class:`multiprocessing.Process`) """ + assert sort in self._sort_orders.keys() q = self.query(querystring) + q.set_sort(self._sort_orders[sort]) return self.async(q.search_threads, (lambda a: a.get_thread_id())) def query(self, querystring): diff --git a/alot/defaults/alot.rc b/alot/defaults/alot.rc index 643864d4..2f07ed9d 100644 --- a/alot/defaults/alot.rc +++ b/alot/defaults/alot.rc @@ -105,6 +105,10 @@ print_cmd = '' # initial command when none is given as argument: initial_command = search tag:inbox AND NOT tag:killed +# default sort order of results in a search +# must be one of one of 'oldest_first', 'newest_first', 'message_id' or 'unsorted' +search_threads_sort_order = newest_first + # in case more than one account has an addressbook: # Set this to True to make tabcompletion for recipients during compose only # look in the abook of the account matching the sender address diff --git a/alot/init.py b/alot/init.py index 8f5665e3..92dde11c 100755 --- a/alot/init.py +++ b/alot/init.py @@ -47,6 +47,18 @@ class ComposeOptions(SubcommandOptions): self['to'] = ' '.join(args) +class SearchOptions(SubcommandOptions): + accepted = ['oldest_first', 'newest_first', 'message_id', 'unsorted'] + def colourint(val): + if val not in accepted: + raise ValueError("Unknown sort order") + return val + colourint.coerceDoc = "Must be one of " + str(accepted) + optParameters = [ + ['sort', 'newest_first', None, 'Sort order'], + ] + + class Options(usage.Options): optFlags = [["read-only", "r", 'open db in read only mode'], ] @@ -74,7 +86,7 @@ class Options(usage.Options): search_help = "start in a search buffer using the querystring provided "\ "as parameter. See the SEARCH SYNTAX section of notmuch(1)." - subCommands = [['search', None, SubcommandOptions, search_help], + subCommands = [['search', None, SearchOptions, search_help], ['compose', None, ComposeOptions, "compose a new message"]] def opt_version(self): @@ -138,7 +150,9 @@ def main(): try: if args.subCommand == 'search': query = ' '.join(args.subOptions.args) - cmd = commands.commandfactory('search ' + query, 'global') + cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(), + query) + cmd = commands.commandfactory(cmdstring, 'global') elif args.subCommand == 'compose': cmdstring = 'compose %s' % args.subOptions.as_argparse_opts() cmd = commands.commandfactory(cmdstring, 'global') |