80
|
1 |
;;; checklist.el --- Simple checklist UI functionality |
|
2 |
|
|
3 |
;; Copyright (c) 2015 Chris Done. All rights reserved. |
|
4 |
|
|
5 |
;; This file is free software; you can redistribute it and/or modify |
|
6 |
;; it under the terms of the GNU General Public License as published by |
|
7 |
;; the Free Software Foundation; either version 3, or (at your option) |
|
8 |
;; any later version. |
|
9 |
|
|
10 |
;; This file is distributed in the hope that it will be useful, |
|
11 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
;; GNU General Public License for more details. |
|
14 |
|
|
15 |
;; You should have received a copy of the GNU General Public License |
|
16 |
;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 |
|
|
18 |
;;; Code: |
|
19 |
|
|
20 |
(defvar checklist-read-checklist-result nil) |
|
21 |
(make-variable-buffer-local 'checklist-read-checklist-result) |
|
22 |
|
|
23 |
(defun checklist-read-checklist (prompt choices) |
|
24 |
"Prompt with PROMPT to choose one or more from the list of CHOICES." |
|
25 |
(switch-to-buffer (generate-new-buffer-name "checklist")) |
|
26 |
(let ((inhibit-read-only t)) |
|
27 |
(special-mode) |
|
28 |
(setq buffer-read-only t) |
|
29 |
(setq cursor-type 'box) |
|
30 |
(insert (concat prompt "\n\n")) |
|
31 |
(use-local-map (copy-keymap special-mode-map)) |
|
32 |
(local-set-key "n" 'next-line) |
|
33 |
(local-set-key "p" 'previous-line) |
|
34 |
(local-set-key (kbd "RET") 'checklist-checklist-choose) |
|
35 |
(local-set-key (kbd "SPC") 'checklist-checklist-choose) |
|
36 |
(local-set-key (kbd "C-c C-c") 'checklist-checklist-done) |
|
37 |
(save-excursion |
|
38 |
(cl-loop for choice in choices |
|
39 |
do (insert (propertize (concat "[ ] " (cdr choice) "\n") |
|
40 |
'checklist-check-item (car choice)))) |
|
41 |
(insert "\n") |
|
42 |
(insert "Hit " (propertize "C-c C-c" 'face 'bold) " to finish.")) |
|
43 |
(add-hook 'post-command-hook #'checklist-highlight-section t t) |
|
44 |
(setq checklist-read-checklist-result nil) |
|
45 |
(recursive-edit) |
|
46 |
(let ((result checklist-read-checklist-result) |
|
47 |
(kill-buffer-query-functions nil)) |
|
48 |
(kill-buffer (current-buffer)) |
|
49 |
result))) |
|
50 |
|
|
51 |
(defun checklist-checklist-done () |
|
52 |
"Done with the checklist, return the result." |
|
53 |
(interactive) |
|
54 |
(throw 'exit nil)) |
|
55 |
|
|
56 |
(defun checklist-highlight-section () |
|
57 |
"Highlight the item at point." |
|
58 |
(remove-overlays) |
|
59 |
(when (get-text-property (point) 'checklist-check-item) |
|
60 |
(let ((o (make-overlay (line-beginning-position) |
|
61 |
(1+ (line-end-position))))) |
|
62 |
(overlay-put o 'face 'secondary-selection)))) |
|
63 |
|
|
64 |
(defun checklist-checklist-choose () |
|
65 |
"Choose the current item at point." |
|
66 |
(interactive) |
|
67 |
(let ((inhibit-read-only t) |
|
68 |
(checked (get-text-property (point) 'checklist-item-checked))) |
|
69 |
(when (get-text-property (point) 'checklist-check-item) |
|
70 |
(if checked |
|
71 |
(setq checklist-read-checklist-result |
|
72 |
(delete (get-text-property (point) 'checklist-check-item) |
|
73 |
checklist-read-checklist-result)) |
|
74 |
(add-to-list 'checklist-read-checklist-result |
|
75 |
(get-text-property (point) 'checklist-check-item) |
|
76 |
t)) |
|
77 |
(save-excursion (goto-char (line-beginning-position)) |
|
78 |
(delete-region (line-beginning-position) |
|
79 |
(+ (line-beginning-position) (length "[ ]"))) |
|
80 |
(if checked |
|
81 |
(insert "[ ]") |
|
82 |
(insert "[x]"))) |
|
83 |
(put-text-property (line-beginning-position) |
|
84 |
(1+ (line-end-position)) |
|
85 |
'checklist-item-checked (not checked)) |
|
86 |
(put-text-property (line-beginning-position) |
|
87 |
(1+ (line-end-position)) |
|
88 |
'face (if checked nil 'bold)) |
|
89 |
(put-text-property (line-beginning-position) |
|
90 |
(1+ (line-end-position)) |
|
91 |
'checklist-check-item t) |
|
92 |
(checklist-highlight-section)))) |
|
93 |
|
|
94 |
(provide 'checklist) |