diff --git a/ftplugin/orgmode/liborgmode/agenda.py b/ftplugin/orgmode/liborgmode/agenda.py index d19e8c7..149be99 100644 --- a/ftplugin/orgmode/liborgmode/agenda.py +++ b/ftplugin/orgmode/liborgmode/agenda.py @@ -16,7 +16,28 @@ from orgmode.liborgmode.agendafilter import is_within_week_and_active_todo from orgmode.liborgmode.agendafilter import contains_active_todo from orgmode.liborgmode.agendafilter import contains_active_date +from orgmode.liborgmode.orgdate import OrgDateTime, OrgTimeRange +import datetime +def agenda_sorting_key(heading): + orgtime = heading.active_date + if orgtime is None or isinstance(orgtime, OrgDateTime): + return orgtime + if isinstance(orgtime, OrgTimeRange): + return orgtime.start + + # It is an OrgDate. OrgDate cannot be compared with datetime-based Org* values by + # default, so it will be converted in such a way that: + # * OrgDate value of _today_ will be displayed after today's passed events and before + # today's upcoming scheduled events. + # * OrgDate value of a past day will be displayed after all other items of the same + # day. + # * OrgDate value of a future day will be displayed before all other items of the same + # day. + now = datetime.datetime.now() + today = now.date() + time_to_add = now.time() if today == orgtime else datetime.time(0, 0) if today < orgtime else datetime.time(23, 59) + return datetime.datetime.combine(orgtime, time_to_add) class AgendaManager(object): u"""Simple parsing of Documents to create an agenda.""" @@ -34,7 +55,7 @@ def get_todo(self, documents): # filter and return headings filtered.extend(filter_items(document.all_headings(), [contains_active_todo])) - return sorted(filtered) + return sorted(filtered, key=agenda_sorting_key) def get_next_week_and_active_todo(self, documents): u""" @@ -46,7 +67,7 @@ def get_next_week_and_active_todo(self, documents): # filter and return headings filtered.extend(filter_items(document.all_headings(), [is_within_week_and_active_todo])) - return sorted(filtered) + return sorted(filtered, key=agenda_sorting_key) def get_timestamped_items(self, documents): u""" @@ -58,4 +79,4 @@ def get_timestamped_items(self, documents): # filter and return headings filtered.extend(filter_items(document.all_headings(), [contains_active_date])) - return sorted(filtered) + return sorted(filtered, key=agenda_sorting_key) diff --git a/ftplugin/orgmode/liborgmode/orgdate.py b/ftplugin/orgmode/liborgmode/orgdate.py index b236506..91fdc03 100644 --- a/ftplugin/orgmode/liborgmode/orgdate.py +++ b/ftplugin/orgmode/liborgmode/orgdate.py @@ -190,6 +190,12 @@ def __unicode__(self): def __str__(self): return u_encode(self.__unicode__()) + def timestr(self): + return '--:--' + + def date(self): + return self + def strftime(self, fmt): return u_decode(datetime.date.strftime(self, u_encode(fmt))) @@ -222,6 +228,12 @@ def __unicode__(self): def __str__(self): return u_encode(self.__unicode__()) + def timestr(self): + return self.strftime('%H:%M') + + def date(self): + return OrgDate(self.active, self.year, self.month, self.day) + def strftime(self, fmt): return u_decode(datetime.datetime.strftime(self, u_encode(fmt))) @@ -292,3 +304,6 @@ def __unicode__(self): def __str__(self): return u_encode(self.__unicode__()) + + def date(self): + return OrgDate(self.active, self.start.year, self.start.month, self.start.day) diff --git a/ftplugin/orgmode/plugins/Agenda.py b/ftplugin/orgmode/plugins/Agenda.py index ed5faa6..017c7f2 100644 --- a/ftplugin/orgmode/plugins/Agenda.py +++ b/ftplugin/orgmode/plugins/Agenda.py @@ -171,32 +171,39 @@ def list_next_week_for(cls, agenda_documents): # It's easy to jump to the right document this way cls.line2doc = {} # format text for agenda - last_date = raw_agenda[0].active_date - final_agenda = [u'Week Agenda:', unicode(last_date)] + last_date = None + final_agenda = [u'Week Agenda:'] for i, h in enumerate(raw_agenda): # insert date information for every new date (not datetime) - if unicode(h.active_date)[1:11] != unicode(last_date)[1:11]: + active_date_no_time = h.active_date.date() + if active_date_no_time != last_date: today = date.today() # insert additional "TODAY" string - if h.active_date.year == today.year and \ - h.active_date.month == today.month and \ - h.active_date.day == today.day: - section = unicode(h.active_date) + u" TODAY" + if active_date_no_time == today: + section = unicode(active_date_no_time) + u" TODAY" today_row = len(final_agenda) + 1 else: - section = unicode(h.active_date) + section = unicode(active_date_no_time) final_agenda.append(section) # update last_date - last_date = h.active_date + last_date = active_date_no_time + + p = h + tags = [] + while p is not None: + tags += p.tags + p = p.parent bufname = os.path.basename(vim.buffers[h.document.bufnr].name) bufname = bufname[:-4] if bufname.endswith(u'.org') else bufname - formatted = u" %(bufname)s (%(bufnr)d) %(todo)s %(title)s" % { + formatted = u" %(bufname)s (%(bufnr)d) %(todo)s %(timestr)s %(title)s %(tags)s" % { 'bufname': bufname, 'bufnr': h.document.bufnr, 'todo': h.todo, - 'title': h.title + 'timestr': h.active_date.timestr(), + 'title': h.title, + 'tags': ':' + ':'.join(tags) + ':' if tags else '' } final_agenda.append(formatted) cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start) diff --git a/syntax/orgagenda.vim b/syntax/orgagenda.vim index 3ea4fad..32f66cd 100644 --- a/syntax/orgagenda.vim +++ b/syntax/orgagenda.vim @@ -5,6 +5,18 @@ syn match org_todo_key /\[\zs[^]]*\ze\]/ hi def link org_todo_key Identifier +" Multi-colored tags in agenda +syn match org_tag_1 /:[a-iA-I][^: ]*:/hs=s+1,me=e-1 +syn match org_tag_2 /:[j-rJ-R][^: ]*:/hs=s+1,me=e-1 +syn match org_tag_3 /:[s-zS-Z0][^: ]*:/hs=s+1,me=e-1 +syn match org_tag_4 /:[1-9_][^: ]*:/hs=s+1,me=e-1 +syn match org_tag_5 /:[\W][^: ]*:/hs=s+1,me=e-1 +hi def link org_tag_1 Title +hi def link org_tag_2 Constant +hi def link org_tag_3 Statement +hi def link org_tag_4 Type +hi def link org_tag_5 Special + let s:todo_headings = '' let s:i = 1 while s:i <= g:org_heading_highlight_levels