How to vote for a heading in org-mode? - emacs

I have thousands of headings in org-mode agenda files and use this structure for a long time. I want to set up org-mode so that it has a voting system. I press a hotkey, org-mode adds +1 to a heading and then I can filter the headings by the number of votes.
Upd. I have to clarify the question. I can see how this can be done:
* heading
:PROPERTIES:
:VOTES: 5
:END:
1) property drawers are searchable http://orgmode.org/worg/org-tutorials/advanced-searching.html, so I can use the comparison operators for filtering, e.g. VOTES>4.
2) I can use the propertу API http://orgmode.org/manual/Using-the-property-API.html for increasing and decreasing the counter.

Here is the solution. I add + to a speed command in org-mode. You could also bind this to some key.
(defun plusone ()
"Increase the VOTES property in an org-heading by one. Create
the property if needed."
(interactive)
(org-entry-put
(point)
"VOTES"
(format "%s" (+ 1 (string-to-number
(or
(org-entry-get (point) "VOTES")
"0"))))))
(add-to-list 'org-speed-commands-user '("+" . (plusone)))

Related

Emacs org-mode: How can i fold everything but the current headline?

I use org-mode to handle my tasks and projects in multiple files.
In the weekly agenda, it is possible to jump to the location of each TODO entry using <TAB> or <RET>. If the target file was not previously open, it is loaded an the cursor is set to the correct headline and the entire document is unfolded, including drawers.
I would very much prefer to see only a sparse tree with everything but the correct headline folded (subtree visibility does not matter).
It is possible to collapse the entire tree by cycling global visibility using C-u <TAB, but then I have to find the heading again.
I know I can hide the rest by narrowing the buffer as described here:
Emacs, How can I display only current task and hide others in org-mode?
but then I loose context (parent heading, easy access to siblings) and the drawers are still open.
Ideally, I would like to have a command that shows the following:
The top level headings
The current headline, and all it's parents up to the top level
The current headline's children
Edit:
A slighty modified version of the functions user3173715 posted seems to do the trick:
(defun org-show-current-heading-tidily ()
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-back-to-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(show-children)))
This is based on the answer in the edit in the actual question.
If of help to anyone:
When I tried to bind the above to a hotkey, I kept getting an error, commandp wrong argument something something ... It turned out one had to add the (interactive) flag to make it work.
Below is an example of the function tied to M-=
(defun org-show-current-heading-tidily ()
(interactive) ;Inteactive
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-back-to-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(show-children)))
(global-set-key "\M-=" 'org-show-current-heading-tidily)
#Patrick.B thanks for edit!
Check your org startup options (customize-group > org-startup) like org-startup-folded or org-agenda-inhibit-startup (others have mentioned these already) and set the options to show only the folded view. Org mode variables like #+STARTUP are discussed here.
You may notice that everything is folded when you now jump to the agenda, even the parents of the active item may not be visible. You can then make the context (parents, children, next sibling) visible with org-reveal (C-c C-r as per the manual)
I am not very sure if this is your demand (I just think it is suitable for your question title), but I use these two functions with plenty of pleasures by binding them in the speed command of org-mode. You can find these two functions in org-mode hacks. I slightly modified them to meet my purposes.
The two functions support:
Unfold every other headings except current heading
Move current heading to top of screen for wider reading area.
In order to accomplish (2), you need to (setq recenter-positions '(top bottom)), there may be some better solutions, but I did not dig into it.
(defun ded/org-show-next-heading-tidily ()
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-next-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(recenter-top-bottom)
(show-children)
(recenter-top-bottom)))
(defun ded/org-show-previous-heading-tidily ()
"Show previous entry, keeping other entries closed."
(let ((pos (point)))
(outline-previous-heading)
(unless (and (< (point) pos) (bolp) (org-on-heading-p))
(goto-char pos)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(recenter-top-bottom)
(show-children)
(recenter-top-bottom)))
And you can bind them with org-mode speed key with j and l, then you can use j and l to control the folding of headings when your cursor is in the beginning of headings.
(setq org-speed-commands-user
'(("j" . ded/org-show-next-heading-tidily)
("l" . ded/org-show-previous-heading-tidily))))
It is perfect for reading org-mode files, cheers!
Current (2022) emacs no longer requires elaborate setup to achieve the goals stated in the Question:
The top level headings
The current headline, and all it's parents up to the top level
The current headline's children
In the current Emacs and org-mode versions (Emacs 27.1, as of August 2022), you can press Shift-Tab Tab to close all headings, then open the current heading. Crucially, the cursor remains on the current collapsed heading so Tab reopens it.
The only significant change that I have from a default install is Evil, which may or may not affect the fact that the cursor remains on the collapsed heading.

org-mode: counter for items, visible in export

I'm writing a document in org-mode. Is it possible to use a counter for exercises that are spread across the document instead of numbering them myself? I am exporting this to HTML and PDF (via LaTeX). Example:
* First chapter
Blabla.
Exercise 1.
* Second chapter.
Blabla
Exercise 2.
* Third chapter.
Exercise 3.
Exercise 4.
I solved this using dynamic blocks in org-mode.
In my init.el I defined the following:
(setf exercise-counter 0)
(defun org-dblock-write:reset-exercise-counter (params)
(setf exercise-counter 0))
(defun org-dblock-write:exercise (params)
(incf exercise-counter)
(insert (concat "Exercise " (int-to-string exercise-counter) ".")))
At the top of my document I reset the counter:
#+BEGIN: reset-counter
#+END
Spread across the document I can now put this:
#+BEGIN: exercise
#+END
Blablabla.
#+BEGIN: exercise
#+END
Blablabla.
After calling org-update-all-dblocks the right numbers will be inserted.
Open for suggestions if anything can be improved.
How do I call org-update-all-dblocks automatically when exporting?
ANSWER: like this: (add-hook 'org-export-first-hook 'org-update-all-dblocks)

Interactively enter headline under which to place an entry using capture

Using capture templates like the one below, I can add entries to different headlines in a file. How can I manually enter a headline during capture, instead of setting up each headline to a key in the .emacs file like I am now doing?
(setq org-capture-templates
'(
("l" "Log" entry
(file+headline "c:/Org/log.org" "Log")
"\n\n** %?\n<%<%Y-%m-%d %a %T>>"
:empty-lines 1))
It looks like, in newer versions of org at least, that custom functions can be used in capture templates to do this.
Instead of:
entry
(file+headline "~/Work/work.org" "Refile")
You can use:
entry
(file+function "~/Work/work.org" function-finding-location)
Where 'function-finding-location' is a custom function you have written yourself, which could easily prompt you for a headline.
Or, you can go even farther, and define a custom function which will prompt for both file name and headline name (or anything else you can dream up):
entry
(function function-finding-location)
I don't really know enough elisp to write these functions myself, but this looks like the place to start. It'd be nice if someone else could offer up some code. The relevant documentation is here:
http://orgmode.org/manual/Template-elements.html
I wrote a function to be used with file+function which will prompt for a location on capture.
It uses the internal prompting function of org-refile so we get completions of headings in the prompt (with maxlevels overridden to 9). When the user enters an unknown heading, it creates it at the end of the file.
(defun org-ask-location ()
(let* ((org-refile-targets '((nil :maxlevel . 9)))
(hd (condition-case nil
(car (org-refile-get-location nil nil t t))
(error (car org-refile-history)))))
(goto-char (point-min))
(outline-next-heading)
(if (re-search-forward
(format org-complex-heading-regexp-format (regexp-quote hd))
nil t)
(goto-char (point-at-bol))
(goto-char (point-max))
(or (bolp) (insert "\n"))
(insert "* " hd "\n")))
(end-of-line))
In your case, you use it like this:
(setq org-capture-templates
'(("l" "Log" entry
(file+function "c:/Org/log.org" org-ask-location)
"\n\n** %?\n<%<%Y-%m-%d %a %T>>"
:empty-lines 1))
I don't believe you can have it prompt for the headline on capture. You can however refile from within the capture window which should result in the desired behaviour.
I would define a catch-all target headline/file so that if you forget you will always collect them in the same location and then just have to refile them once created. If you also set a category/tag on this headline you will be able to easily see the misfiled capture entry and refile it as desired. (Example below)
Then instead of finishing with C-c C-c choose to refile with C-c C-w and you will be asked to select the headline you want to send the new entry to.
The capture template I use for this catch all is as follows (adapted from Bernt Hansen's capture settings)
("i"
"Incidents"
entry
(file+headline "~/Work/work.org" "Refile")
"* TODO %^{Ticket} - %^{User}\nSCHEDULED: %^t DEADLINE: %^t\n:PROPERTIES:
\n:DATE: %^U\n:END:\n%^{MANAGER}p%^{HOSTNAME}p%^{LOCATION}p%^{TEL}p\n%c"
:empty-lines 1 :clock-in t :clock-resume t)
(Line breaks are added to avoid scrolling when reading here)
The heading is configured as follows
* Refile :refile:
:PROPERTIES:
:CATEGORY: Unsorted
:END:
With this I end up with all non-refiled tasks showing up as
Unsorted: Deadline: TODO <Headline> :refile::
I currently tend to use tags as reference if I'm waiting for coworkers/managers to deal with the ticket, or to remind me to speak to them about it when I see them so the tag at the end stands out clearly, as does Unsorted if I'm trying to remember what the issue is (since I simply have a case number and user name showing, details within the entry).
while capturing a note, after finishing writeup press C-u C-c C-w to refile under desired new headline.
you also need to set this variable
(setq org-refile-allow-creating-parent-nodes (quote confirm))
you can set it to t instead of confirm. But I like it be confirm because I dont often refile to new targets

show org-mode outline up to a certain heading level

I'm making an outline for my thesis using org-mode, and I'd like to show all headings up to a certain level (e.g. all level-1 and level-2 headings).
I haven't found anything about that in the org-mode manual. Cycling shows either only level-1 headings, or all headings, which is too much information in my outline right now.
Thanks,
daniel.
Update: I found a workaround for his: set the variable org-cycle-max-level. This is a global setting, though.
Just stumbled on this question. One year later but what the heck.. There are commands for this that allows you to show headings to a certain level.
One command is C-<n> C-c tab will show subheadings up to level <n> (<n>=1,2,3...).
Another command is C-<n> S-tab which will operate on the whole buffer. It shows all headings up to level <n> (<n>=1,2,3...)
I found a solution that suits me: The command org-content shows the folder hierarchy, and giving it a numeric argument does exactly what I want: limit the maximum level shown. In my example, I wanted to show 2 levels, so I can do C-2 M-x org-content <RET>.
I also added my own command to my .emacs init file, binding that command to C-c m
(defun org-show-two-levels ()
(interactive)
(org-content 2))
(add-hook 'org-mode-hook
(lambda ()
(define-key org-mode-map "\C-cm" 'org-show-two-levels)))
If the prefix arguments from M. Kullman's answer take too much mental capacity for you (a limited resource when you are thinking hard about something else at the same time) then you can use the following functions to expand contract headings
(defvar hf-org-depth-point nil)
(defvar hf-org-depth-depth nil)
(defun hf-org-depth-increase ()
(interactive)
(hf-org-depth-incr 1))
(defun hf-org-depth-decrease ()
(interactive)
(hf-org-depth-incr -1))
(defun hf-org-depth-incr (incr)
(when (not (equal (point) hf-org-depth-point))
(setq hf-org-depth-point nil)
(setq hf-org-depth-depth 0))a
(setq hf-org-depth-point (point))
(setq hf-org-depth-depth (max (+ hf-org-depth-depth incr) 0))
(hide-subtree)
(show-children hf-org-depth-depth))
```
I am way late to the party, but let us add a simple way for posterity. Simply use Cycle Global Visibility (<backtab>). If your headings are open, it will close them. However, if you apply it repeatedly with all headings collapsed, they will open to the level you want.
I use it from the keyboard by <SHIFT>+<TAB>. You can also find it in the Org menu (in Emacs) under Show/Hide -> Cycle Global Visibility ()

(re)number numbered lists in emacs (muse)

suppose I have a text list in emacs like this:
a
b
c
...
d
Is there a way to assign numbers to those items in Emacs, by selecting the region? End results should look like:
1. a
2. b
3. c
j. ...
n. d
Thanks.
The way I do this, which may not be optimal, is to use regex search and replace. This, of course, requires that you be able to define a regex to match the start of the lines you want numbers on. Taking your example, I'd use a search regex like this:
\([a-z]\)
note the capturing brackets, we'll need that first letter soon. And a replace regex like this:
\#. \1
where:
\# is a special form which is replaced, by Emacs, by the right number (though see the warning below);
. writes a stop; and
\1 writes a space and the captured group.
WARNING: Emacs will number your items 0, 1, 2, .... Until someone posts to tell us how to start at 1, I always insert a dummy 0th element before the edit, then delete it.
You can use the Emacs Keyboard Macro Counter.
Put the cursor one line ABOVE your list.
Start a macro: F3
Insert the counter value: C-x C-k C-i. A 0 will appear
Insert the DOT and a space: .
Move the cursor to the next line
Stop the macro: F4
Select your list
M-x apply-macro-to-region-lines
You can delete the 0 you added on the top and enjoy :)
NOTE: This will create a numbered list. It will not use letters.
A much simpler way is to use the CUA library's advanced rectangle editing commands. CUA is included in Emacs (at least 23.1, I think it's in earlier versions as well), so there isn't any new code to get.
You can use cua-set-rectangle-mark (bound to C-Return by default) to start a rectangle, and then use cua-sequence-rectangle to insert increasing values. It also gives you control over the format and starting value, so there is a lot of flexibility.
As an aside, CUA is primarily designed to make Emacs operate more like standard text editors (with C-c for copy, C-v for paste, etc), but it also includes some unrelated niceties, like rectangle editing. Don't ask me why :). If you want to use the rectangle editing without enabling the CUA keybindings (which is what I do), set cua-enable-cua-keys to nil, which can be done via customize.
(defun number-region (start end)
(interactive "r")
(let* ((count 1)
(indent-region-function (lambda (start end)
(save-excursion
(setq end (copy-marker end))
(goto-char start)
(while (< (point) end)
(or (and (bolp) (eolp))
(insert (format "%d. " count))
(setq count (1+ count)))
(forward-line 1))
(move-marker end nil)))))
(indent-region start end)))
Here's some elisp code to do it; would be easy to customize if you like tinkering.
This will number the current region (unless it is already numbered), and also the last line binds to the M-n keys. You could use a function key "[F6]" as needed.
Modified to take a format string to use. The default is 1. but you could do something like %d) to get a bracket instead of a . and so on.
(defun number-region(fmt)
(interactive "sFormat : ")
(if (or (null fmt) (= 0 (length fmt)))
(setf fmt "%d. "))
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(goto-char (point-min))
(let ((num 1))
(while (> (point-max) (point))
(if (null (number-at-point))
(insert (format fmt num)))
(incf num)
(forward-line))))))
(global-set-key "\M-n" 'number-region)
Not a direct answer to your question, but if you find yourself manipulating numbered lists frequently, you may want to look into org-mode. In particular, the section on plain lists.