소스 검색

Hide and show the contents of blocks

Patch by Eric Schulte, with modifications.
Carsten Dominik 16 년 전
부모
커밋
bfa7c38c1c
3개의 변경된 파일145개의 추가작업 그리고 3개의 파일을 삭제
  1. 32 2
      doc/org.texi
  2. 14 0
      lisp/ChangeLog
  3. 99 1
      lisp/org.el

+ 32 - 2
doc/org.texi

@@ -121,6 +121,7 @@ Document Structure
 * Sparse trees::                Matches embedded in context
 * Plain lists::                 Additional structure within an entry
 * Drawers::                     Tucking stuff away
+* Blocks::                      Folding blocks
 * Footnotes::                   How footnotes are defined in Org's syntax
 * Orgstruct mode::              Structure editing outside Org
 
@@ -715,6 +716,7 @@ edit the structure of the document.
 * Sparse trees::                Matches embedded in context
 * Plain lists::                 Additional structure within an entry
 * Drawers::                     Tucking stuff away
+* Blocks::                      Folding blocks
 * Footnotes::                   How footnotes are defined in Org's syntax
 * Orgstruct mode::              Structure editing outside Org
 @end menu
@@ -1424,7 +1426,7 @@ Sort the plain list.  You will be prompted for the sorting method:
 numerically, alphabetically, by time, or by custom function.
 @end table
 
-@node Drawers, Footnotes, Plain lists, Document Structure
+@node Drawers, Blocks, Plain lists, Document Structure
 @section Drawers
 @cindex drawers
 @cindex visibility cycling, drawers
@@ -1454,7 +1456,26 @@ storing properties (@pxref{Properties and Columns}), and you can also arrange
 for state change notes @pxref{Tracking TODO state changes} and clock times
 (@pxref{Clocking work time}) to be stored in a drawer @code{LOGBOOK}.
 
-@node Footnotes, Orgstruct mode, Drawers, Document Structure
+@node Blocks, Footnotes, Drawers, Document Structure
+@section Blocks
+
+@vindex org-hide-block-startup
+@cindex blocks, folding
+Org-mode uses begin...end blocks for various purposes from including source
+code examples (@pxref{Literal examples}) to capturing time logging
+information (@pxref{Clocking work time}).  These blocks can be folded and
+unfolded by pressing TAB in the begin line.  You can also get all blocks
+folded at startup by configuring the variable @code{org-hide-block-startup}
+or on a per-file basis by using
+
+@cindex @code{hideblocks}, STARTUP keyword
+@cindex @code{nohideblocks}, STARTUP keyword
+@example
+#+STARTUP: hideblocks
+#+STARTUP: nohideblocks
+@end example
+
+@node Footnotes, Orgstruct mode, Blocks, Document Structure
 @section Footnotes
 @cindex footnotes
 
@@ -9947,6 +9968,15 @@ fnauto      @r{create [fn:1]-like labels automatically (default)}
 fnconfirm   @r{offer automatic label for editing or confirmation}
 fnplain     @r{create [1]-like labels automatically}
 @end example
+@cindex org-hide-block-startup
+To hide blocks on startup, use these keywords. The corresponding variable is
+@code{org-hide-block-startup}.
+@cindex @code{hideblocks}, STARTUP keyword
+@cindex @code{nohideblocks}, STARTUP keyword
+@example
+hideblocks   @r{Hide all begin/end blocks on startup}
+nohideblocks @r{Do not hide blocks on startup}
+@end example
 @item #+TAGS:  TAG1(c1) TAG2(c2)
 @vindex org-tag-alist
 These lines (several such lines are allowed) specify the valid tags in

+ 14 - 0
lisp/ChangeLog

@@ -1,3 +1,17 @@
+2009-06-02  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.el (org-startup-options): New keywords blockhide and
+	blockshow.
+	(org-mode): Add new invisibility spec.
+	(org-set-startup-visibility): Hide block on startup if so
+	desired.
+	(org-hide-block-startup): New option.
+	(org-block-regexp): New constant.
+	(org-hide-block-overlays): New variable.
+	(org-block-map, org-hide-block-toggle-all, org-hide-block-all)
+	(org-show-block-all, org-hide-block-toggle-maybe)
+	(org-hide-block-toggle): New functions.
+
 2009-05-30  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org.el (org-buffer-property-keys): Add Effort property for

+ 99 - 1
lisp/org.el

@@ -3438,7 +3438,9 @@ After a match, the following groups carry important information:
     ("fnplain" org-footnote-auto-label plain)
     ("constcgs" constants-unit-system cgs)
     ("constSI" constants-unit-system SI)
-    ("noptag" org-tag-persistent-alist nil))
+    ("noptag" org-tag-persistent-alist nil)
+    ("hideblocks" org-hide-block-startup t)
+    ("nohideblocks" org-hide-block-startup nil))
   "Variable associated with STARTUP options for org-mode.
 Each element is a list of three items: The startup options as written
 in the #+STARTUP line, the corresponding variable, and the value to
@@ -3871,6 +3873,7 @@ The following commands are available:
   (org-install-agenda-files-menu)
   (if org-descriptive-links (org-add-to-invisibility-spec '(org-link)))
   (org-add-to-invisibility-spec '(org-cwidth))
+  (org-add-to-invisibility-spec '(org-hide-block . t))
   (when (featurep 'xemacs)
     (org-set-local 'line-move-ignore-invisible t))
   (org-set-local 'outline-regexp org-outline-regexp)
@@ -4952,6 +4955,7 @@ With a numeric prefix, show all headlines up to that level."
    ((eq org-startup-folded 'content)
     (let ((this-command 'org-cycle) (last-command 'org-cycle))
       (org-cycle '(4)) (org-cycle '(4)))))
+  (if org-hide-block-startup (org-hide-block-all))
   (org-set-visibility-according-to-property 'no-cleanup)
   (org-cycle-hide-archived-subtrees 'all)
   (org-cycle-hide-drawers 'all)
@@ -5128,6 +5132,100 @@ Optional argument N means, put the headline into the Nth line of the window."
     (beginning-of-line)
     (recenter (prefix-numeric-value N))))
 
+;;; Folding of blocks
+
+(defcustom org-hide-block-startup nil
+  "Non-nil means, , entering Org-mode will fold all blocks.
+This can also be set in on a per-file basis with
+
+#+STARTUP: hideblocks
+#+STARTUP: showblocks"
+  :group 'org-startup
+  :type 'boolean)
+
+(defconst org-block-regexp
+
+  "^[ \t]*#\\+begin_\\([^ \n]+\\)\\(\\([^\n]+\\)\\)?\n\\([^\000]+?\\)#\\+end_\\1"
+  "Regular expression for hiding blocks.")
+
+(defvar org-hide-block-overlays nil
+  "Overays hiding blocks.")
+(make-variable-buffer-local 'org-hide-block-overlays)
+
+(defun org-block-map (function &optional start end)
+  "Call func at the head of all source blocks in the current
+buffer.  Optional arguments START and END can be used to limit
+the range."
+  (let ((start (or start (point-min)))
+        (end (or end (point-max))))
+    (save-excursion
+      (goto-char start)
+      (while (and (< (point) end) (re-search-forward org-block-regexp end t))
+	(save-excursion
+	  (save-match-data
+            (goto-char (match-beginning 0))
+            (funcall function)))))))
+
+(defun org-hide-block-toggle-all ()
+  "Toggle the visibility of all blocks in the current buffer."
+  (org-block-map #'org-hide-block-toggle))
+
+(defun org-hide-block-all ()
+  "Fold all blocks in the current buffer."
+  (interactive)
+  (org-show-block-all)
+  (org-block-map #'org-hide-block-toggle-maybe))
+
+(defun org-show-block-all ()
+  "Unfold all blocks in the current buffer."
+  (mapc 'org-delete-overlay org-hide-block-overlays)
+  (setq org-hide-block-overlays nil))
+
+(defun org-hide-block-toggle-maybe ()
+  "Toggle visibility of block at point."
+  (interactive)
+  (let ((case-fold-search t))
+    (if (save-excursion
+          (beginning-of-line 1)
+          (looking-at org-block-regexp))
+        (progn (org-hide-block-toggle)
+               t) ;; to signal that we took action
+      nil))) ;; to signal that we did not
+
+(defun org-hide-block-toggle (&optional force)
+  "Toggle the visibility of the current block."
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (if (re-search-forward org-block-regexp nil t)
+        (let ((start (- (match-beginning 4) 1)) ;; beginning of body
+              (end (match-end 0))
+	      ov) ;; end of entire body
+          (if (memq t (mapcar (lambda (overlay)
+                                (eq (org-overlay-get overlay 'invisible)
+				    'org-hide-block))
+                              (org-overlays-at start)))
+	      (if (or (not force) (eq force 'off))
+		  (mapc (lambda (ov)
+			  (when (member ov org-hide-block-overlays)
+			    (setq org-hide-block-overlays
+				  (delq ov org-hide-block-overlays)))
+			  (when (eq (org-overlay-get ov 'invisible)
+				    'org-hide-block)
+			    (org-delete-overlay ov)))
+			(org-overlays-at start)))
+	    (setq ov (make-overlay start end))
+            (org-overlay-put ov 'invisible 'org-hide-block)
+	    (push ov org-hide-block-overlays)))
+      (error "Not looking at a source block"))))
+
+;; org-tab-after-check-for-cycling-hook
+(add-hook 'org-tab-first-hook 'org-hide-block-toggle-maybe)
+;; Remove overlays when changing major mode
+(add-hook 'org-mode-hook
+	  (lambda () (org-add-hook 'change-major-mode-hook
+				   'org-show-block-all 'append 'local)))
+
 ;;; Org-goto
 
 (defvar org-goto-window-configuration nil)