Merge from emacs--rel--22
[bpt/emacs.git] / lisp / progmodes / hideshow.el
CommitLineData
26d654ec 1;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks
6da7653c 2
034babe1 3;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
48d33090 4;; 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
b578f267 5
9b4a7800 6;; Author: Thien-Thi Nguyen <ttn@gnu.org>
26a0b399 7;; Dan Nicolaescu <dann@ics.uci.edu>
b7c09257 8;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines
a5b101dc 9;; Maintainer-Version: 5.65.2.2
b578f267
EN
10;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning
11
12;; This file is part of GNU Emacs.
13
14;; GNU Emacs is free software; you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
1a484753 16;; the Free Software Foundation; either version 3, or (at your option)
b578f267
EN
17;; any later version.
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs; see the file COPYING. If not, write to the
3a35cf56
LK
26;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA.
b578f267 28
6da7653c
TTN
29;;; Commentary:
30
26a0b399 31;; * Commands provided
aaa114d0 32;;
a23c5037 33;; This file provides Hideshow Minor Mode. When active, nine commands
1a8e83dc 34;; are available, implementing block hiding and showing. They (and their
26a0b399 35;; keybindings) are:
aaa114d0 36;;
60470e65
TTN
37;; hs-hide-block C-c @ C-h
38;; hs-show-block C-c @ C-s
39;; hs-hide-all C-c @ C-M-h
40;; hs-show-all C-c @ C-M-s
41;; hs-hide-level C-c @ C-l
42;; hs-toggle-hiding C-c @ C-c
26d654ec 43;; hs-mouse-toggle-hiding [(shift mouse-2)]
26a0b399 44;; hs-hide-initial-comment-block
b578f267 45;;
26a0b399
TTN
46;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they
47;; are simply text between curly braces, while in Lisp-ish modes parens
48;; are used. Multi-line comment blocks can also be hidden. Read-only
49;; buffers are not a problem, since hideshow doesn't modify the text.
50;;
51;; The command `M-x hs-minor-mode' toggles the minor mode or sets it
52;; (similar to other minor modes).
b578f267 53
26d654ec
TTN
54;; * Suggested usage
55;;
56;; First make sure hideshow.el is in a directory in your `load-path'.
57;; You can optionally byte-compile it using `M-x byte-compile-file'.
58;; Then, add the following to your ~/.emacs:
59;;
60;; (load-library "hideshow")
61;; (add-hook 'X-mode-hook ; other modes similarly
aa7d6700 62;; (lambda () (hs-minor-mode 1)))
26d654ec
TTN
63;;
64;; where X = {emacs-lisp,c,c++,perl,...}. You can also manually toggle
65;; hideshow minor mode by typing `M-x hs-minor-mode'. After hideshow is
66;; activated or deactivated, `hs-minor-mode-hook' is run w/ `run-hooks'.
67;;
68;; Additionally, Joseph Eydelnant writes:
69;; I enjoy your package hideshow.el Ver. 5.24 2001/02/13
70;; a lot and I've been looking for the following functionality:
71;; toggle hide/show all with a single key.
72;; Here are a few lines of code that lets me do just that.
73;;
74;; (defvar my-hs-hide nil "Current state of hideshow for toggling all.")
75;; ;;;###autoload
76;; (defun my-toggle-hideshow-all () "Toggle hideshow all."
77;; (interactive)
78;; (setq my-hs-hide (not my-hs-hide))
79;; (if my-hs-hide
80;; (hs-hide-all)
81;; (hs-show-all)))
82;;
83;; [Your hideshow hacks here!]
84
26a0b399
TTN
85;; * Customization
86;;
87;; You can use `M-x customize-variable' on the following variables:
88;;
9b4a7800
TTN
89;; - hs-hide-comments-when-hiding-all -- self-explanatory!
90;; - hs-hide-all-non-comment-function -- if non-nil, when doing a
91;; `hs-hide-all', this function
92;; is called w/ no arguments
93;; - hs-isearch-open -- what kind of hidden blocks to
26a0b399
TTN
94;; open when doing isearch
95;;
9b4a7800
TTN
96;; Some languages (e.g., Java) are deeply nested, so the normal behavior
97;; of `hs-hide-all' (hiding all but top-level blocks) results in very
98;; little information shown, which is not very useful. You can use the
99;; variable `hs-hide-all-non-comment-function' to implement your idea of
100;; what is more useful. For example, the following code shows the next
101;; nested level in addition to the top-level:
102;;
103;; (defun ttn-hs-hide-level-1 ()
104;; (hs-hide-level 1)
105;; (forward-sexp 1))
106;; (setq hs-hide-all-non-comment-function 'ttn-hs-hide-level-1)
107;;
26a0b399
TTN
108;; Hideshow works w/ incremental search (isearch) by setting the variable
109;; `hs-headline', which is the line of text at the beginning of a hidden
110;; block that contains a match for the search. You can have this show up
111;; in the mode line by modifying the variable `mode-line-format'. For
112;; example, the following code prepends this info to the mode line:
aaa114d0 113;;
26a0b399
TTN
114;; (unless (memq 'hs-headline mode-line-format)
115;; (setq mode-line-format
116;; (append '("-" hs-headline) mode-line-format)))
aaa114d0 117;;
26a0b399 118;; See documentation for `mode-line-format' for more info.
aaa114d0
TTN
119;;
120;; Hooks are run after some commands:
121;;
122;; hs-hide-hook in hs-hide-block, hs-hide-all, hs-hide-level
9b4a7800 123;; hs-show-hook hs-show-block, hs-show-all
aaa114d0 124;;
9b4a7800
TTN
125;; One of `hs-hide-hook' or `hs-show-hook' is run for the toggling
126;; commands when the result of the toggle is to hide or show blocks,
127;; respectively. All hooks are run w/ `run-hooks'. See docs for each
128;; variable or hook for more info.
26a0b399
TTN
129;;
130;; Normally, hideshow tries to determine appropriate values for block
131;; and comment definitions by examining the buffer's major mode. If
132;; there are problems, hideshow will not activate and in that case you
133;; may wish to override hideshow's heuristics by adding an entry to
134;; variable `hs-special-modes-alist'. Packages that use hideshow should
135;; do something like:
136;;
aa7d6700 137;; (add-to-list 'hs-special-modes-alist '(my-mode "{{" "}}" ...))
26a0b399
TTN
138;;
139;; If you have an entry that works particularly well, consider
140;; submitting it for inclusion in hideshow.el. See docstring for
141;; `hs-special-modes-alist' for more info on the entry format.
dfdc1af2
TTN
142;;
143;; See also variable `hs-set-up-overlay' for per-block customization of
144;; appearance or other effects associated with overlays. For example:
145;;
146;; (setq hs-set-up-overlay
147;; (defun my-display-code-line-counts (ov)
148;; (when (eq 'code (overlay-get ov 'hs))
149;; (overlay-put ov 'display
150;; (propertize
151;; (format " ... <%d>"
152;; (count-lines (overlay-start ov)
153;; (overlay-end ov)))
154;; 'face 'font-lock-type-face)))))
b578f267 155
26a0b399
TTN
156;; * Bugs
157;;
158;; (1) Hideshow does not work w/ emacs 18 because emacs 18 lacks the
159;; function `forward-comment' (among other things). If someone
160;; writes this, please send me a copy.
161;;
162;; (2) Sometimes `hs-headline' can become out of sync. To reset, type
26d654ec 163;; `M-x hs-minor-mode' twice (that is, deactivate then re-activate
26a0b399 164;; hideshow).
aaa114d0 165;;
26d654ec 166;; (3) Hideshow 5.x is developed and tested on GNU Emacs 20.7.
26a0b399 167;; XEmacs compatibility may have bitrotted since 4.29.
aaa114d0 168;;
9b4a7800
TTN
169;; (4) Some buffers can't be `byte-compile-file'd properly. This is because
170;; `byte-compile-file' inserts the file to be compiled in a temporary
171;; buffer and switches `normal-mode' on. In the case where you have
172;; `hs-hide-initial-comment-block' in `hs-minor-mode-hook', the hiding of
173;; the initial comment sometimes hides parts of the first statement (seems
174;; to be only in `normal-mode'), so there are unbalanced "(" and ")".
175;;
176;; The workaround is to clear `hs-minor-mode-hook' when byte-compiling:
177;;
178;; (defadvice byte-compile-file (around
179;; byte-compile-file-hideshow-off
180;; act)
181;; (let ((hs-minor-mode-hook nil))
182;; ad-do-it))
26d654ec
TTN
183;;
184;; (5) Hideshow interacts badly with Ediff and `vc-diff'. At the moment, the
185;; suggested workaround is to turn off hideshow entirely, for example:
186;;
26d654ec
TTN
187;; (add-hook 'ediff-prepare-buffer-hook 'turn-off-hideshow)
188;; (add-hook 'vc-before-checkin-hook 'turn-off-hideshow)
189;;
190;; In the case of `vc-diff', here is a less invasive workaround:
191;;
192;; (add-hook 'vc-before-checkin-hook
aa7d6700
TTN
193;; (lambda ()
194;; (goto-char (point-min))
195;; (hs-show-block)))
26d654ec
TTN
196;;
197;; Unfortunately, these workarounds do not restore hideshow state.
198;; If someone figures out a better way, please let me know.
9b4a7800 199
26d654ec
TTN
200;; * Correspondance
201;;
26a0b399 202;; Correspondance welcome; please indicate version number. Send bug
9b4a7800 203;; reports and inquiries to <ttn@gnu.org>.
b578f267 204
26a0b399 205;; * Thanks
aaa114d0 206;;
26a0b399
TTN
207;; Thanks go to the following people for valuable ideas, code and
208;; bug reports.
aaa114d0 209;;
2bbf1842
TTN
210;; Dean Andrews, Alf-Ivar Holm, Holger Bauer, Christoph Conrad, Dave Love,
211;; Dirk Herrmann, Gael Marziou, Jan Djarv, Guillaume Leray, Moody Ahmad,
212;; Preston F. Crow, Lars Lindberg, Reto Zimmermann, Keith Sheffield,
213