From ee9826f62698b2e5d200fdf90a963ddd751ad679 Mon Sep 17 00:00:00 2001 From: Dmitrii Korobeinikov Date: Fri, 3 Apr 2020 16:19:33 +0600 Subject: [PATCH] org.el: Add an option to restore scroll position when collapsing a tree * lisp/org.el (org-optimize-window-after-visibility-change): Restore the scroll position after folding a tree (if no commands other than `org-cycle' get executed in the meantime, so has to be right after its expansion). (org-restore-scroll-position-on-collapse): Non-nil for the new behavior. `org-cycle' scrolls the buffer when expanding a large tree to show as much of the tree as possible, but doesn't restore the initial view when folding back, which is disorienting. TINYCHANGE --- lisp/org.el | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 06891b8bd..1b2dfdb8c 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6071,6 +6071,9 @@ region as a drawer without further ado." (put 'org-cycle-global-status 'org-state t) (defvar-local org-cycle-subtree-status nil) (put 'org-cycle-subtree-status 'org-state t) +(defvar-local org-scroll-position-to-restore-after-cycling nil) +(defvar org-restore-scroll-position-on-collapse t + "Non-nil if should restore display position after org-cycle folds the tree.") (defun org-show-all (&optional types) "Show all contents in the visible part of the buffer. @@ -6501,9 +6504,17 @@ This function is the default value of the hook `org-cycle-hook'." (cond ((eq state 'content) nil) ((eq state 'all) nil) - ((eq state 'folded) nil) - ((eq state 'children) (or (org-subtree-end-visible-p) (recenter 1))) - ((eq state 'subtree) (or (org-subtree-end-visible-p) (recenter 1)))))) + ((eq state 'folded) + (if (and org-restore-scroll-position-on-collapse + (eq last-command this-command)) + (set-window-start nil org-scroll-position-to-restore-after-cycling))) + ((eq state 'children) + (setq org-scroll-position-to-restore-after-cycling (window-start)) + (or (org-subtree-end-visible-p) (recenter 1))) + ((eq state 'subtree) + (if (not (eq last-command this-command)) + (setq org-scroll-position-to-restore-after-cycling (window-start))) + (or (org-subtree-end-visible-p) (recenter 1)))))) (defun org-clean-visibility-after-subtree-move () "Fix visibility issues after moving a subtree." -- 2.25.1