Is it possible to collapse just one subtree without having to cycle over TAB functionality? - org-mode

What I mean is, if you have a tree, and you go to 1.2.1, I want to expand and collapse this without expanding the children (1.2.1.1 & 1.2.1.2).
In other words, normally I would have to press TAB three times, which shows the expanding of all subchildren. I just want a different key press to close the recently opened subtree.
Thanks! And hopefully I made myself clear!
EG

Possible it is, everything is possible in emacs if you go into defining lisp functions. However that eludes my knowledge.
What I can see from the available functionality is that you can't do that in a straightforward manner. See some relevant highlights from the help for the TAB key:
<tab> runs the command org-cycle.
(...)
- When point is at the beginning of a headline, rotate the subtree started
by this line through 3 different states (local cycling)
1. FOLDED: Only the main headline is shown.
2. CHILDREN: The main headline and the direct children are shown.
From this state, you can move to one of the children
and zoom in further.
3. SUBTREE: Show the entire subtree, including body text.
If there is no subtree, switch directly from CHILDREN to FOLDED.
(...)
- When there is a numeric prefix, go up to a heading with level ARG, do
a ‘show-subtree’ and return to the previous cursor position. If ARG
is negative, go up that many levels.
Full help see `C-h k TAB'.
You can also set VISIBILITY properties per buffer:
#+STARTUP: fold (or ‘overview’, this is equivalent)
#+STARTUP: nofold (or ‘showall’, this is equivalent)
#+STARTUP: content
#+STARTUP: showeverything
see: C-h v org-startup-folded.
Bottom line is: maybe the easiest is to just press TAB 3 times, unless you're skilled in lisp and are willing to make the changes,,,

This is what I came up with. It can be used repeatedly to fold up the chain.
(defun my/org-fold-this-heading ()
(interactive)
(org-back-to-heading)
(when (or
;; already folded
(outline-invisible-p (point-at-eol))
;; empty subtree
(let
((eoh (save-excursion (outline-end-of-heading) (point)))
(eos (save-excursion (org-end-of-subtree t t)
(when (bolp) (backward-char)) (point))))
(= eos eoh)))
;; move up a level before folding
(outline-up-heading 1))
(outline-hide-subtree))
(define-key org-mode-map (kbd "M-v") 'my/org-fold-this-heading)

Related

Emacs lisp code indentation

In emacs-lisp mode whenever i insert a closing brace i prefer to have indented to the same column like the corresponding opening brace. How is that possible? If i have eg in my init.el
(defadvice isearch-forward-regexp (before kill-ring-save-before-search activate)
"Save region (if active) to kill-ring before starting isearch. So that region
can be inserted into isearch easily with C-y."
(when (region-active-p)
(kill-ring-save (region-beginning) (region-end))
) ;; this should be under (when
) ;; this should be under (defadvice
It seems that you want to align the close parens to be able to
visually match them to the opening ones. You can do that with
show-paren-mode instead - it's much better at that job.
As pointed out by others, and I fully agree, the hanging parens are
very annoying and painful to look at - don't make a habit out of using
them. I've authored a minor mode for editing Elisp which might be
interesting for you - lispy-mode:
Pressing i will auto-indent an s-expression, eliminating
the hanging parens.
Pressing d will switch from one side of s-expression to
the other: a quick way to see what the current list contains.
Pressing m will toggle the region selection on the
current list: you can see what it contains even more clearly.

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.

emacs: second toolbar (row)

this is my first question, so apologies for breaking any rules.
I've just started writing some functions in elisp to help me navigate certain types of text files more efficiently. To make these accessible, I've added some buttons to the tool-bar. As it's now becoming busy, I'd like to either: 1) move some of these additional buttons to a second line; or 2) instantiate a second tool-bar that could be placed somewhere else in the frame (either under the existing tool-bar, or perhaps vertically along the side where the scrollbar is).
I've searched high and low but am unable to find an existing example of this and, as I don't yet really know what I'm doing, I wonder if somebody has a code snippet from which I might start to hack a solution together.
Many thanks in advance.
System: CentOS 5/6, emacs for linux 23.1
Edit:
Thanks for the comment, William. Here's a simple example representing what my tool-bar code might do:
;
; functions used by the toolbar
;
;
(defun copy-paste-whole-line ()
"copies and pastes the whole of the current into a new line underneath"
(interactive)
(beginning-of-line)
(set-mark (point))
(end-of-line)
(setq temp (buffer-substring (region-beginning) (region-end)))
(message " copying: %s" temp )
(newline)
(insert temp))
;
;
; population of the toolbar:
;
;
(when (find-image '((:type xpm :file "copy_paste_line.xpm")))
(unless tool-bar-mode (tool-bar-mode 1))
; (setq tool-bar-map (make-sparse-keymap)) ; <- uncomment this line to have only this button present
(tool-bar-add-item
"copy_paste_line"
'copy-paste-whole-line
'copy-paste-whole-line
:help "copies and pastes the whole of the current line into a new line underneath"))
so, as you can see (actually, I'm not allowed to post images until I have 10 reputation points, so you won't be able to see), the code adds an extra button to the end of the existing tool-bar buttons. I believe this to be a reasonable way to achieve this, but I'm not an experienced elisp programmer, so if you think it's poorly written, please comment - I'd like to understand why... :)
If I only had 1 button, it would be ok like that, however, I have multiple buttons. I would, thus, like to add them to a second instance of a similar tool-bar (or, perhaps a vertical one placed where the scrollbars are).
Thanks again for any input.
Frame parameter tool-bar-lines is supposed to control this. You can, for instance, customize option default-frames-alist if you want to change the number of tool-bar rows to 2 or 3 everywhere. Or you can do this on a mode-by-mode or frame-by-frame basis. You can, for instance, use M-: (set-frame-parameter nil 'tool-bar-lines 3).
Depending on your platform (and toolkit), the behavior might be variable. See the Elisp manual, node Layout Parameters and node Tool Bars.
I believe you are out of luck. It seems to me that (at least on ubuntu and cygwin) only one row of buttons in the tool-bar is supported.
Here is what I have tried without luck on both systems:
(progn
(set-frame-parameter nil 'tool-bar-lines 3)
(loop for i from 1 upto 20 do
(setcdr tool-bar-map (cons (cadr tool-bar-map) (cdr tool-bar-map)))))
The following picture shows what I get:
The other buttons appear in a pull-down menu if you click on the little triangle at the right end of the toolbar:
You can restore the old tool-bar with the following commands:
(progn
(setq tool-bar-map (make-sparse-keymap))
(tool-bar-setup))
Finally, I have 3 rows of buttons. This is possible with emacs-w32:
So it is the gtk+ / nextstep problem.

Decrease indentation on a couple of lines

Is there some way I can mark text in emacs and shift it left (removing starting spaces) by space/Tab granularity?
Same way I would do on some other editor with Shift+Tab.
Select your region;
Type C-u followed by the number of spaces you want to indent (negative number if you want to decrease indentation);
Use C-x TAB (by default bound to indent-rigidly) to apply the indentation to the region.
This is much more cumbersome than S-TAB, but it is IMHO some kind of last resort in case Emacs formatting doesn't solve your problem.
EDIT: much better solution: Shift a region or line in emacs (accepted answer). This is what I'm currently using in Emacs for changing indentation. WARNING: involves some Emacs Lisp.
This might be simpler and more visually intuitive: first make sure cua-mode is enabled (M-x cua-mode toggles it). Then go to the start of the line and press C-return. A red rectangle appears. Now move your cursor down and right to grow the rectangle as needed. Then press C-d to delete it. That's it.
I come across this problem often when the major-mode doesn't dictate any automatic indentation (or when it messes up).
There is a lot more you can do with cua-mode's rectangles, see http://trey-jackson.blogspot.com/2008/10/emacs-tip-26-cua-mode-specifically.html
Generally emacs places things where the current style dictates when you hit <TAB>, so naturally it's a little different here. The closest thing that comes to mind is M-\ which collapses horizontal whitespace around point. If you want to remove a "rectangle" of space before the lines, then delete-rectangle might be more appropriate, which you can do by setting mark and moving point to select the rectangle and then using C-x r d.
It sounds like the problem you're trying to solve is incorrect indentation of code when you're cutting/pasting. You can solve that by automatically re-indenting the text with something like the following.
Note: Using a prefix argument forces no re-indentation (C-u C-y), plus there's the size threshold variable.
;; automatically indenting yanked text if in programming-modes
(defvar yank-indent-modes '(emacs-lisp-mode
c-mode c++-mode
tcl-mode sql-mode
perl-mode cperl-mode
java-mode jde-mode
lisp-interaction-mode
LaTeX-mode TeX-mode)
"Modes in which to indent regions that are yanked (or yank-popped)")
(defvar yank-advised-indent-threshold 1000
"Threshold (# chars) over which indentation does not automatically occur.")
(defun yank-advised-indent-function (beg end)
"Do indentation, as long as the region isn't too large."
(if (<= (- end beg) yank-advised-indent-threshold)
(indent-region beg end nil)))
(defadvice yank (after yank-indent activate)
"If current mode is one of 'yank-indent-modes, indent yanked text (with prefix arg don't indent)."
(if (and (not (ad-get-arg 0))
(member major-mode yank-indent-modes))
(let ((transient-mark-mode nil))
(yank-advised-indent-function (region-beginning) (region-end)))))

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