I added this to .emacs:
(setq org-support-shift-select t)
So, each time a TODO item is set to done, I get this:
* DONE Important task
CLOSED: [2014-09-04 Thu 18:44]
Is it possible to add seconds to the timestamp? So I could get this:
* DONE Important task
CLOSED: [2014-09-04 Thu 18:44:31]
This page says, that I can customize the timestamp format. But I couldn't understand, how to do it. I tried this:
(setq org-time-stamp-custom-formats '("<%m/%d/%y %a>" "<%m/%d/%y %a %H:%M:%S>"))
But it doesn't work.
Try this:
(setq org-time-stamp-formats
'("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M:%S>"))
Take note that it's defined as a constant, so you're not encouraged to
fiddle with it (but you still can:).
Related
Just learn to write an interactive function in elisp:
If called with prefix, open calendar and get the date which is picked by user.
I try to do something like this:
(calendar)
(org-get-date-from-calendar)
It return today straight away instead of let user to pick a date.
I tried
(org-read-date)
And that worked for me
As you've seen, the problem is that after invoking (calendar) your code simply continues and doesn't wait around for any interactions in the calendar window. You need to prevent the emacs command loop from continuing until the user has selected a date.
Setting up your own keys is one way to do this. For example, if you look at the org-read-date-minibuffer-local-map variable in the org-mode source code, you can see that org-mode essentially takes over keys in calendar mode to allow the user to navigate the calendar while org-mode waits for the result. Studying this keymap and the org-eval-in-calendar function might give you some ideas on how to achieve what you want.
Another way to wait for the result is via recursive-edit. The code below enters the calendar and, by calling (recursive-edit), waits for the user to exit the calendar via the q key, which normally invokes calendar-exit. The code temporarily applies advice to that function to have it set a local variable to the date selected in the calendar before calling calendar-exit (via the funcall) and then exiting the recursive edit:
(let* (date
(adv '(lambda (fn &rest args)
(setq date (calendar-cursor-to-date))
(funcall fn args)
(exit-recursive-edit))))
(advice-add 'calendar-exit :around adv)
(calendar)
(message "Select the desired date, then type `q' to exit.")
(recursive-edit)
(advice-remove 'calendar-exit adv)
date)
Using advice can be a brittle approach, though. It potentially changes function semantics in unexpected ways — and see this page for other potential problems — plus there are probably other issues lurking with this approach with respect to abnormal exits. You're better off using keymap approaches like those used in org-mode.
I use the Org-Mode diary to keep a record of my upcoming appointments.
In my diary.org file I could have an entry that looks something like the following:
*** 2014-10-31 Friday
**** 9:30 Take dog to vet
<2014-10-31 Fri>
Now imagine I need to reschedule my vet appointment. Is there a quick way (i.e. some Org-Mode command) to refile the appropriate heading within the same file but under a different date?
I don't see a builtin function that does this, but it sounds pretty useful. This function is really just a simplification of the code in org-archive.el that archives to datetrees. If you instead want to refile based on SCHEDULED, DEADLINE or some other property, just change "TIMESTAMP" to the property you want.
(defun org-refile-to-datetree ()
"Refile a subtree to a datetree corresponding to it's timestamp."
(interactive)
(let* ((datetree-date (org-entry-get nil "TIMESTAMP" t))
(date (org-date-to-gregorian datetree-date)))
(when date
(save-excursion
(org-cut-subtree)
(org-datetree-find-date-create date)
(org-narrow-to-subtree)
(show-subtree)
(org-end-of-subtree t)
(newline)
(goto-char (point-max))
(org-paste-subtree 4)
(widen)
)
)
))
Use org-refile with C-c C-w. This will allow you to refile it to the rescheduled date. Also be sure to check out the variables org-refile-use-outline-path (nil by default) and org-outline-path-complete-in-steps.
I would also recommend using the full power of org-mode dates so they show up in the agenda (C-a) appropriately. For example:
* Take Dog to Vet
<2014-10-31 Fri 09:30>--<2014-10-31 Fri 10:30>
I'm trying to call the following org-mode function to insert the current timestamp in the buffer. The function is called by a script.
(org-time-stamp-inactive)
This, as expected, brings up a prompt asking for the date to use for the timestamp. But I want to skip the prompt and insert the timestamp directly. Is that possible at all? Haven't found anything that could help me.
This should insert the current inactive time stamp:
(org-insert-time-stamp nil nil t)
org-time-stamp unconditionally¹ calls org-read-date to prompt the user for a date. You can't pass a date. But you can locally bind org-read-date to a function that returns the date that you want to use.
(require 'cl)
(flet ((org-read-date (org-with-time &rest args)
(format-time-string (if org-with-time "%Y-%m-%d %H:%M" "%Y-%m-%d")
(current-time))))
(org-time-stamp-inactive with-time))
¹ Except sometimes when there is already a time stamp, but that's no help.
I ended up creating the timestamp from scratch with the following call:
(insert (format-time-string "[%Y-%m-%d %a]"))
You can find the answer in documentation for similar function (org-time-stamp)
[...] With two universal prefix arguments, insert an active timestamp
with the current time without prompting the user. [...]
So.. all you need to do is press C-u C-u before you invoke the function (for example C-u C-u M-x org-time-stamp-inactive RET)
The title pretty much says it:
I often want to create a sparse tree
for my current position in the current buffer,
showing all the headings to get to me.
Here's
** WANTED create a sparse tree for where I am now :orgmode:
I often want to be able to create a sparse tree for where I am now.
It is a bit of a pain to have to create a search C-c //
- but that is my current kluge:
a) insert a unique string like HERE-I-AM
b) C-C // HERE-I-AM
(org-occur "HERE-I-AM" nil)
Giving something like this
** My (org-mode) LOGS :top:
** LOGs :log
*** Fri Mar 22 2013
**** DONE org-mode - trying to get calendar to work
***** DONE rewrote docs
- State "DONE" from "" [2013-03-22 Fri 14:49]
blah blah blah
HERE-I-AM
** ...NEXT Daily Log
This is obviously unsatisfactory.
e.g. may not have write permission
This function should do what you want:
(defun my-org-sparse-tree ()
"Create an org sparse tree showing only point"
(interactive)
(org-overview) ;; Hide everything
(org-show-context)) ;; Show context around point
I quickly wipped something up that might be what you want, or at least close:
(defun tr/path-sparse-tree ()
"sparse tree to the current buffer position"
(interactive)
(setq pathmarker "Eeshoo9OomeiRaix") ;; random string obtained from
;; pwgen, probably a unique marker
;; in any org document...
(save-excursion
(insert pathmarker)
(org-occur pathmarker))
(delete-char 16))
I'm not a emacs-lisp practitioner per se, but my quick tests were promising with respect to your problem description. At least it's your current kludge automated ;-).
I read the org-mode manual but couldn't find an easy way to add a CREATED field to newly created TODOs. In combination with org-log-done one could then compute the time it took to close a particular TODO. This is especially useful when using archive files.
Example:
* TODO Do something
CREATED: [2012-09-02 Sun 23:02]
* DONE Do something else
CREATED: [2012-09-02 Sun 20:02]
CLOSED: [2012-09-02 Sun 22:02]
I would expect the CREATED field to be added to new tasks (tasks which don't have that field) whenever the file is saved.
Any suggestions on how to achieve this? Using something like Git is not a solution for me to track the creations of TODOS.
I use org-expiry to implement that functionality, which is in the contrib directory of org.
The base configuration I use is:
;; Allow automatically handing of created/expired meta data.
(require 'org-expiry)
;; Configure it a bit to my liking
(setq
org-expiry-created-property-name "CREATED" ; Name of property when an item is created
org-expiry-inactive-timestamps t ; Don't have everything in the agenda view
)
(defun mrb/insert-created-timestamp()
"Insert a CREATED property using org-expiry.el for TODO entries"
(org-expiry-insert-created)
(org-back-to-heading)
(org-end-of-line)
(insert " ")
)
;; Whenever a TODO entry is created, I want a timestamp
;; Advice org-insert-todo-heading to insert a created timestamp using org-expiry
(defadvice org-insert-todo-heading (after mrb/created-timestamp-advice activate)
"Insert a CREATED property using org-expiry.el for TODO entries"
(mrb/insert-created-timestamp)
)
;; Make it active
(ad-activate 'org-insert-todo-heading)
If you are using capture it does not automatically work and needs a little glue. I have posted the complete config here: https://gist.github.com/4037694
A more lightweight solution would be to add ! flag to the TODO state:
(setq org-todo-keywords '((sequence "TODO(!)" "DONE")))
Then:
* TODO get of your ass
- State "TODO" from [2016-06-03 to. 10:35]
It isn't very pretty though.
Ref: http://orgmode.org/org.html#Tracking-TODO-state-changes
You don't need to modify functions with 'defadvice' to run expiry code on capture.
You should use hook:
(add-hook 'org-capture-before-finalize-hook
(lambda()
(save-excursion
(org-back-to-heading)
(org-expiry-insert-created))))
Same for 'org-insert-todo-heading'. There is a hook:
(add-hook 'org-insert-todo-heading-hook
(lambda()
(save-excursion
(org-back-to-heading)
(org-expiry-insert-created))))
Org provides a hook org-after-todo-state-change-hook which you can use here:
org-after-todo-state-change-hook is a variable defined in ‘org.el’.
Documentation:
Hook which is run after the state of a TODO item was changed.
The new state (a string with a TODO keyword, or nil) is available in the
Lisp variable ‘org-state’.
Use it as follows:
(require 'org-expiry)
(add-hook 'org-after-todo-state-change-hook
(lambda ()
(when (string= org-state "TODO")
(save-excursion
(org-back-to-heading)
(org-expiry-insert-created)))))
org-expiry is part of org-contrib, which is included in the org-plus-contrib package on the org ELPA.
Here's a buried treasure:
(setq org-treat-insert-todo-heading-as-state-change t)
I found it here, in response to someone saying they wanted an org-insert-todo-heading-hook.
Just tried it out and, true to form, when you org-insert-todo-heading, it counts as a state change, so ex: #+TODO: TODO(t!) | ... will add a log.
If you create all your TODOs with org-capture the following capture template does the trick:
(setq org-capture-templates
'(
("t" "TODO Task" entry (file+headline "~/inbox.org" "Tasks")
"* TODO %?\nCREATED: %u\nSRC: %a\n%i\n")
))
The result will look something like this:
* Tasks
** TODO Dummy task
CREATED: [2015-05-08 Fri]
SRC: [[file:~/path/to/file/where/you/created/the/task.org::*heading"][heading]]
Here is a lightweight solution that does not require an external package. I got it from the answer by #MarcinAntczak, the comments by #Clément, and this similar thread. It works with org-capture and with M-S-RET. Put this in your Emacs initialization file (e.g. ~/.emacs):
(defun insert-created-date(&rest ignore)
(insert (format-time-string
(concat "\nCREATED: "
(cdr org-time-stamp-formats))
))
(org-back-to-heading) ; in org-capture, this folds the entry; when inserting a heading, this moves point back to the heading line
(move-end-of-line()) ; when inserting a heading, this moves point to the end of the line
)
; add to the org-capture hook
(add-hook 'org-capture-before-finalize-hook
#'insert-created-date
)
; hook it to adding headings with M-S-RET
; do not add this to org-insert-heading-hook, otherwise this also works in non-TODO items
; and Org-mode has no org-insert-todo-heading-hook
(advice-add 'org-insert-todo-heading :after #'insert-created-date)
I did not add this function to state changes (e.g., from plain heading to TODO) because it would need to be in a properties drawer and I prefer to not have those extra lines. If you prefer to have it in properties, use the function defined in see this thread.
You can add a time stamp at creation time with zero config, but it won't be labeled CREATED. Rather than manually typing TODO, use C-c C-t. It will then be logged as "state changed to TODO from """ and time stamped.