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

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.

Related

How to make `C-x b RET` switch to previous buffer even if it's already shown in another frame?

Edit: What the poster calls a "window", Emacs calls a "frame". I fixed the title.
Concisely, the question is: in a window, how do I switch quickly to a buffer previously visited in that window, even if it's already opened in another window?
A more detailed description follows.
Normally, in order to switch window to previous buffer one just types C-x b RET. That is, the default argument to switch-to-buffer (or ido-switch-buffer) is the previous buffer.
This is not, however, the case when that (previous) buffer is already shown in another window. That's exactly what bugs me.
Let's consider an example. Suppose I have three buffers (A, B and C) and two windows showing buffers A and B (C is not visible at this point).
Then I open buffer A in the second window, too. So, now I have buffer A shown in both windows. Then I switch (C-x b RET) to B again. After that, C-x b RET will bring me not to A, but to C because A is already shown in the other window.
How do I make C-x b RET behave more consistently?
Update
After this problem had been solved, I realized I needed more: namely, for point position to be remembered per-window, not per buffer. Luckily, there're ready-made solutions:
winpoint
per-window-point
They're quite similar; for a discussion of differences see here.
I've found a fix for switch-to-buffer. It eventually calls
(other-buffer (current-buffer))
while in order to fix your problem, the call needs to look like this:
(other-buffer (current-buffer) t)
i.e. the visible-ok argument needs to be t.
Here's an advice to have it always at t. Hopefully it won't break other stuff that uses other-buffer:
(defadvice other-buffer (around fix-switch-to-buffer
(&optional buffer visible-ok frame) activate)
(setq visible-ok t)
ad-do-it)
Note that ido-switch-to-buffer uses a different machinery, so a different method is needed to fix it.
update: fix for ido-switch-to-buffer
I needed to re-define ido-make-buffer-list:
(defun ido-make-buffer-list (default)
(let* ((ido-current-buffers (list (buffer-name (current-buffer))))
(ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
(if ido-temp-list
(nconc ido-temp-list ido-current-buffers)
(setq ido-temp-list ido-current-buffers))
(if default
(setq ido-temp-list
(cons default (delete default ido-temp-list))))
(if (bound-and-true-p ido-enable-virtual-buffers)
(ido-add-virtual-buffers-to-list))
(run-hooks 'ido-make-buffer-list-hook)
ido-temp-list))
The diff is just one line, but it's too messy to advice it.
update: use new advice system for other-buffer
The old stuff should still work for quite a while, but here's the new approach:
(defun other-buffer-advice (orig-fun &optional buffer visible-ok frame)
(funcall orig-fun buffer t frame))
(advice-add 'other-buffer :around #'other-buffer-advice)
;; (advice-remove 'other-buffer :around #'other-buffer-advice)
Instead of advising the built-in function other-buffer, you can pre-select visible buffers using a package.
1 Using Ivy
If you're using Ivy, you can use abo-abo's approach to override the lower-use function ivy-switch-buffer.
(defun user/ivy-switch-buffer ()
"Switch to another buffer with visible-ok preselection."
(interactive)
(ivy-read "Switch to buffer: " #'internal-complete-buffer
:keymap ivy-switch-buffer-map
:preselect (buffer-name (other-buffer (current-buffer) t))
:action #'ivy--switch-buffer-action
:matcher #'ivy--switch-buffer-matcher
:caller 'ivy-switch-buffer))
(advice-add 'ivy-switch-buffer :override #'user/ivy-switch-buffer)
2 Using Ido mode
2.1 Switching to a buffer shown in another frame
If by "window" you really mean "frame" (i.e., you'd like to ido-switch-buffer to a buffer that is currently shown in another frame), then ido-mode gives you the behavior you're looking for when you change ido-default-buffer-method from its default value of raise-frame to selected-window:
(setq ido-default-buffer-method 'selected-window)
Emacs constructs an independent buffer list for each frame, so the only thing you have to do is to configure Ido to avoid jumping to another frame when you switch buffers.
2.2 Switching to a buffer that is shown in another window inside the same frame
To get this behavior across windows within the same frame, you should hook a function that reorders the buffer list onto ido-make-buffer-list-hook.
From ido.el:
;; Changing the list of files
;; --------------------------
;; By default, the list of current files is most recent first,
;; oldest last, with the exception that the files visible in the
;; current frame are put at the end of the list. A hook exists to
;; allow other functions to order the list. For example, if you add:
;;
;; (add-hook 'ido-make-buffer-list-hook 'ido-summary-buffers-to-end)
;;
;; then all files matching "Summary" are moved to the end of the
;; list. (I find this handy for keeping the INBOX Summary and so on
;; out of the way.) It also moves files matching "output\*$" to the
;; end of the list (these are created by AUCTeX when compiling.)
;; Other functions could be made available which alter the list of
;; matching files (either deleting or rearranging elements.)

How to make *Buffer List* appear below the other windows?

So, instead of creating a split window under (or to the right of) the currently active window, it would appear below all the existed ones with a half of the frame height? And, after closing, frame layout would be restored as it was before calling C-x C-b?
I’d like see the full paths to opened files.
See also my previous answer to your related issue: https://stackoverflow.com/a/21544307/2112489
See also a related answer by #phils, which includes a nice halve-other-window-height function: https://stackoverflow.com/a/4988206/2112489
See also the built-in stock functions display-buffer-below-selected or display-buffer-at-bottom, which are available in a recent version of Emacs Trunk -- I'm not sure when each function was first introduced. They are in window.el.
The doc-string of the function split-window states in relevant part:  SIZE defaults to half of
WINDOW's size. That is the second optional argument -- i.e., split-window (&optional window size side pixelwise)
Don't be shy about modifying these things -- you can make it do whatever you want. If want to select the window automatically after it is displayed, then you can add this to the bottom of the lawlist-display-buffer-below function:  (select-window (get-buffer-window (buffer-name buffer))) -- leaving, of course, two closing parenthesis to the right -- i.e., one closing parentheis for the let binding and one closing parenthesis for the defun.
(defun lawlist-list-buffers-below (&optional arg)
"Display a list of existing buffers.
The list is displayed in a buffer named \"*Buffer List*\".
See `buffer-menu' for a description of the Buffer Menu.
By default, all buffers are listed except those whose names start
with a space (which are for internal use). With prefix argument
ARG, show only buffers that are visiting files."
(interactive "P")
(lawlist-display-buffer-below (list-buffers-noselect arg) nil))
(defun lawlist-display-buffer-below (buffer alist)
(let (
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction 'below))
(t
(split-window (selected-window) nil 'below)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)))

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 ()

How to move forward and backward in Emacs' mark ring

In Emacs, C-u C-SPC will "jump to the mark, and set the mark from
position popped off the local mark ring". Is there a way to go the opposite way around the mark ring? Say you have typed C-u C-SPC several times and want to go back to a mark you have seen without going all the way around the ring.
Unlike previous answers, this one does only exactly what was asked: the reverse of C-u C-SPC. I find it the most useful.
(defun unpop-to-mark-command ()
"Unpop off mark ring. Does nothing if mark ring is empty."
(interactive)
(when mark-ring
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(set-marker (mark-marker) (car (last mark-ring)) (current-buffer))
(when (null (mark t)) (ding))
(setq mark-ring (nbutlast mark-ring))
(goto-char (marker-position (car (last mark-ring))))))
Comparing to the answer by scottfrazer, this command has a subtle difference of how it moves the cursor and mark, which more accurately mirrors C-u C-spc, and it does not require that the previous command was a unpop/pop-to-mark-command.
Here's a solution I just finished spending way too much time on. The difference between this and the other solutions is it works across buffers, ie it works on the 'global-mark-ring'. My goal was to emulate history browsing similar to Eclipse or IntelliJ. I bind it to M-left and M-right, obviously you can choose different keys for this.
(defun marker-is-point-p (marker)
"test if marker is current point"
(and (eq (marker-buffer marker) (current-buffer))
(= (marker-position marker) (point))))
(defun push-mark-maybe ()
"push mark onto `global-mark-ring' if mark head or tail is not current location"
(if (not global-mark-ring) (error "global-mark-ring empty")
(unless (or (marker-is-point-p (car global-mark-ring))
(marker-is-point-p (car (reverse global-mark-ring))))
(push-mark))))
(defun backward-global-mark ()
"use `pop-global-mark', pushing current point if not on ring."
(interactive)
(push-mark-maybe)
(when (marker-is-point-p (car global-mark-ring))
(call-interactively 'pop-global-mark))
(call-interactively 'pop-global-mark))
(defun forward-global-mark ()
"hack `pop-global-mark' to go in reverse, pushing current point if not on ring."
(interactive)
(push-mark-maybe)
(setq global-mark-ring (nreverse global-mark-ring))
(when (marker-is-point-p (car global-mark-ring))
(call-interactively 'pop-global-mark))
(call-interactively 'pop-global-mark)
(setq global-mark-ring (nreverse global-mark-ring)))
(global-set-key [M-left] (quote backward-global-mark))
(global-set-key [M-right] (quote forward-global-mark))
Following up my comment to scottfrazer's very handy solution, here's some advice which works in conjunction with that to make it easy to reverse directions around the mark ring at will, without the need to use a different key-binding for each direction.
I use cua-selection-mode, so for me C-SPC is bound to cua-set-mark, but I've written this as a macro so as to advise whichever function is bound to C-SPC, and verified that it works with the default set-mark-command.
To unpop, simply supply a negative prefix argument. e.g. C-- C-SPC
One of the nice things about cua-set-mark is that after an initial C-u C-SPC, you can continue to pop successive marks with just C-SPC, and I've included that behaviour here: After an initial C-- C-SPC you can continue un-popping with just C-SPC. To reverse the direction again and call pop-to-mark, simply supply a positive argument once more with C-u C-SPC.
(defmacro my-unpop-to-mark-advice ()
"Enable reversing direction with un/pop-to-mark."
`(defadvice ,(key-binding (kbd "C-SPC")) (around my-unpop-to-mark activate)
"Unpop-to-mark with negative arg"
(let* ((arg (ad-get-arg 0))
(num (prefix-numeric-value arg)))
(cond
;; Enabled repeated un-pops with C-SPC
((eq last-command 'unpop-to-mark-command)
(if (and arg (> num 0) (<= num 4))
ad-do-it ;; C-u C-SPC reverses back to normal direction
;; Otherwise continue to un-pop
(setq this-command 'unpop-to-mark-command)
(unpop-to-mark-command)))
;; Negative argument un-pops: C-- C-SPC
((< num 0)
(setq this-command 'unpop-to-mark-command)
(unpop-to-mark-command))
(t
ad-do-it)))))
(my-unpop-to-mark-advice)
Here's a function to do it:
(defun unpop-to-mark-command ()
"Unpop off mark ring into the buffer's actual mark.
Does not set point. Does nothing if mark ring is empty."
(interactive)
(let ((num-times (if (equal last-command 'pop-to-mark-command) 2
(if (equal last-command 'unpop-to-mark-command) 1
(error "Previous command was not a (un)pop-to-mark-command")))))
(dotimes (x num-times)
(when mark-ring
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(set-marker (mark-marker) (+ 0 (car (last mark-ring))) (current-buffer))
(when (null (mark t)) (ding))
(setq mark-ring (nbutlast mark-ring))
(goto-char (mark t)))
(deactivate-mark))))
There are two rings of markers: one local to the current buffer and one global among all buffers.
By default, in Icicles (in Icicle global minor mode):
C-- C-SPC lets you trip among the local markers
C-- C-x C-SPC lets you trip among the global markers
IOW, with a negative prefix arg, C-SPC and C-x C-SPC navigate. Without it they just do what they normally do (set-mark-command and pop-global-mark, respectively).
Navigating works as follows:
Locations are available as completion candidates: the text is that of the marker's line.
Completion: you can use substring, regexp, prefix, fuzzy (various kinds).
You can cycle among any of the completion candidates, or go to any of them directly.
Keys available during completion include:
up, down -- cycle among candidates in *Completions*, without navigating to their locations
C-up, C-down -- cycle, navigating to each location in turn
C-RET, C-mouse-2 -- go directly to the current/clicked candidate (e.g. in *Completions*)
RET, mouse-2 -- same as previous (go to candidate), but end the command (done)
S-TAB -- apropos-complete (substring/regexp)
TAB -- prefix or fuzzy complete
It doesn't do exactly what you're asking for, but it might be worth looking for a package called marker-visit.el which lets you navigate the marks in the current buffer in 'buffer position order'. From that file:
;;; Commentary:
;; This file provides a simple way to navigate among marks in a
;; buffer. C-u C-SPC is similar, but takes you haphazardly around the
;; buffer. Setting bookmarks is a lot of extra work if you just want
;; to jump around your buffer quickly; plus, you have to come up with
;; a name for every bookmark.
;; All the marks you've left while editing a buffer serve as bread
;; crumb trails of areas in the buffer you've edited. It is
;; convenient to navigate back and forth among these marks in order.
;; This file provides two methods to do just that, marker-visit-prev
;; and marker-visit-next. These two functions will take you, from
;; point, to the nearest mark in either direction. The function
;; marker-visit-truncate-mark-ring will truncate the mark ring.
;; The marks you can visit in a buffer consist of: "the mark" plus the
;; contents of the mark-ring.
I bind [S-up] and [S-down] to marker-visit-prev and marker-visit-next respectively.
If you really want/need to navigate in the order your mark-ring has currently, then you might get somewhere by looking at the functions pop-to-mark-command and pop-mark and implementing your own versions to rotate the mark ring in the opposite direction.
The manual says this:
The variable mark-ring-max
specifies the maximum number of
entries to keep in the mark ring. If
that many entries exist and another
one is pushed, the earliest one in the
list is discarded. Repeating `C-u
C-' cycles through the positions
currently in the ring.
I suggest you use that to contain the size of the mark ring (to 3 or 4, mine is currently 16). Then you can move around it much faster using prefixes.
Also:
If you want to move back to the
same place over and over, the mark
ring may not be convenient enough. If
so, you can record the position in a
register for later retrieval (*note
Saving Positions in Registers:
RegPos.).
Not directly answer for this question for emacs keybindings.
For evil users
I found better-jumper for evil users. If you are interested with evil-mode honestly offering to use.
By using How it's offer in it's main repository
(with-eval-after-load 'evil-maps
(define-key evil-motion-state-map (kbd "C-o") 'better-jumper-jump-backward)
(define-key evil-motion-state-map (kbd "<C-i>") 'better-jumper-jump-forward))
It's really easy to go back and forward to old positions of the cursor.
Additional you can create new scenarios by using it's hook function like if I change the buffer mark the old point etc.
For emacs key binding fans
Only advice which I can give for default-keybinding style is helm-all-mark-rings. It gives best visibility about mark-rings.

Emacs :TODO indicator at left side

I want to have sort of indiacator at left side of the line wherever I have in the source code
#TODO: some comment
//TODO: some comments
The indicator could be a just mark and I already enabled line numbers displayed at emacs.
This command will do something like you want.
(defun annotate-todo ()
"put fringe marker on TODO: lines in the curent buffer"
(interactive)
(save-excursion
(goto-char (point-min))
(while (re-search-forward "TODO:" nil t)
(let ((overlay (make-overlay (- (point) 5) (point))))
(overlay-put overlay 'before-string (propertize "A"
'display '(left-fringe right-triangle)))))))
You can customize the bitmap as desired.
To get this to apply to all files, you could add it to the 'find-file-hooks
(add-hook 'find-file-hooks 'annotate-todo)
Or, if you want it just for certain modes, you could add it to those mode hooks.
See Fringes, The 'display' Property, Overlays, and most importantly the before-string property.
Note: The code was updated 27/02/2010 to use overlays instead of directly adding text properties to the current text.
I like the approach described in this post on emacs-fu, which adds TODO/FIXME/... to the font-lock settings of the modes where you need it. In contrast to Trey's approach this should highlight the words as you type, whereas his approach should only highlight them when you open a file (or do I get this wrong).
Anyway its up to you. A good google search gives you probably even more ideas: http://www.google.com/search?q=emacs+highlight+todo
Update: Your question has already been answered: Emacs, highlight all occurences of a word