mirror of
https://github.com/topydo/topydo.git
synced 2024-05-20 13:58:33 +00:00
edit: Don't move modified todo items to the end of file
Before this patch a `t edit ...` will remove todo items selected by `...` and then do equivalent of `t add` with input from result of editing. This works, but has the property that whenever a todo item is edited, it is always moved till the end of todo.txt file. This property creates noise and makes synchronization harder to implement for some of us who uses VCS and different machines to maintain todo.txt . -> Teach edit to preserve todo items in their places. Adjust existing tests and add a couple more exercising cases where either new todo items are added in the editor, or vice versa, removed in the editor. /cc @mruwek
This commit is contained in:
parent
767bea58a0
commit
09438df104
|
@ -58,7 +58,7 @@ class EditCommandTest(CommandTest):
|
|||
|
||||
self.assertEqual(self.errors, "")
|
||||
self.assertTrue(self.todolist.dirty)
|
||||
self.assertEqual(self.todolist.print_todos(), u"Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1")
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a")
|
||||
|
||||
@mock.patch('topydo.commands.EditCommand._is_edited')
|
||||
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
|
||||
|
@ -75,7 +75,7 @@ class EditCommandTest(CommandTest):
|
|||
|
||||
self.assertTrue(self.todolist.dirty)
|
||||
self.assertEqual(self.errors, "")
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat")
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nLazy Cat\nBaz @test\nFo\u00f3B\u0105\u017a")
|
||||
|
||||
def test_edit03(self):
|
||||
""" Throw an error after invalid todo number given as argument. """
|
||||
|
@ -156,12 +156,49 @@ class EditCommandTest(CommandTest):
|
|||
self.error, None)
|
||||
command.execute()
|
||||
|
||||
expected = u"| 3| Lazy Cat\n| 4| Lazy Dog\n"
|
||||
expected = u"| 2| Lazy Cat\n| 3| Lazy Dog\n"
|
||||
|
||||
self.assertEqual(self.errors, "")
|
||||
self.assertTrue(self.todolist.dirty)
|
||||
self.assertEqual(self.output, expected)
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog")
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nLazy Cat\nLazy Dog\nFo\u00f3B\u0105\u017a")
|
||||
|
||||
@mock.patch('topydo.commands.EditCommand._is_edited')
|
||||
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
|
||||
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
|
||||
def test_edit_addnew(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
|
||||
""" New todos are added in the process of editing. """
|
||||
mock_open_in_editor.return_value = 0
|
||||
mock_todos_from_temp.return_value = [Todo('Bar (edited)'),
|
||||
Todo('New1'),
|
||||
Todo('New 2')]
|
||||
mock_is_edited.return_value = True
|
||||
|
||||
command = EditCommand(["2"], self.todolist, self.out, self.error, None)
|
||||
command.execute()
|
||||
|
||||
self.assertEqual(self.errors, "")
|
||||
self.assertTrue(self.todolist.dirty)
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nBar (edited)\nBaz @test\nFo\u00f3B\u0105\u017a\nNew1\nNew 2")
|
||||
|
||||
@mock.patch('topydo.commands.EditCommand._is_edited')
|
||||
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
|
||||
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
|
||||
def test_edit_remove(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
|
||||
""" Some todos are removed in the process of editing. """
|
||||
mock_open_in_editor.return_value = 0
|
||||
mock_todos_from_temp.return_value = [Todo('Foo (edited)')]
|
||||
|
||||
mock_is_edited.return_value = True
|
||||
|
||||
command = EditCommand(["1", "2"], self.todolist, self.out, self.error, None)
|
||||
command.execute()
|
||||
|
||||
self.assertEqual(self.errors, "")
|
||||
self.assertTrue(self.todolist.dirty)
|
||||
self.assertEqual(self.todolist.print_todos(), u"Foo (edited)\nBaz @test\nFo\u00f3B\u0105\u017a")
|
||||
|
||||
|
||||
|
||||
@mock.patch.dict(os.environ, {'EDITOR': 'vi'})
|
||||
@mock.patch('topydo.commands.EditCommand.check_call')
|
||||
|
|
|
@ -117,10 +117,15 @@ class EditCommand(MultiCommand):
|
|||
new_todos = EditCommand._todos_from_temp(temp_todos)
|
||||
|
||||
if _is_edited(orig_mtime, temp_todos):
|
||||
for todo in self.todos:
|
||||
modified = list(zip(self.todos, new_todos))
|
||||
for (todo, new_todo) in modified:
|
||||
self.todolist.modify_todo(todo, new_todo.src)
|
||||
self.out(self.printer.print_todo(todo))
|
||||
|
||||
for todo in self.todos[len(modified):]:
|
||||
self.todolist.delete(todo, p_leave_tags=True)
|
||||
|
||||
for todo in new_todos:
|
||||
for todo in new_todos[len(modified):]:
|
||||
self.todolist.add_todo(todo)
|
||||
self.out(self.printer.print_todo(todo))
|
||||
else:
|
||||
|
|
|
@ -173,6 +173,13 @@ class TodoListBase(object):
|
|||
# todo item couldn't be found, ignore
|
||||
pass
|
||||
|
||||
def modify_todo(self, p_todo, p_new_source):
|
||||
""" Modify source of a Todo item from the list. """
|
||||
assert p_todo in self._todos
|
||||
p_todo.set_source_text(p_new_source)
|
||||
self._update_todo_ids()
|
||||
self.dirty = True
|
||||
|
||||
def erase(self):
|
||||
""" Erases all todos from the list. """
|
||||
self._todos = []
|
||||
|
|
Loading…
Reference in a new issue