Skip to content

Improve sorting and display format in org-agenda #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions ftplugin/orgmode/liborgmode/agenda.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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"""
Expand All @@ -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"""
Expand All @@ -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)
15 changes: 15 additions & 0 deletions ftplugin/orgmode/liborgmode/orgdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Expand Down Expand Up @@ -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)))

Expand Down Expand Up @@ -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)
29 changes: 18 additions & 11 deletions ftplugin/orgmode/plugins/Agenda.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions syntax/orgagenda.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down