Started using org-mode and I've gotten to configuring the org-capture template. Would like to get a simple set-up going for starters.
I've bound 'org-capture to C-c c so C-c c C gives me the org-capture-templates interface - supposedly a good way to configure a template.
But how do I interact with this interface?
Consulted the org-manual but haven't found mention how how the customize interface actually work ...
I find that I have more control over my user customization file when I edit it manually, which lets me decide at what location entries are stored and I choose the format that suits my needs. Always remember to keep daily backups just in case something goes awry. The vast majority of examples that I generally see on the internet contemplate that the user will copy and paste the sample code into his / her user customization file, rather than using the built-in customization interface.
This is what I use for tasks, events, contacts, undated, etc. I also use a modified version of org-toodledo and synchronize with the Toodledo server so that my hand-held devices and computers can all synchronize in the cloud: https://github.com/christopherjwhite/org-toodledo
(setq org-todo-keywords '(
(sequence
"Active(a)"
"Next Action(n)"
"Canceled(c)"
"Hold(h)"
"Reference(r)"
"Delegated(d)"
"Waiting(w)"
"Postponed(P)"
"Someday(s)"
"Planning(p)"
"|"
"None(N)") ))
(setq org-capture-templates '(
("a" "Active" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "TASKS")
"** Active [#A] %?\n DEADLINE: <%<%Y-%m-%d %a>>\n :PROPERTIES:\n :ToodledoFolder: TASKS\n :END:"
:empty-lines 1)
("n" "Next Action" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "TASKS")
"** Next Action [#A] %?\n DEADLINE: <%<%Y-%m-%d %a>>\n :PROPERTIES:\n :ToodledoFolder: TASKS\n :END:"
:empty-lines 1)
("s" "Someday" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "UNDATED")
"** Someday [#D] %?\n :PROPERTIES:\n :ToodledoFolder: UNDATED\n :END:"
:empty-lines 1)
("r" "Reference" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "EVENTS")
"** Reference [#A] %? :event:\n DEADLINE: <%<%Y-%m-%d %a 08:30>> SCHEDULED: <%<%Y-%m-%d %a>>\n :PROPERTIES:\n :ToodledoFolder: EVENTS\n :END:"
:empty-lines 1)
("d" "Delegated" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "EVENTS")
"** Delegated [#A] %? :event:\n DEADLINE: <%<%Y-%m-%d %a 08:30>> SCHEDULED: <%<%Y-%m-%d %a>>\n :PROPERTIES:\n :ToodledoFolder: EVENTS\n :END:"
:empty-lines 1)
("w" "Waiting" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "EVENTS")
"** Waiting [#A] %? :event:\n DEADLINE: <%<%Y-%m-%d %a 08:30>> SCHEDULED: <%<%Y-%m-%d %a>>\n :PROPERTIES:\n :ToodledoFolder: EVENTS\n :END:"
:empty-lines 1)
("p" "Planning" entry (file+headline "/Users/HOME/.0.data/.0.emacs/.todo" "CONTACTS")
"** Planning [#D] %?\n :PROPERTIES:\n :ToodledoFolder: CONTACT\n :END:"
:empty-lines 1) ))
Here is what it looks like in practice:
(source: lawlist.com)
Here is screenshot of calendar entries containing ** Waiting; ** Reference; and ** Delegated:
(source: lawlist.com)
In the customize buffer click on INS button it is just below the Org Capture Templates entry. This will open up a form like UI where you can fill the desired values. The explanation of what each value is given in the customize buffer itself. After you have entered the values save the template by clicking on Apply and Save button.
For general help on using the customize interface do C-higEasy Customization InterfaceRET
Related
I'm having a weird problem with Emacs (doom-emacs) on macOS (brew cask emacs-mac-spacemacs-icon): I sporadically cannot fold a heading. I can unfold it, then its children are shown, however, when I try to fold it I get the message "No matching item found on the current line". Sometimes it works again after changing to another application and tabbing back, the the message line shows "FOLDED" and "CHILDREN" when I press the Tab key.
It also works in some org files, but not in others. I don't know what's differen between them.
I just realized that when I have an inactive timestamp as a heading, pressing tab once shows the children but pressing it again just jumps between the brackets...
Here is my configuration:
;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
;; are the three important ones:
;;
;; + `doom-font'
;; + `doom-variable-pitch-font'
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
;; presentations or streaming.
;;
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
;; font string. You generally only need these two:
(setq doom-font (font-spec :family "Meslo LG M for Powerline"
:size 12))
;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. This is the default:
(setq doom-theme 'doom-gruvbox)
;; Enable visual line mode per default for text files
(add-hook! 'text-mode-hook 'turn-on-visual-line-mode)
;; Enable org-autolist
(add-hook 'org-mode-hook (lambda () (org-autolist-mode)))
;; Org mode configuration
(setq org-directory "~/org")
(setq org-default-clock-file (concat org-directory "/clock.org"))
(after! org
(setq org-agenda-files (list org-directory))
(setq org-default-notes-file (concat org-directory "/inbox.org"))
(setq org-task-file (concat org-directory "/tasks.org"))
(setq org-log-into-drawer t)
(setq org-log-done nil)
(setq org-image-actual-width (/ (display-pixel-width) 3))
(setq org-todo-keywords
'((sequence "TODO(t)" "IN-PROGRESS(i!)" "WAITING(#w)" "|"
"DONE(d!)" "CANCELED(#c)")))
(setq org-todo-keyword-faces
'(
("TODO" . (:foreground "#fb4933" :weight bold))
("IN-PROGRESS" . (:foreground "#fabd2f" :weight bold))
("WAITING" . (:foreground "#fe8019" :weight bold))
("DONE" . (:foreground "#8ec07c" :weight bold))
("CANCELED" . (:foreground "#83a598" :weight bold))
)
)
(setq org-capture-templates
`(("r" "Weekly report" entry (file+headline org-default-clock-file "Clock")
,(concat "** Woche %<%V>\n"
"*** Gesamt\n"
"#+BEGIN: clocktable :scope agenda :maxlevel 20 :block 2020-W%<%V> :step week :stepskip0 t\n"
"#+END:\n"
"*** Tage\n"
"#+BEGIN: clocktable :scope agenda :maxlevel 20 :block 2020-W%<%V> :step day :stepskip0 t\n"
"#+END:"
)
)))
(setq org-startup-indented t)
(setq org-clock-persist 'history)
(org-clock-persistence-insinuate)
(setq org-duration-format (quote h:mm))
(setq org-refile-targets '((org-agenda-files :maxlevel . 10)))
(setq org-goto-interface 'outline-path-completion)
(defvar org-created-property-name "CREATED"
"The name of the org-mode property that stores the creation date of the entry")
(defun org-set-created-property (&optional active NAME)
"Set a property on the entry giving the creation time.
By default the property is called CREATED. If given the `NAME'
argument will be used instead. If the property already exists, it
will not be modified."
(interactive)
(let* ((created (or NAME org-created-property-name))
(fmt (if active "<%s>" "[%s]"))
(now (format fmt (format-time-string "%Y-%m-%d %a %H:%M"))))
(unless (org-entry-get (point) created nil)
(org-set-property created now))))
;; Key mappings
(map! :leader
(:prefix ("o" . "org")
:desc "Goto" "g" 'org-goto
:desc "Insert inactive timestamp" "!" 'org-time-stamp-inactive
:desc "Update dynamic block" "u" 'org-dblock-update
:desc "Todo list" "t" 'org-todo-list
:desc "Agenda" "a" 'org-agenda
:desc "Tag search" "m" 'org-tags-view
:desc "Search org headlines" "h" #'+default/org-notes-headlines
:desc "Search org files" "s" #'+default/org-notes-search
:desc "Refile" "r" 'org-refile
:desc "Browse notes" "f" #'+default/browse-notes
:desc "Search notes for symbol" "." #'+default/search-notes-for-symbol-at-point
:desc "Org capture" "n" #'org-capture
(:prefix ("c" . "clock")
:desc "Clock in" "i" 'org-clock-in
:desc "Clock out" "o" 'org-clock-out
:desc "Jump to last clock" "l" (lambda () (interactive) (setq current-prefix-arg '(4)) (org-clock-goto))
:desc "Jump to active clock" "j" 'org-clock-goto)
(:prefix ("p" . "properties")
:desc "Set CREATED property" "c" 'org-set-created-property)
))
)
;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
(setq display-line-numbers-type t)
;; Key unmappings
(map! :leader "n" nil)
(map! :leader "o" nil)
i had this problem with doom, due to a keybinding conflict with
evil-jump-item. I fixed it by rebinding tab:
(map! :after evil-org
:map org-mode-map
:desc "org-cycle" :n [tab] #'org-cycle)
I have a list of tasks in the following form in an org-file
* Tasks
** task 1
** task 2
and would like to create subtasks under * Tasks that I can easily clock it to (eg. task 1, task 2 etc popup when calling C-uorg-clock-in. I was considering using org-clock-history-push in order to build the list of tasks but hadn't come accross a simple way to walk the org-mode header tree to create the tasks? I was looking at this link, but was hoping there was an alternative/org API that would accomplish this.
I would also be interested in a way to save clock history across destop-sessions without loading org-mode as my attempts at adding org-clock-marker and org-clock-history to desktop-globals-to-save haven't worked.
I ended up writing my own with inspiration from the linked post. This is code that will create and add tasks that aren't "DONE" to org-clock-history so they are readily acccessible via C-u org-clock-in.
(defun my-org-header-list (&optional header-re level buffer items)
"Get the headers of an org buffer (default current buffer). Optionally,
narrows to headers matching HEADER-RE under nesting LEVEL (defaults all
headers). Returns plist list of headers with specified values in ITEMS when defined.
Defaults to header text, location, level, todo status.
See `org-element-all-elements' for possible item types."
(setq level (or level 0)) ;default all headers
(save-restriction
(with-current-buffer (or buffer (current-buffer))
(goto-char (point-min))
(and header-re
(re-search-forward header-re nil nil 1)
(org-narrow-to-element))
(let ((tree (org-element-parse-buffer 'headline)))
(list :buffer (current-buffer)
:headers
(org-element-map tree 'headline
(lambda (el)
(when (< level (org-element-property :level el))
(or (and items
(cl-loop for sym in items
nconc (list sym (org-element-property sym el))))
(list :raw-value (org-element-property :raw-value el) ;text
:begin (org-element-property :begin el) ;start
:end (org-element-property :end el) ;end
:level (org-element-property :level el) ;depth
:todo-keyword (org-element-property :todo-keyword el))
)))))))))
;; construct list of tasks to choose from in clock history buffer
;; #<marker at 19296 in org-clock.el>
(defun my-org-clock-create (headers)
"Create clock tasks for headers."
(let ((buf (plist-get headers :buffer)))
(cl-loop for h in (plist-get headers :headers)
when (not (string= "DONE" (plist-get h :todo-keyword)))
do (org-clock-history-push (plist-get h :begin) buf))))
;; generate a list of TODO tasks nested under Tasks heading from
;; BUFFER-NAME
;;;###autoload
(defun my-org-clock-in (arg &optional buffer-name)
(interactive "P")
(my-org-clock-create
(my-org-header-list
(if arg (read-string "Task group: ") "Tasks") 1 (or buffer-name "gtd.org")
'(:raw-value :begin :todo-keyword))))
I'm trying to make a 'class' template for org-capture.
What I want is to easily make this kind of entry:
* TODO <course>: Week <week> Lecture <number>
SCHEDULED: %^T
** TODO prepare for class: <course>-<week>-<number>
SCHEDULED: <two days before T> DEADLINE: <one day before T>
** TODO review class: <course>-<week>-<number>
SCHEDULED: <one day after T> DEADLINE: <two days after T>
Currently, I have this template.
(setq org-capture-templates
'(
("c" "Class" entry (file "~/sydbox/personal/workflow/class.txt")
"* TODO %^{Course}: Week %^{Week} Lecture %^{Number}\n SCHEDULED: %(org-insert-time-stamp (org-read-date nil t nil nil nil \" \"))\n location: %^{location} %?\n** TODO %\\1: prepare lecture %\\3 from week %\\2\n DEADLINE: %(org-insert-time-stamp (org-read-date nil t \"-1d\")) SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"-2d\"))\n** TODO %\\1: review lecture %\\3 from week %\\2\n DEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\")) SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+1d\"))\n")
("e" "Exercise session" entry (file "~/sydbox/personal/workflow/class.txt")
))
However, now I have no idea how to input the dates. The date and time of the course should be prompted for (_only_once_).
The following code works for me. It first defines a custom function to create the template (org-capture-class), which calculates the date as necessary and is easier on the eyes than the in-line string (note that it relies on cl-lib, so make sure that's loaded). It then calls that function in the template itself, niling out if any of the fields are empty (updated in response to comment):
(defun org-capture-class ()
"Capture a class template for org-capture."
(cl-labels ((update (date days)
(format-time-string
(car org-time-stamp-formats)
(seconds-to-time (+ (time-to-seconds date)
(* days 86400))))))
(let ((course (read-string "Course: " nil nil '(nil)))
(week (read-string "Week: " nil nil '(nil)))
(lecture (read-string "Lecture No.: " nil nil '(nil)))
(date (org-read-date nil t))
(location (read-string "Location: " nil nil '(nil))))
(when (and course week lecture date location)
(concat (format "* TODO %s: Week %s Lecture %s\n"
course week lecture)
(format " SCHEDULED: %s\n" (update date 0))
(format " Location: %s %%?\n" location)
(format "** TODO %s: prepare lecture %s from week %s\n"
course lecture week)
(format " DEADLINE: %s SCHEDULED: %s\n"
(update date -1) (update date -2))
(format "** TODO %s: review lecture %s from week %s\n"
course lecture week)
(format " DEADLINE: %s SCHEDULED: %s\n"
(update date 2) (update date 1)))))))
(setq org-capture-templates
'(("c" "Class" entry
(file "~/sydbox/personal/workflow/class.txt")
#'org-capture-class)
("e" "Exercise session" entry
(file "~/sydbox/personal/workflow/class.txt"))))
What is the best way, please, to test for the existence of a specific todo state and a deadline that is not equal to today?
org-state is a "[h]ook which is run after the state of a TODO item was changed". So unless I'm actually changing the state of a todo, I don't think I can use (string-equal org-state "Next Action"). Each of my string-equal lines of code listed below are rejected: Symbol's value as variable is void: org-todo and org-deadline. The deadline is a line that appears underneath the todo state, so that may also pose a problem when testing for the existence of both conditions.
(defun if-next-action-not-today-then-promote ()
(interactive)
(goto-char (point-min))
(while
(re-search-forward "^\*\* Next Action" nil t)
(when (and (string-equal org-todo "Next Action") (not (string-equal org-deadline "<%<%Y-%m-%d %a>>")) )
(message "You have satisfied the two conditions . . . proceeding.")
(org-todo "Active") ;; change state to active
(org-deadline nil "<%<%Y-%m-%d %a>>") ;; change deadline to today
)
)
)
Sample *.org configuration file.
* TASKS
** Active [#A] First task due today. :lawlist:
DEADLINE: <2013-07-11 Thu >
** Active [#A] Second task due today. :lawlist:
DEADLINE: <2013-07-11 Thu >
** Next Action [#E] Test One -- make Active with deadline today. :lawlist:
DEADLINE: <2013-07-31 Wed >
** Next Action [#E] Test Two -- make Active with deadline today. :lawlist:
DEADLINE: <2013-07-31 Wed >
EDIT: The following is a modification of the function proposed by Jonathan Leech-Pepin in his answer further down below. In the first draft of the answer, I was unable to obtain anything but nil from the variable deadline due to a problem with (org-element-timestamp-interpreter . . . nil) -- completely eliminating that reference appears to correct the issue. I set up messages along the way so that I could better understand what was happening. I used if instead of unless because I wanted an else message to let me know that the conditions were not met but that the function was nevertheless working correctly. I've run several tests, including wrapping it into an re-search-forward type function and it works very nicely -- a wrapped function can be done several ways, but that is beyond the scope of this thread -- e.g., (&optional from-state to-state) and (interactive) and then (setq . . .) further down; or (from-state to-state) and (interactive (list (setq . . .).
(defun zin/org-test-deadline (from-state to-state)
"Change headline from FROM-STATE to TO-STATE if the deadline is not already set to today."
(interactive "sChange from state: \nsChange to state: ")
(unless (org-at-heading-p)
(org-back-to-heading))
(let* (
(element (org-element-at-point))
(todo-state (org-element-property :todo-keyword element))
;; "ignore-errors" avoids throwing an error message if there is no deadline.
(deadline
(ignore-errors
(time-to-days
(org-time-string-to-time
(org-element-property :deadline element) ))))
(today (time-to-days (current-time))) )
(message "This is the element variable: %s" element)
(message "This is the today variable: %s" today)
(message "This is the deadline variable: %s" deadline)
(message "This is the todo-state variable: %s" todo-state)
(message "This is the from-state variable: %s" from-state)
(message "This is the to-state variable: %s" to-state)
(if (not (eq today deadline))
(message "The deadline is not today.")
(message "Today is the deadline."))
(if (and
(not (eq today deadline)) ;; condition -- deadline not equal to today
(string= todo-state from-state) ) ;; condition -- todo-state equals from-state
(progn ;; Process following list if conditions were met.
(org-todo to-state)
(org-deadline nil ".")
(message "The conditions were met, so we did everything that was required.") )
(message "The conditions were not met, so nothing has been done."))
))
As long as you are using Org 7.9.2 or greater the following should work. I tested it as well as I could by adjusting deadlines and todo states.
(defun zin/org-test-deadline (from-state to-state)
"Change headline from FROM-STATE to TO-STATE if the deadline is
not already set to today."
(interactive "sChange from state: \nsChange to state: ")
(unless (org-at-heading-p)
(org-back-to-heading))
(let* ((element (org-element-at-point))
(todo-state (org-element-property :todo-keyword
element))
;; Do not give an error if there is no deadline
(deadline (ignore-errors
(time-to-days
(org-time-string-to-time
(org-element-timestamp-interpreter
(org-element-property :deadline
element) nil)))))
(today (time-to-days (current-time))))
(unless (or
;; Is there a deadline
(not deadline)
;; Is the deadline today
(eq today deadline)
;; Is the todo state the wrong one
(not (string= todo-state from-state)))
(org-todo to-state)
(org-deadline nil "."))))
You can then bind this or wrap it in a function that defines from-state and to-state. It will also prompt for the two states if called interactively.
Using Emacs org-mode, I often have a list of TODO items that I want to have active one at a time, in sequence. For example when the Item A in a list is marked "DONE", then I want Item B to be automatically be marked "TODO". How do I make this happen? This should not be any kind of general behavior, it should only happen with specific pairs or lists of items that I chose.
;; init-org-lawlist.el
;;
;; QUESTION #Brian Z -- stackoverflow.com: "How to automatically trigger a change in TODO state in Emacs org-mode."
;;
;; "I often have a list of TODO items that I want to have active one at a time, in sequence. For example when the
;; Item A in a list is marked "DONE", then I want Item B to be automatically be marked "TODO". How do I make this
;; happen? This should not be any kind of general behavior, it should only happen with specific pairs or lists of
;; items that I chose."
;;
;;
;; ANSWER #lawlist -- stackoverflow.com -- This script provides two (2) possible options:
;;
;; 1. Navigate to a ** TODO heading (must have at least one todo subtree underneath) and enter: M-x lawlist-done
;; OR
;; 2. Within a ** TODO heading (must have at least one todo subtree underneath), Shift-Right or Shift-Left and cycle
;; to the option ** DONE and then confirm yes or no.
;;
;; NOTE # A: This configuration script assumes the `org-archive-location` will use the SAME lawlist.org file for everything.
;; In this example, the script uses: (setq org-archive-location "/Users/HOME/.0.data/lawlist.org::* ARCHIVES")
;;
;; NOTE # B: Whenever using setq . . ., there is a likelihood that other settings with the same variable will be trumped.
;; So, after testing this script, it would be best to mix and match portions you like with your own configuration for org-mode.
;; You may need to temporarily disable your other configurations that use the same setq variables so as not to conflict while
;; testing this script.
;;
;; NOTE # C: Author to consider adding a check for the existence of at least one subsequent todo subtree as a condition precedent.
;;
;; NOTE # D: Author to consider adding a check that the user is on a second level tier (i.e., a todo) as a condition precedent.
;;
;;
;;
;;
;; SAMPLE lawlist.org CONFIGURATION FILE
;;
;;
;; * TASKS
;;
;; ** TODO [#A] First, figure out this new feature request. :lawlist:
;; DEADLINE: <2013-07-09 Tue>
;; :PROPERTIES:
;; :lawlist-drawer: ACTIVE
;; :END:
;;
;; ** NEXT [#B] Second, If at first you don't succeed, then try again. :lawlist:
;; :PROPERTIES:
;; :lawlist-drawer: PENDING
;; :END:
;;
;; ** WAITING [#C] Third, try again to figure out this new feature request. :lawlist: :WAITING:
;; :PROPERTIES:
;; :lawlist-drawer: DORMANT
;; :END:
;;
;; ** HOLD [#D] Fourth, try, try again to figure out this new feature request. :lawlist: :WAITING:HOLD:
;; :PROPERTIES:
;; :lawlist-drawer: DORMANT
;; :END:
;;
;;
;; * ARCHIVES
;;
;; ** DONE [#E] This task is a done deal. :lawlist:
;; :PROPERTIES:
;; :lawlist-drawer: COMPLETED
;; :END:
(require 'org)
(setq org-startup-folded 'showeverything) ;; overview | content | all | showeverything
(setq org-tags-column 0)
(setq org-startup-indented nil)
(setq org-indent-mode nil)
(setq org-support-shift-select t) ;; 'always to disable; or, t to use shift-select only when cursor is within a special context.
(setq org-cycle-separator-lines 1)
(setq org-insert-heading-respect-content t)
(setq org-blank-before-new-entry '((heading . t) (plain-list-item . nil)))
(setq org-enable-priority-commands t)
(setq org-highest-priority ?A)
(setq org-lowest-priority ?E)
(setq org-default-priority ?A)
(setq org-ellipsis " \u25bc" )
;; '!' (for a timestamp) or '#' (for a note with timestamp)
(setq org-todo-keywords
(quote ((sequence "TODO(t)" "NEXT(n)" "WAITING(w)" "HOLD(h)" "|" "DONE(d)" "CANCELED(c)") )))
(setq org-global-properties '(("lawlist-drawer_ALL". "ACTIVE PENDING DORMANT COMPLETED")))
(setq org-default-properties (cons "lawlist-drawer" org-default-properties))
(setq org-todo-state-tags-triggers
(quote (("CANCELED" ("CANCELED" . t))
("WAITING" ("WAITING" . t))
("HOLD" ("WAITING" . t) ("HOLD" . t))
(done ("WAITING") ("HOLD"))
("TODO" ("WAITING") ("CANCELED") ("HOLD"))
("NEXT" ("WAITING") ("CANCELED") ("HOLD"))
("DONE" ("WAITING") ("CANCELED") ("HOLD")))))
(setq org-tag-alist (quote ((:startgroup)
("john-doe" . ?j)
("jane-doe" . ?J)
(:endgroup)
("lawlist" . ?0))))
(add-hook 'org-after-todo-state-change-hook 'lawlist-hook)
(defun lawlist-hook (&optional default-heading)
(let ((lawlist-item default-heading)
result)
(unless lawlist-item
(condition-case nil
(progn
(org-back-to-heading t)
(setq lawlist-item (elt (org-heading-components) 4)))
)
)
(when (string-equal org-state "DONE")
(if (string-equal org-state "DONE")
(or (yes-or-no-p (format "%s -- process?" org-state))
(error "You changed your mind.")))
(org-forward-heading-same-level 1)
(org-todo "TODO")
(org-priority ?A)
(org-deadline nil "<%<%Y-%m-%d %a>>")
(org-set-property "lawlist-drawer" "ACTIVE")
(org-backward-heading-same-level 1)
(org-priority ?E)
(org-deadline 'remove)
(org-set-property "lawlist-drawer" "COMPLETED")
;; (setq org-archive-save-context-info nil) ;; Set to nil if user doesn't want archive info.
;; NOTE: User must set the correct path to his / her lawlist.org file.
(setq org-archive-location "/Users/HOME/.0.data/lawlist.org::* ARCHIVES")
(org-archive-subtree)
(goto-char (point-min))
(re-search-forward "^\* ARCHIVES" nil t)
(org-sort-entries t ?a)
;; (org-sort-entries t ?d) additional sorting criteria if deadline is not removed.
(lawlist-org-cleanup)
(goto-char (point-min))
(re-search-forward lawlist-item nil t)
(beginning-of-line)
(message "Please take a moment to visually verify your completed tasks has been refiled correctly, then press any key.")
(read-event) )))
(defun delete-trailing-blank-lines-at-end-of-file ()
"Deletes all blank lines at the end of the file, even the last one"
(interactive)
(save-excursion
(save-restriction
(widen)
(goto-char (point-max))
(delete-blank-lines)
(let ((trailnewlines (abs (skip-chars-backward "\n\t"))))
(if (> trailnewlines 0)
(progn
(delete-char trailnewlines)))))))
(defun lawlist-org-cleanup ()
(interactive)
(save-excursion
(replace-regexp "\n+\\*\\* " "\n\n** " nil (point-min) (point-max))
(replace-regexp "\n+\\* " "\n\n\n* " nil (point-min) (point-max))
(replace-regexp "\n\t\s*" "\n " nil (point-min) (point-max)) )
(delete-trailing-blank-lines-at-end-of-file) )
(defun lawlist-done (&optional default-heading)
(interactive)
(remove-hook 'org-after-todo-state-change-hook 'lawlist-hook)
(let ((lawlist-item default-heading)
result)
(unless lawlist-item
(condition-case nil
(progn
(org-back-to-heading t)
(setq lawlist-item (elt (org-heading-components) 4)))
)
)
(org-forward-heading-same-level 1)
(org-todo "TODO")
(org-priority ?A)
(org-deadline nil "<%<%Y-%m-%d %a>>")
(org-set-property "lawlist-drawer" "ACTIVE")
(org-backward-heading-same-level 1)
(org-todo "DONE")
(org-priority ?E)
(org-deadline 'remove)
(org-set-property "lawlist-drawer" "COMPLETED")
;; (setq org-archive-save-context-info nil) ;; Set to nil if user doesn't want archive info.
;; NOTE: User must set the correct path to his / her lawlist.org file.
(setq org-archive-location "/Users/HOME/.0.data/lawlist.org::* ARCHIVES")
(org-archive-subtree)
(goto-char (point-min))
(re-search-forward "^\* ARCHIVES" nil t)
(org-sort-entries t ?a)
;; (org-sort-entries t ?d) additional sorting criteria if deadline is not removed.
(lawlist-org-cleanup)
(goto-char (point-min))
(re-search-forward lawlist-item nil t)
(beginning-of-line))
(add-hook 'org-after-todo-state-change-hook 'lawlist-hook) )
(provide 'init-org-lawlist)
The lawlist.org sample file used for testing the script should look exactly like this:
* TASKS
** TODO [#A] First, figure out this new feature request. :lawlist:
DEADLINE: <2013-07-09 Tue>
:PROPERTIES:
:lawlist-drawer: ACTIVE
:END:
** NEXT [#B] Second, If at first you don't succeed, then try again. :lawlist:
:PROPERTIES:
:lawlist-drawer: PENDING
:END:
** WAITING [#C] Third, try again to figure out this new feature request. :lawlist: :WAITING:
:PROPERTIES:
:lawlist-drawer: DORMANT
:END:
** HOLD [#D] Fourth, try, try again to figure out this new feature request. :lawlist: :WAITING:HOLD:
:PROPERTIES:
:lawlist-drawer: DORMANT
:END:
* ARCHIVES
** DONE [#E] This task is a done deal. :lawlist:
:PROPERTIES:
:lawlist-drawer: COMPLETED
:END:
You're not giving a lot of context here, is this what you want?
(defun org-todo-plus ()
(interactive)
(org-todo)
(org-forward-element)
(org-todo))
It works for this list:
* TODO spam
* eggs
* foo
* bar
With point on spam, just keep M-x org-todo-plus until everything is done.