Intermediate state, I am just trying comiting now.
[org-mode.git] / EXPERIMENTAL / org-fastup.el
bloba791c5f6b3c834a9f013633bbe01398df3e0ba8c
1 ;; Then I don't really thing you would have to be able to customize
2 ;; this, as there are only very few operations for which this makes
3 ;; sense:
5 ;; A**** Archive
6 ;; T**** Mark TODO
7 ;; D**** Mark DONE
8 ;; N**** Cycle TODO to the next state
10 ;; Can't really think of anything else.
13 ;; I prefer configurable, because then people can use numbers. This is
14 ;; the idea that the editor may have limited UI. I'm using a j2me based
15 ;; editor called JPE at the moment:
16 ;; http://my-communicator.com/s80/software/applications.php?fldAuto=556&faq=2
18 ;; But other people may be using something like this:
19 ;; http://www.getjar.com/products/3960/TextEditor
21 ;; Or this which i'm currently playing with:
22 ;; http://www.bermin.net/index.html
24 ;; As for other things, it depends on what you want emacs to be able to
25 ;; do with an externally changed org mode file. For me this is about
26 ;; using org mode in an intelligent way with my mobile phone/pda. I can
27 ;; imagine wanting to write functions like:
29 ;; * move this huge piece of text and tables down a level
30 ;; <* move this huge piece of text and tables up a level
31 ;; M* ask to recategorise this heading when i open org mode
32 ;; +* remind me about this when i open org mode so i can brain dump on it
33 ;; in a real editor.
34 ;; D* ask me to schedule this as an event when i open org mode.
35 ;; O* open my mail client to send an email to this email address i just got
36 ;; C* search bbdb for the contact details of the phone no on this line.
37 ;; c* search ldap for the contact details of this name
38 ;; B* open a web browser to this link i wanted to check out when i got back to my machine
39 ;; R* remind me to look at TheseSearchTags headings when i get back to my machine.
42 (defcustom org-fastup-action-alist
43 '((?A org-archive t)
44 (?T (org-todo 1) nil)
45 (?D (org-todo (length org-todo-keywords)) nil)
46 (?N org-todo nil)
47 (?< org-promote-subtree t)
48 (?> org-demote-subtree t)
49 (?M org-set-tags nil)
50 (?S org-schedule t))
51 "List of fastupdate actions.
52 Each entry in this list is a list of 3 items:
54 - A character representing the fastupdate action
55 - A function or form to be executed, with cursor at beginning of headline
56 - A flag indicating if execution of this action should normally be confirmed."
57 :group 'org-fastup
58 :type '(repeat
59 (list :value (?a nil t)
60 (character :tag "Prefix char")
61 (choice
62 (const :tag "Archive this subtree" org-archive)
63 (const :tag "Make TODO" (org-todo 1))
64 (const :tag "Mark DONE" (org-todo (length org-todo-keywords)))
65 (const :tag "Cycle TODO" org-todo)
66 (const :tag "Promote subtree" org-promote-subtree)
67 (const :tag "Demote subtree" org-demote-subtree)
68 (const :tag "Set Tags" org-set-tags)
69 (const :tag "Schedule" org-schedule)
70 (const :tag "Set Deadline" org-schedule)
71 (sexp))
72 (boolean :tag "Confirm"))))
74 (defun org-fastup-check-buffer ()
75 "Check for and execute fastupdate actions.
76 This first checks if there are any fastupdate actions in the buffer.
77 If yes, the user is asked for a processing mode, with three possibilities
78 with respect to confirming actions:
80 Always confirm each action before executing it
81 Never execute all actions without prior confirmation
82 Maybe get only confirmation for actions that have been configured
83 as requiring confirmation in `org-fastup-action-alist'.
85 The command will then walk through the buffer, stop at each eaction
86 and do the right thing there."
87 (interactive)
88 (show-all) ; make everything visible
89 (let ((start (point-min))
90 ;; FIXME: should I limit the regexp to match existing actions?
91 ;; I think not, to catch typos
92 (re "^\\([-a-zA-Z0-9!@#$%^&+?<>]\\)\\*+")
93 s action confirm)
94 (if (not (save-excursion
95 (goto-char (point-min))
96 (re-search-forward re nil t)))
97 (if (interactive-p) (message "No fastupdate actions in this buffer"))
98 (goto-char start)
99 (message "Fastupdate: Confirm actions [A]lways [Maybe] [N]ever, or [Q]uit?")
100 (setq reaction (read-char-exclusive))
101 (cond
102 ((memq reaction '(?q ?Q)) (error "Abort"))
103 ((memq reaction '(?a ?A)) (setq cf 'always))
104 ((memq reaction '(?m ?M)) (setq cf 'maybe))
105 ((memq reaction '(?n ?N)) (setq cf 'never)))
106 (while (re-search-forward re nil t)
107 (goto-char (setq start (match-beginning 0)))
108 (setq s (match-string 1)
109 entry (assoc (string-to-char s) org-fastup-action-alist)
110 action (nth 1 entry)
111 confirm (nth 2 entry))
112 (cond
113 ((null action)
114 (if (y-or-n-p "Unknown action. Remove fastupdate character? ")
115 (delete-region start (1+ start))
116 (goto-char (1+ start))))
117 ((or (equal cf 'never)
118 (and (eq cf 'maybe) (not confirm))
119 (y-or-n-p (format "execute action [%s] " s)))
120 (delete-region start (1+ start))
121 ;; FIXME: wrap the following into condition-case and
122 ;; handle any errors in some way.
123 (if (symbolp action) (funcall action) (eval action))
124 ;; FIXME: remove the sit-for
125 (sit-for 2))
127 (if (y-or-n-p "Action denied. Remove fastupdate character? ")
128 ;; Remove the character, without action.
129 (delete-region start (1+ start))
130 ;; Just leave the character in and skip this location
131 (goto-char (1+ start)))))))))