-
-
Notifications
You must be signed in to change notification settings - Fork 286
/
vtask.py
executable file
·105 lines (85 loc) · 4.1 KB
/
vtask.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
'Full terminal interface for TaskWarrior (task).'
import tasklib
from visidata import vd, launchExternalEditorValue, Sheet, ColumnItem, date, vlen, CellColorizer, Column, run
from visidata import *
vd.options.disp_date_fmt = '%Y-%m-%d %H:%M'
vd.option('color_task_changed', 'reverse yellow', 'color when vtask is changed')
def editTask(task):
taskdesc = ''
# pack "key: value" metadata
for k in 'description project status'.split():
taskdesc += '%s: %s\n' % (k, task[k])
# pack annotations separated by ---
for note in task["annotations"]:
taskdesc += "\n---\n"
taskdesc += note.description
# add final sentinel to indicate how to separate if no notes
taskdesc += "\n---\n"
ret = launchExternalEditorValue(taskdesc)
# unpack annotations separated by ---
newnotes = ret.split("\n---\n")
task["annotations"] = newnotes[1:]
# unpack "key: value" metadata
for line in newnotes[0].splitlines():
k, v = line.split(': ', maxsplit=1)
task[k] = v
# task.save()
class TodoSheet(Sheet):
rowtype = 'tasks' # rowdef: tasklib.Task
columns = [
ColumnItem('id', type=int, width=4),
ColumnItem('project'),
ColumnItem('description'),
ColumnItem('status'),
ColumnItem('urgency', type=float, fmtstr='{:.01f}'),
ColumnItem('start', type=date),
ColumnItem('due', type=date),
ColumnItem('wait', type=date, width=0),
ColumnItem('scheduled', type=date, width=0),
ColumnItem('until', type=date, width=0),
ColumnItem('entry', type=date, width=0),
ColumnItem('modified', type=date, width=0),
ColumnItem('completed', type=date, width=0),
# ColumnItem('depends'),
Column('tags', getter=lambda c,r: ' '.join(r["tags"]),
setter=lambda c,r: r["tags"].tags.split(' ')),
# ColumnItem('tags'),
ColumnItem('annotations', type=vlen),
# Column('age', width=3, getter=lambda c,r: date()-r.date_entered), # formatter=duration
]
nKeys = 1
colorizers = Sheet.colorizers + [
CellColorizer(8, 'color_task_changed', lambda s,c,r,v: r and c and isChanged(r, c.name)),
]
def newRow(self, **kwargs):
return tasklib.Task(self.tw, **kwargs)
def reload(self):
self.tw = tasklib.TaskWarrior(data_location=str(self.source), create=True)
self.rows = list(self.tw.tasks.pending())
self.orderBy(None, self.column('urgency'), reverse=True)
def isChanged(r, key):
return r._data.get(key, None) != r._original_data.get(key, None)
class TaskAnnotationsSheet(Sheet):
rowtype = 'notes' # rowdef: TaskAnnotation
columns = [
ColumnItem('entry', type=date),
ColumnItem('description'),
]
def reload(self):
self.rows = self.source['annotations']
TodoSheet.addCommand('^O', 'edit-notes', 'editTask(cursorRow)')
TodoSheet.addCommand('a', 'add-task', 't=newRow(description=input("new task: ")); rows.insert(cursorRowIndex+1, t); t.save(); cursorDown()')
TodoSheet.addCommand('d', 'complete-task', 'cursorRow.done(); cursorRow.refresh()')
TodoSheet.addCommand('gd', 'complete-tasks', 'for r in selectedRows: r.done() or r.refresh()')
TodoSheet.addCommand('zd', 'delete-task', 'cursorRow.delete(); cursorRow.refresh()')
TodoSheet.addCommand('gzd', 'delete-tasks', 'for r in selectedRows: r.delete() or r.refresh()')
TodoSheet.addCommand('z^R', 'refresh-tasks', 'cursorRow.refresh()')
TodoSheet.addCommand('z^S', 'save-task', 'cursorRow.save()')
TodoSheet.addCommand('^S', 'save-modified-tasks', 'list(r.save() for r in rows if r.modified)')
TodoSheet.addCommand(' ', 'start-task', 'cursorRow.stop() if cursorRow["start"] else cursorRow.start()')
TodoSheet.addCommand(ENTER, '', 'vd.push(TaskAnnotationsSheet("cursorRow.description", source=cursorRow))')
TaskAnnotationsSheet.addCommand('a', 'add-task-note', 'source.add_annotation(input("note: ")); reload()')
TaskAnnotationsSheet.addCommand('d', 'delete-task-note', 'source.remove_annotation(cursorRow); reload()')
def main_vtask():
run(TodoSheet('todos', source=Path('~/.task')))
vd.addGlobals(globals())