Browse Source

Save and restore outline visibility when pressing C-c C-c on a meta line

Carsten Dominik 15 years ago
parent
commit
a3b773e419
2 changed files with 60 additions and 1 deletions
  1. 3 0
      lisp/ChangeLog
  2. 57 1
      lisp/org.el

+ 3 - 0
lisp/ChangeLog

@@ -2,6 +2,9 @@
 
 	* org.el (org-inhibit-startup-visibility-stuff): New variable.
 	(org-mode): Don't do startup visibility if inhibited.
+	(org-outline-overlay-data, org-set-outline-overlay-data): New
+	functions.
+	(org-save-outline-visibility): New macro.
 
 2009-12-13  Carsten Dominik  <carsten.dominik@gmail.com>
 

+ 57 - 1
lisp/org.el

@@ -5631,6 +5631,62 @@ Optional argument N means, put the headline into the Nth line of the window."
     (beginning-of-line)
     (recenter (prefix-numeric-value N))))
 
+;;; Saving and restoring visibility
+
+(defun org-outline-overlay-data (&optional use-markers)
+  "Return a list of the locations of all outline overlays.
+The are overlays with the `invisible' property value `outline'.
+The return valus is a list of cons cells, with start and stop
+positions for each overlay.
+If USE-MARKERS is set, return the positions as markers."
+  (let (beg end)
+    (save-excursion
+      (save-restriction
+	(widen)
+	(delq nil
+	      (mapcar (lambda (o) 
+			(when (eq (org-overlay-get o 'invisible) 'outline)
+			  (setq beg (org-overlay-start o)
+				end (org-overlay-end o))
+			  (and beg end (> end beg)
+			       (if use-markers
+				   (cons (move-marker (make-marker) beg)
+					 (move-marker (make-marker) end))
+				 (cons beg end)))))
+		      (org-overlays-in (point-min) (point-max))))))))
+
+(defun org-set-outline-overlay-data (data)
+  "Create visibility overlays for all positions in DATA.
+DATA should have been made by `org-outline-overlay-data'."
+  (let (o)
+    (save-excursion
+      (save-restriction
+	(widen)
+	(show-all)
+	(mapc (lambda (c)
+		(setq o (org-make-overlay (car c) (cdr c)))
+		(org-overlay-put o 'invisible 'outline))
+	      data)))))
+
+(defmacro org-save-outline-visibility (use-markers &rest body)
+  "Save and restore outline visibility around BODY.
+If USE-MARKERS is non-nil, use markers for the positions.
+This means that the buffer may change while running BODY,
+but it also means that the buffer should stay alive
+during the operation, because otherwise all these markers will
+point nowhere."
+  `(let ((data (org-outline-overlay-data ,use-markers)))
+     (unwind-protect
+	 (progn
+	   ,@body
+	   (org-set-outline-overlay-data data))
+       (when ,use-markers
+	 (mapc (lambda (c)
+		 (and (markerp (car c)) (move-marker (car c) nil))
+		 (and (markerp (cdr c)) (move-marker (cdr c) nil)))
+	       data)))))
+
+
 ;;; Folding of blocks
 
 (defconst org-block-regexp
@@ -15760,7 +15816,7 @@ This command does many different things, depending on context:
        (t
 	(let ((org-inhibit-startup-visibility-stuff t)
 	      (org-startup-align-all-tables nil))
-	  (org-mode-restart))
+	  (org-save-outline-visibility 'use-markers (org-mode-restart)))
 	(message "Local setup has been refreshed"))))
      ((org-clock-update-time-maybe))
      (t (error "C-c C-c can do nothing useful at this location")))))