The keystroke C-u C-u TAB is supposed to set the visibility of the buffer to its initial state. At a minimum, I expect the second...nth consecutive use of this key combo to not change the visibility of the buffer at all. I have ‘org-startup-folded’ set to 'content (i.e. show all headlines, but no text), and for me C-u C-u TAB instead cycles through various visibility states.
Does anyone else observe this behavior? A reading of the code indicates that it should be a problem with org-startup-folded set to 'content, and possibly with the 'all value of that variable as well. The attached patch changes to a new implementation at the cost of sometimes doing extra cycling. (The problem is that we cannot rely on the org-cycle-global-status variable except immediately after a global cycle, and we can’t AFAICS know when we are immediately after such an event. It might be better to set org-global-cycle-status to nil after any visibility-changing command, to indicate that its value is not to be trusted. But I think it would be difficult to exhaustively find all such functions, and then to differentiate between “good” uses that hide e.g. archived subtrees and “bad” uses that mess up the proper global visibility state by individually toggling a headline.) Comments welcome. Thanks,
>From af05e125fce67e916c317bc179461375f2eb179b Mon Sep 17 00:00:00 2001 From: Aaron Ecay <aarone...@gmail.com> Date: Mon, 16 Dec 2013 18:38:03 -0500 Subject: [PATCH] fix C-u C-u TAB -> set visibility to initial status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/org.el (org-set-startup-visibility): refactor to work properly Previously, ‘org-set-startup-visibility’ would use a pre-calculated number of trips through ‘org-cycle’ to get the right visibility. This is fragile, and sometimes wrong. This new implementation instead loops until the visibility is correct (erroring out after 5 tries to avoid an infloop). --- lisp/org.el | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 59f55a8..07a2942 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6891,12 +6891,35 @@ With a numeric prefix, show all headlines up to that level." (defun org-set-startup-visibility () "Set the visibility required by startup options and properties." - (cond - ((eq org-startup-folded t) - (org-cycle '(4))) - ((eq org-startup-folded 'content) - (let ((this-command 'org-cycle) (last-command 'org-cycle)) - (org-cycle '(4)) (org-cycle '(4))))) + (let ((goal-state 'all) + ;; Hack the following two variables to make + ;; `org-cycle-internal-global' do the right thing; with these + ;; unbound it perseverates in the overview state. + (last-command 'org-cycle) + (this-command 'org-cycle)) + (cond + ((eq org-startup-folded t) + (setq goal-state 'overview)) + ((eq org-startup-folded 'content) + ;; Annoyingly 'content' is spelled with an 's' in one variable, + ;; and without in another. + (setq goal-state 'contents))) + ;; Cycle once unconditionally so that `org-cycle-global-status' is + ;; synced with the state of the buffer (this may turn out to be + ;; overly conservative). + (org-cycle '(4)) + (dotimes (_ 5) + ;; Now try to get into the right state. We try 5 times just to + ;; make sure, even though strictly speaking 3 is the maximum + ;; number of states we could progress thorugh; see the + ;; implementation of `org-cycle-internal-global'. + (unless (eq org-cycle-global-status goal-state) + (org-cycle '(4)))) + ;; Something weird is going on; we cannot get into the right + ;; state. Error out and hope this prompts a bug report. + (unless (eq org-cycle-global-status goal-state) + (error "Could not get the correct visibility state after trying 5 times!"))) + (unless (eq org-startup-folded 'showeverything) (if org-hide-block-startup (org-hide-block-all)) (org-set-visibility-according-to-property 'no-cleanup) -- 1.8.5.1
-- Aaron Ecay