Commit dca02e2b authored by Bram Schoenmakers's avatar Bram Schoenmakers

Add %n, %N, %u and %U in the formatting for identifiers

%n: Line number
%N: Padded line number
%u: Text-based ID
%U: Padded text-based ID

Addresses issue #184.
parent b4c7b0a0
......@@ -718,6 +718,65 @@ x 2014-12-12 Completed but with date:2014-12-12
self.assertEqual(self.output, '')
self.assertEqual(self.errors, error)
def test_list_format48(self):
"""
Test line numbers
"""
command = ListCommand(["-F %n"], self.todolist, self.out, self.error)
command.execute()
result = """ 1
3
4
5
"""
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_list_format49(self):
"""
Test padded line numbers
"""
command = ListCommand(["-F %N"], self.todolist, self.out, self.error)
command.execute()
result = """ 1
3
4
5
"""
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_list_format50(self):
"""
Test line numbers
"""
command = ListCommand(["-F %u"], self.todolist, self.out, self.error)
command.execute()
result = """ mfg
t5c
n8m
wa5
"""
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_list_format51(self):
"""
Test padded identifiers
"""
command = ListCommand(["-F %U"], self.todolist, self.out, self.error)
command.execute()
result = """ mfg
t5c
n8m
wa5
"""
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
if __name__ == '__main__':
unittest.main()
......@@ -226,6 +226,11 @@ class TodoListTester(TopydoTest):
config(p_overrides={('topydo', 'identifiers'): 'linenumber'})
self.assertRaises(InvalidTodoException, self.todolist.todo, '11a')
def test_uid5(self):
""" Handle bogus UIDs """
todo = Todo('invalid')
self.assertRaises(InvalidTodoException, self.todolist.uid, todo)
def test_new_uid(self):
""" Make sure that item has new text ID after append. """
config("test/data/todolist-uid.conf")
......
......@@ -176,6 +176,12 @@ class ListFormatParser(object):
'K': lambda t: ' '.join([u'{}:{}'.format(tag, value)
for tag, value in sorted(t.tags())]),
# line number
'n': lambda t: str(self.todolist.linenumber(t)),
# line number, pre-filled with 1 or 2 spaces if its length <3
'N': lambda t: _filler(str(self.todolist.linenumber(t)), 3),
# priority
'p': lambda t: t.priority() if t.priority() else '',
......@@ -197,6 +203,12 @@ class ListFormatParser(object):
# relative start date
'T': lambda t: humanize_date(t.start_date()) if t.start_date() else '',
# unique text ID
'u': lambda t: self.todolist.uid(t),
# unique text ID, pre-filled with 1 or 2 spaces if its length <3
'U': lambda t: _filler(self.todolist.uid(t), 3),
# absolute completion date
'x': lambda t: 'x ' + t.completion_date().isoformat() if t.is_completed() else '',
......
......@@ -247,18 +247,33 @@ class TodoListBase(object):
p_todo.set_priority(p_priority)
self.dirty = True
def linenumber(self, p_todo):
"""
Returns the line number of the todo item.
"""
try:
return self._todos.index(p_todo) + 1
except ValueError as ex:
raise InvalidTodoException from ex
def uid(self, p_todo):
"""
Returns the unique text-based ID for a todo item.
"""
try:
return self._todo_id_map[p_todo]
except KeyError as ex:
raise InvalidTodoException from ex
def number(self, p_todo):
"""
Returns the line number or text ID of a todo (depends on the
configuration.
"""
try:
if config().identifiers() == 'text':
return self._todo_id_map[p_todo]
else:
return self._todos.index(p_todo) + 1
except (ValueError, KeyError) as ex:
raise InvalidTodoException from ex
if config().identifiers() == "text":
return self.uid(p_todo)
else:
return self.linenumber(p_todo)
def _update_todo_ids(self):
# the idea is to have a hash that is independent of the position of the
......
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