emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Aaron Ecay <aaronecay@gmail.com>
To: "emacs-orgmode@gnu.org" <emacs-orgmode@gnu.org>
Subject: [patch] fix the behavior of C-u C-u TAB
Date: Mon, 16 Dec 2013 18:57:57 -0500	[thread overview]
Message-ID: <87vbyoe4ca.fsf@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1337 bytes --]

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,

[-- Attachment #2: 0001-fix-C-u-C-u-TAB-set-visibility-to-initial-status.patch --]
[-- Type: text/x-diff, Size: 2864 bytes --]

From af05e125fce67e916c317bc179461375f2eb179b Mon Sep 17 00:00:00 2001
From: Aaron Ecay <aaronecay@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


[-- Attachment #3: Type: text/plain, Size: 15 bytes --]

-- 
Aaron Ecay

             reply	other threads:[~2013-12-16 23:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-16 23:57 Aaron Ecay [this message]
2014-01-04 11:24 ` [patch] fix the behavior of C-u C-u TAB Bastien

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vbyoe4ca.fsf@gmail.com \
    --to=aaronecay@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).