org-fastup.el 5.1 KB

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