Commit 31e43b14 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Restructured the completion class and added date completions.

Date completions are triggered when entering 'due:' or 't:' (depends on
your configuration which tags you use).
parent aab00c3c
......@@ -14,31 +14,93 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import re
from prompt_toolkit.completion import Completer, Completion
from topydo.lib.Config import config
from topydo.Commands import _SUBCOMMAND_MAP
from topydo.lib.RelativeDate import relative_date_to_date
def _date_suggestions():
"""
Returns a list of relative date that is presented to the user as auto
complete suggestions.
"""
# don't use strftime, prevent locales to kick in
days_of_week = {
0: "Monday",
1: "Tuesday",
2: "Wednesday",
3: "Thursday",
4: "Friday",
5: "Saturday",
6: "Sunday"
}
dates = [
'today',
'tomorrow',
]
# show days of week up to next week
dow = datetime.date.today().weekday()
for i in range(dow + 2 % 7, dow + 7):
dates.append(days_of_week[i % 7])
# and some more relative days starting from next week
dates += ["1w", "2w", "1m", "2m", "3m", "1y"]
return dates
class TopydoCompleter(Completer):
def __init__(self, p_todolist):
self.todolist = p_todolist
def _subcommands(self, p_word_before_cursor):
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if sc.startswith(p_word_before_cursor)]
for command in subcommands:
yield Completion(command, -len(p_word_before_cursor))
def _projects(self, p_word_before_cursor):
projects = [p for p in self.todolist.projects() if p.startswith(p_word_before_cursor[1:])]
for project in projects:
yield Completion("+" + project, -len(p_word_before_cursor))
def _contexts(self, p_word_before_cursor):
contexts = [c for c in self.todolist.contexts() if c.startswith(p_word_before_cursor[1:])]
for context in contexts:
yield Completion("@" + context, -len(p_word_before_cursor))
def _dates(self, p_word_before_cursor):
to_absolute = lambda s: relative_date_to_date(s).isoformat()
start_value_pos = p_word_before_cursor.find(':') + 1
value = p_word_before_cursor[start_value_pos:]
for reldate in _date_suggestions():
if not reldate.startswith(value):
continue
yield Completion(reldate, -len(value), display_meta=to_absolute(reldate))
def get_completions(self, p_document, p_complete_event):
# include all characters except whitespaces (for + and @)
word_before_cursor = p_document.get_word_before_cursor(True)
is_first_word = not re.match(r'\s*\S+\s', p_document.current_line_before_cursor)
if is_first_word:
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if sc.startswith(word_before_cursor)]
for command in subcommands:
yield Completion(command, -len(word_before_cursor))
return self._subcommands(word_before_cursor)
elif word_before_cursor.startswith('+'):
projects = [p for p in self.todolist.projects() if p.startswith(word_before_cursor[1:])]
for project in projects:
yield Completion("+" + project, -len(word_before_cursor))
return self._projects(word_before_cursor)
elif word_before_cursor.startswith('@'):
contexts = [c for c in self.todolist.contexts() if c.startswith(word_before_cursor[1:])]
return self._contexts(word_before_cursor)
elif word_before_cursor.startswith(config().tag_due() + ':'):
return self._dates(word_before_cursor)
elif word_before_cursor.startswith(config().tag_start() + ':'):
return self._dates(word_before_cursor)
for context in contexts:
yield Completion("@" + context, -len(word_before_cursor))
return []
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment