4

The function org-toggle-heading is quite handy to convert existing text into an org heading.

Input:

pay rent

Output:

* pay rent

The function org-insert-heading has an analogous org-insert-todo-heading, but I don't see the function org-toggle-todo-heading as a counterpart to org-toggle-heading.

Desired output:

* TODO pay rent

Is there a function to convert existing text into org todo heading?

1
  • On a side note, you can easily convert abc or a list element - abc to * abc using the default binding C-c *. C-c - will convert to a list element instead of heading. Commented Jul 9, 2015 at 20:24

1 Answer 1

6

My preferred implementation

This alternative solution will not act as a toggle, but it will directly convert Heading to * TODO Heading on hitting C-c C-t (The Shift bindings will not work here).

The advantage of this approach is that you do not need to remember a new function or binding just for this special plain text to TODO conversion; the C-c C-t default binding for org-todo will work in DWIM fashion.

For instance, both of the below conversions happen when using the same C-c C-t binding:

Heading▮   -- (C-c C-t)--> * TODO Heading▮
* Heading▮ -- (C-c C-t)--> * TODO Heading▮

Implementation

(defun modi/org-first-convert-to-heading (orig-fun &rest args)
  (let ((is-heading))
    (save-excursion
      (forward-line 0)
      (when (looking-at "^\\*")
        (setq is-heading t)))
    (unless is-heading
      (org-toggle-heading))
    (apply orig-fun args)))
(advice-add 'org-todo :around #'modi/org-first-convert-to-heading)

You need to be using emacs 24.4+ for the above advice system to work.


Toggle current line between a non-heading and TODO heading

Below function will work on a non-empty line as follows:

If the line contains

Heading▮

M-x my/org-toggle-heading-and-todo will convert that to,

* TODO Heading▮

Calling that function again will convert it back to,

Heading▮

Defining my/org-toggle-heading-and-todo

(defun my/org-toggle-heading-and-todo ()
  "Toggles the current line between a non-heading and TODO heading."
  (interactive)
  (let ((is-heading))
    (save-excursion
      (forward-line 0)
      (when (looking-at "^\\*") 
        (setq is-heading t)))
    (if is-heading 
        (progn
          (org-todo 'none) ; remove TODO
          (org-toggle-heading)) ; remove heading
      (progn
        (org-toggle-heading) ; convert to heading
        (org-todo 'nextset))))) ; add TODO

Cycle only the TODO states

While the point is anywhere on the heading, S-right/S-left will cycle through all the TODO states. This works even if shift-select-mode is t. The key is to have the point/cursor on the heading. I also noticed that the org-treat-S-cursor-todo-selection-as-state-change is t by default (and that's why the shift bindings for changing TODO states work).

Example:

Below, the point is on the heading

* Heading▮

After pressing S-right, I get,

* TODO Heading▮

After pressing S-left, I once again get,

* Heading▮

Reference

My org version as of writing this is 8.2.10.

11
  • Well of course. Or you can just type in * TODO manually. I'm asking for a function that will do it for me automatically, since I do it many times a day. Commented Jul 9, 2015 at 20:53
  • 1
    Maybe the answer could be expanded to include an example of how to use (org-todo "TODO") following the function that the original poster is calling to insert the asterisk? See the doc-string of org-todo for all the available options . . .
    – lawlist
    Commented Jul 9, 2015 at 21:18
  • @incandescentman To allow me to help better, can you please answer the following? (1) Are you looking for an interactive solution or elisp solution? I am wondering because you are referring to function names rather than the more convenient bindings. (2) How is navigating and then typing/deleting TODO better than a quick S-right or S-left? (3) How many todo states do you plan to use? By default, you need to cycle, not toggle the todo states: nothing -> TODO -> DONE -> nothing. Commented Jul 10, 2015 at 1:31
  • S-right and S-left require org-support-shift-select to be turned off. Surely there's a universal solution that doesn't require me to turn that setting off and on. And org-todo cycling only works on headings, not plain text. Commented Jul 10, 2015 at 1:33
  • 1
    @incandescentman Improved the solution even more; try using the solution with advice and the use of C-c C-t bindings. Commented Jul 10, 2015 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.