summaryrefslogtreecommitdiff
path: root/alot
diff options
context:
space:
mode:
authorPatrick Totzke <patricktotzke@gmail.com>2012-01-03 01:39:57 +0000
committerPatrick Totzke <patricktotzke@gmail.com>2012-01-03 01:39:57 +0000
commit06efef90f270b2113d254f7b800b8f7c0ca44cfc (patch)
treef61d02ae07f67abeced08bd9654545d2d291bd97 /alot
parent11958849b95dc77feb2ce1f99f12789d972897cd (diff)
parent4e45e2f12520bd2dc06549953c3c17993583c244 (diff)
Merge branch 'feature-sort-145' into testing
Diffstat (limited to 'alot')
-rw-r--r--alot/buffers.py8
-rw-r--r--alot/commands/globals.py8
-rw-r--r--alot/commands/search.py22
-rw-r--r--alot/db.py17
-rw-r--r--alot/defaults/alot.rc4
-rwxr-xr-xalot/init.py18
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')
diff --git a/alot/db.py b/alot/db.py
index 26da8883..69256ea1 100644
--- a/alot/db.py
+++ b/alot/db.py
@@ -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')