/
ry-org-scrum.el
144 lines (121 loc) · 4.43 KB
/
ry-org-scrum.el
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
;;; ry-org-scrum.el --- a simple org scrum package -*- lexical-binding: t; -*-
;; Copyright (C) 2018 Ryan Himmelwright
;; Author: Ryan Himmelwright <ryan.himmelwright@gmail.com>
;; Keywords: lisp org scrum
;; URL: https://github.com/himmAllRight/ry-org-scrum
;; Version: 0.0.1
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Just a simple package that contains a few functions to help
;; organize scrum planning in org mode.
;;; Code:
(provide 'ry-org-scrum)
;; Writting some org functions to help me manage my stuff easier.
(defclass ry/task ()
((level :initarg :level :initform 0)
(status :initarg :status :initform nil)
(heading :initarg :heading :initform "")
(tags :initarg :tags :initform nil)
(time :initarg :time :initform 0))
(:documentation "Class for objects to hold info about each task."))
;; An alist to manage the status names and their respective columns in
;; the scrum table.
(setf *columns-alist* '(("Queue" "\n| %s | | | | |")
("Working On" "\n| | %s | | | |")
("On Hold" "\n| | | %s | | |")
("Finished" "\n| | | | %s | |")
("Removed" "\n| | | | | %s |")))
(defun ry/create-scrum-board ()
"Create a new scrum board, with BEGIN and END tags."
(interactive)
(insert (format "#+BEGIN: scrum-board\n"))
(ry/generate-scrum-board)
(insert (format "\n#+END:")))
(defun org-dblock-write:scrum-board (params)
"Add scrum-board as an org-dblock-write"
(ry/generate-scrum-board))
(defun ry/generate-scrum-board ()
"Generates a scrum board from the current buffer."
(interactive)
(let ((task-list (ry/get-tasks-with-status)))
;; Create Header
(insert
(format "|--|\n|%s|\n|--|"
(mapconcat #'car *columns-alist* " | ")))
;; Insert rows for each task
(mapcar #'ry/insert-scrum-board-task
task-list)
;; Align compelted table
(org-table-align)))
(defun ry/insert-scrum-board-task (task)
(let* ((status (oref task :status))
(link-heading (format "[[%s]]" (oref task :heading)))
(str (ry/scrum-row-format-string status)))
;; Only write task it matches a proper status
(when str
(insert (format str link-heading)))))
(defun ry/scrum-row-format-string (status)
"Returns the format string based on status/column placement
using *coumns-alist*."
(let ((var (assoc status *columns-alist* #'string-equal)))
(when var
(cadr var))))
(org-map-entries (lambda () (print (org-heading-components))))
(defun ry/grab-notes ()
(interactive)
(let (output-items)
(org-diary
(lambda ()
(let* ((heading-data (org-heading-components))
(level (elt heading-data 0))
(status (elt heading-data 2))
(heading (elt heading-data 4))
(tags (elt heading-data 5))
(time (org-element-property :TIME (org-element-at-point))))
(when status
(push
(make-instance 'ry/task
:level level
:status status
:heading heading
:tags tags
:time (when time (string-to-number time)))
output-items))))
nil
nil)
(reverse output-items)))
(defun ry/get-tasks-with-status ()
"Returns a list of task objects in the buffer that have a
status marked."
(interactive)
(let (output-items)
(org-map-entries
(lambda ()
(let* ((heading-data (org-heading-components))
(level (elt heading-data 0))
(status (elt heading-data 2))
(heading (elt heading-data 4))
(tags (elt heading-data 5))
(time (org-element-property :TIME (org-element-at-point))))
(when status
(push
(make-instance 'ry/task
:level level
:status status
:heading heading
:tags tags
:time (when time (string-to-number time)))
output-items))))
nil
nil)
(reverse output-items)))
;;; ry-org-scrum.el ends here