diff options
author | pazz <patricktotzke@gmail.com> | 2011-07-20 22:21:09 +0100 |
---|---|---|
committer | pazz <patricktotzke@gmail.com> | 2011-07-20 22:21:27 +0100 |
commit | 5e2eca8e2778ec4cd130af8881f01163e745c0a1 (patch) | |
tree | c37da6ab6ea3bfee9aac44b16609acb232aeab30 | |
parent | ef2edc0210377f02638eb30ed3f09c67410f6569 (diff) |
tabcompletion yea!
issue #50
-rw-r--r-- | alot/commands.py | 11 | ||||
-rw-r--r-- | alot/completion.py | 83 | ||||
-rw-r--r-- | alot/settings.py | 6 | ||||
-rw-r--r-- | alot/ui.py | 4 |
4 files changed, 82 insertions, 22 deletions
diff --git a/alot/commands.py b/alot/commands.py index 2b8d312a..936a376b 100644 --- a/alot/commands.py +++ b/alot/commands.py @@ -35,7 +35,8 @@ from settings import get_account_by_address from settings import get_accounts from db import DatabaseROError from db import DatabaseLockedError -import completion +from completion import ContactsCompleter +from completion import AccountCompleter import helper @@ -390,11 +391,12 @@ class ComposeCommand(Command): a = accounts[0] else: # TODO: completer for accounts - fromaddress = ui.prompt(prefix='From>') + cmpl = AccountCompleter() + fromaddress = ui.prompt(prefix='From>',completer=cmpl) validaddresses = [a.address for a in accounts] + [None] while fromaddress not in validaddresses: ui.notify('couldn\'t find a matching account. (<esc> cancels)') - fromaddress = ui.prompt(prefix='From>') + fromaddress = ui.prompt(prefix='From>',completer=cmpl) if not fromaddress: ui.notify('canceled') return @@ -403,7 +405,8 @@ class ComposeCommand(Command): #get To header if 'To' not in self.headers: - self.headers['To'] = ui.prompt(prefix='To>') + self.headers['To'] = ui.prompt(prefix='To>', + completer=ContactsCompleter()) if config.getboolean('general', 'ask_subject') and \ not 'Subject' in self.headers: self.headers['Subject'] = ui.prompt(prefix='Subject>') diff --git a/alot/completion.py b/alot/completion.py index 10ff7b28..fcfc4d57 100644 --- a/alot/completion.py +++ b/alot/completion.py @@ -20,6 +20,7 @@ Copyright (C) 2011 Patrick Totzke <patricktotzke@gmail.com> import re import commandfactory +import settings class Completer: @@ -34,40 +35,63 @@ class QueryCompleter(Completer): # TODO: boolean connectors and braces? def __init__(self, dbman): self.dbman = dbman + self._contactscompleter = ContactsCompleter() + self._tagscompleter = TagsCompleter(dbman) self.keywords = ['tag', 'from', 'to', 'subject', 'attachment', 'is', 'id', 'thread', 'folder'] def complete(self, original): - lastbit = prefix = original.split(' ')[-1] - m = re.findall('[tag|is]:(\w*)', lastbit) + prefix = original.split(' ')[-1] + m = re.search('(tag|is|to):(\w*)', prefix) if m: - prefix = m[0] - plen = len(prefix) - tags = self.dbman.get_all_tags() - matched = filter(lambda t: t.startswith(prefix), tags) - return [t[plen:] + ' ' for t in matched] + cmd, params = m.groups() + if cmd == 'to': + return self._contactscompleter.complete(params) + else: + return self._tagscompleter.complete(params, last=True) else: - prefix = original.split(' ')[-1] plen = len(prefix) matched = filter(lambda t: t.startswith(prefix), self.keywords) return [t[plen:] + ':' for t in matched] -class TagListCompleter(Completer): +class TagsCompleter(Completer): """completion for a comma separated list of tagstrings""" def __init__(self, dbman): self.dbman = dbman - def complete(self, original): - taglist = original.split(',') - prefix = taglist[-1] + def complete(self, original, last=False): + otags = original.split(',') + prefix = otags[-1] tags = self.dbman.get_all_tags() - return [t[len(prefix):] + ',' for t in tags if t.startswith(prefix)] + if len(otags)>1 and last: + return [] + else: + matching = [t[len(prefix):] for t in tags if t.startswith(prefix)] + if last: + return matching + else: + return [t + ',' for t in matching] + + +class ContactsCompleter(Completer): + """completes contacts""" + def complete(self, prefix): + # TODO + return [] + + +class AccountCompleter(Completer): + """completes own mailaddresses""" + + def complete(self, prefix): + valids = settings.get_account_addresses() + return [a[len(prefix):] for a in valids if a.startswith(prefix)] class CommandCompleter(Completer): - """completion for commandline""" + """completes commands""" def __init__(self, dbman, mode): self.dbman = dbman @@ -77,4 +101,33 @@ class CommandCompleter(Completer): #TODO refine <tab> should get current querystring cmdlist = commandfactory.ALLOWED_COMMANDS[self.mode] olen = len(original) - return [t[olen:] + ' ' for t in cmdlist if t.startswith(original)] + return [t[olen:] + '' for t in cmdlist if t.startswith(original)] + + +class CommandLineCompleter(Completer): + """completion for commandline""" + + def __init__(self, dbman, mode): + self.dbman = dbman + self.mode = mode + self._commandcompleter = CommandCompleter(dbman, mode) + self._querycompleter = QueryCompleter(dbman) + self._tagscompleter = TagsCompleter(dbman) + self._contactscompleter = ContactsCompleter() + + def complete(self, prefix): + words = prefix.split(' ',1) + if len(words)<=1: # we complete commands + return self._commandcompleter.complete(prefix) + else: + cmd, params = words + if cmd in ['search', 'refine']: + return self._querycompleter.complete(params) + if cmd == 'retag': + return self._tagscompleter.complete(params) + if cmd == 'toggletag': + return self._tagscompleter.complete(params, last=True) + if cmd == 'to': + return self._contactscompleter.complete(params) + else: + return [] diff --git a/alot/settings.py b/alot/settings.py index 24eb2b1d..c7a07619 100644 --- a/alot/settings.py +++ b/alot/settings.py @@ -296,13 +296,17 @@ def get_accounts(): def get_account_by_address(address): - accounts = get_accounts() + accounts = ACCOUNTS matched = [a for a in accounts if a.address == address] if len(matched) == 1: return matched.pop() else: return None + +def get_account_addresses(): + return [a.address for a in get_accounts()] + # maps mode to keybingins: for each one, # a key is mapped to a pair cmdline, helpstring. MAPPING = { @@ -27,7 +27,7 @@ from buffer import BufferListBuffer from commandfactory import commandfactory from commandfactory import interpret_commandline from widgets import CompleteEdit -from completion import CommandCompleter +from completion import CommandLineCompleter class UI: @@ -109,7 +109,7 @@ class UI: mode = self.current_buffer.typename cmdline = self.prompt(prefix=':', text=startstring, - completer=CommandCompleter(self.dbman, mode)) + completer=CommandLineCompleter(self.dbman, mode)) if cmdline: cmd = interpret_commandline(cmdline, mode) if cmd: |