diff options
| author | Thien-Thi Nguyen | 1999-12-26 11:03:32 +0000 |
|---|---|---|
| committer | Thien-Thi Nguyen | 1999-12-26 11:03:32 +0000 |
| commit | 26a0b3991e4bf4749b4486b264bfc05627606689 (patch) | |
| tree | b05b5f8613b37839be384b529900a198ef177587 | |
| parent | f7c9e039d2487f11d2d714ce6803a464040be6cd (diff) | |
| download | emacs-26a0b3991e4bf4749b4486b264bfc05627606689.tar.gz emacs-26a0b3991e4bf4749b4486b264bfc05627606689.zip | |
Generally, synch w/ maintainer version 5.9.
(hs-show-hidden-short-form): Delete var; hard-code uses as `t'.
(hs-minor-mode-hook): Don't initialize.
(hs-special-modes-alist): Rewrite value and docstring.
(hs-minor-mode-prefix): Delete unused var.
(hs-block-start-mdata-select): New var, buffer local.
(hs-headline): New var.
(hs-match-data, hs-forward-sexp): New funcs.
(hs-hide-comment-region): New func.
(hs-discard-overlays, hs-flag-region, hs-hide-block-at-point,
hs-safety-is-job-n, hs-hide-initial-comment-block, hs-inside-comment-p,
hs-grok-mode-type, hs-find-block-beginning, hs-hide-level-recursive,
hs-life-goes-on, hs-already-hidden-p, hs-c-like-adjust-block-beginning,
hs-hide-all, hs-show-all, hs-hide-block, hs-show-block, hs-show-region,
hs-hide-level, hs-mouse-toggle-hiding, hs-minor-mode): Rewrite.
(hs-isearch-show): Renamed from `hs-isearch-open-invisible'.
(hs-isearch-show-temporary): New funcs.
(hs-show-block-at-point, java-hs-forward-sexp): Delete funcs.
(hs-hide-all, hs-mouse-toggle-hiding): Don't autoload.
When constructing menu, use `[(shift button2)]' notation.
| -rw-r--r-- | lisp/progmodes/hideshow.el | 1109 |
1 files changed, 555 insertions, 554 deletions
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 85c917cdae7..6573ab35e68 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | ;;; hideshow.el --- minor mode cmds to selectively display blocks of code | 1 | ;;; hideshow.el --- minor mode cmds to selectively display blocks of code |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation | 3 | ;; Copyright (C) 1994, 95, 96, 97, 98, 99 Free Software Foundation |
| 4 | 4 | ||
| 5 | ;; Author: Thien-Thi Nguyen <ttn@netcom.com> | 5 | ;; Author: Thien-Thi Nguyen <ttn@netcom.com> |
| 6 | ;; Dan Nicolaescu <dann@ics.uci.edu> | 6 | ;; Dan Nicolaescu <dann@ics.uci.edu> |
| 7 | ;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines | 7 | ;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines |
| 8 | ;; Maintainer-Version: 4.22 | 8 | ;; Maintainer-Version: 5.9 |
| 9 | ;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning | 9 | ;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning |
| 10 | 10 | ||
| 11 | ;; This file is part of GNU Emacs. | 11 | ;; This file is part of GNU Emacs. |
| @@ -27,85 +27,149 @@ | |||
| 27 | 27 | ||
| 28 | ;;; Commentary: | 28 | ;;; Commentary: |
| 29 | 29 | ||
| 30 | ;; - Commands provided | 30 | ;; * Commands provided |
| 31 | ;; | 31 | ;; |
| 32 | ;; This file provides `hs-minor-mode'. When active, seven commands: | 32 | ;; This file provides `hs-minor-mode'. When active, eight commands are |
| 33 | ;; available, implementing block hiding and showing. They (and their | ||
| 34 | ;; keybindings) are: | ||
| 33 | ;; | 35 | ;; |
| 34 | ;; hs-{hide,show}-{all,block}, hs-show-region, | 36 | ;; hs-hide-block C-c h |
| 35 | ;; hs-hide-level and hs-minor-mode | 37 | ;; hs-show-block C-c s |
| 38 | ;; hs-hide-all C-c H | ||
| 39 | ;; hs-show-all C-c S | ||
| 40 | ;; hs-show-region C-c R | ||
| 41 | ;; hs-hide-level C-c L | ||
| 42 | ;; hs-mouse-toggle-hiding [(shift button-2)] | ||
| 43 | ;; hs-hide-initial-comment-block | ||
| 36 | ;; | 44 | ;; |
| 37 | ;; are available, implementing block hiding and showing. Blocks are | 45 | ;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they |
| 38 | ;; defined per mode. In c-mode or c++-mode, they are simply curly braces, | 46 | ;; are simply text between curly braces, while in Lisp-ish modes parens |
| 39 | ;; while in Lisp-ish modes they are parens. Multi-line comments can also | 47 | ;; are used. Multi-line comment blocks can also be hidden. Read-only |
| 40 | ;; be hidden. The command `M-x hs-minor-mode' toggles the minor mode or | 48 | ;; buffers are not a problem, since hideshow doesn't modify the text. |
| 41 | ;; sets it (similar to outline minor mode). | 49 | ;; |
| 50 | ;; The command `M-x hs-minor-mode' toggles the minor mode or sets it | ||
| 51 | ;; (similar to other minor modes). | ||
| 42 | 52 | ||
| 43 | ;; - Customization | 53 | ;; * Customization |
| 54 | ;; | ||
| 55 | ;; You can use `M-x customize-variable' on the following variables: | ||
| 56 | ;; | ||
| 57 | ;; hs-hide-comments-when-hiding-all -- self-explanatory! | ||
| 58 | ;; hs-isearch-open -- what kind of hidden blocks to | ||
| 59 | ;; open when doing isearch | ||
| 60 | ;; | ||
| 61 | ;; Hideshow works w/ incremental search (isearch) by setting the variable | ||
| 62 | ;; `hs-headline', which is the line of text at the beginning of a hidden | ||
| 63 | ;; block that contains a match for the search. You can have this show up | ||
| 64 | ;; in the mode line by modifying the variable `mode-line-format'. For | ||
| 65 | ;; example, the following code prepends this info to the mode line: | ||
| 44 | ;; | 66 | ;; |
| 45 | ;; Variables control things thusly: | 67 | ;; (unless (memq 'hs-headline mode-line-format) |
| 68 | ;; (setq mode-line-format | ||
| 69 | ;; (append '("-" hs-headline) mode-line-format))) | ||
| 46 | ;; | 70 | ;; |
| 47 | ;; hs-hide-comments-when-hiding-all -- self-explanatory! | 71 | ;; See documentation for `mode-line-format' for more info. |
| 48 | ;; hs-show-hidden-short-form -- whether or not the last line in a form | ||
| 49 | ;; is omitted (saving screen space) | ||
| 50 | ;; hs-isearch-open -- what kind of hidden blocks to open when | ||
| 51 | ;; doing isearch | ||
| 52 | ;; hs-special-modes-alist -- keeps at bay hideshow's heuristics with | ||
| 53 | ;; respect to block definitions | ||
| 54 | ;; | 72 | ;; |
| 55 | ;; Hooks are run after some commands: | 73 | ;; Hooks are run after some commands: |
| 56 | ;; | 74 | ;; |
| 57 | ;; hs-hide-hook in hs-hide-block, hs-hide-all, hs-hide-level | 75 | ;; hs-hide-hook in hs-hide-block, hs-hide-all, hs-hide-level |
| 58 | ;; hs-show-hook hs-show-block, hs-show-all, hs-show-region | 76 | ;; hs-show-hook hs-show-block, hs-show-all, hs-show-region |
| 59 | ;; | 77 | ;; |
| 60 | ;; See docs for each variable or hook for more info. | 78 | ;; All hooks are run w/ `run-hooks'. See docs for each variable or hook |
| 79 | ;; for more info. | ||
| 80 | ;; | ||
| 81 | ;; Normally, hideshow tries to determine appropriate values for block | ||
| 82 | ;; and comment definitions by examining the buffer's major mode. If | ||
| 83 | ;; there are problems, hideshow will not activate and in that case you | ||
| 84 | ;; may wish to override hideshow's heuristics by adding an entry to | ||
| 85 | ;; variable `hs-special-modes-alist'. Packages that use hideshow should | ||
| 86 | ;; do something like: | ||
| 87 | ;; | ||
| 88 | ;; (let ((my-mode-hs-info '(my-mode "{{" "}}" ...))) | ||
| 89 | ;; (if (not (member my-mode-hs-info hs-special-modes-alist)) | ||
| 90 | ;; (setq hs-special-modes-alist | ||
| 91 | ;; (cons my-mode-hs-info hs-special-modes-alist)))) | ||
| 92 | ;; | ||
| 93 | ;; If you have an entry that works particularly well, consider | ||
| 94 | ;; submitting it for inclusion in hideshow.el. See docstring for | ||
| 95 | ;; `hs-special-modes-alist' for more info on the entry format. | ||
| 61 | 96 | ||
| 62 | ;; - Suggested usage | 97 | ;; * Suggested usage |
| 98 | ;; | ||
| 99 | ;; First make sure hideshow.el is in a directory in your `load-path'. | ||
| 100 | ;; You can optionally byte-compile it using `M-x byte-compile-file'. | ||
| 101 | ;; Then, add the following to your ~/.emacs: | ||
| 63 | ;; | 102 | ;; |
| 64 | ;; (load-library "hideshow") | 103 | ;; (load-library "hideshow") |
| 65 | ;; (add-hook 'X-mode-hook 'hs-minor-mode) ; other modes similarly | 104 | ;; (add-hook 'X-mode-hook 'hs-minor-mode) ; other modes similarly |
| 66 | ;; | 105 | ;; |
| 67 | ;; where X = {emacs-lisp,c,c++,perl,...}. See the doc for the variable | 106 | ;; where X = {emacs-lisp,c,c++,perl,...}. You can also manually toggle |
| 68 | ;; `hs-special-modes-alist' if you'd like to use hideshow w/ other modes. | 107 | ;; hideshow minor mode by typing `M-x hs-minor-mode'. After hideshow is |
| 108 | ;; activated, `hs-minor-mode-hook' is run w/ `run-hooks'. A good hook | ||
| 109 | ;; to add is `hs-hide-initial-comment-block'. | ||
| 69 | 110 | ||
| 70 | ;; - Bugs / caveats | 111 | ;; * Bugs |
| 112 | ;; | ||
| 113 | ;; (1) Hideshow does not work w/ emacs 18 because emacs 18 lacks the | ||
| 114 | ;; function `forward-comment' (among other things). If someone | ||
| 115 | ;; writes this, please send me a copy. | ||
| 116 | ;; | ||
| 117 | ;; (2) Sometimes `hs-headline' can become out of sync. To reset, type | ||
| 118 | ;; `M-x hs-minor-mode' twice (that is, deactivate then activate | ||
| 119 | ;; hideshow). | ||
| 71 | ;; | 120 | ;; |
| 72 | ;; 1. Hideshow does not work w/ emacs 18 because emacs 18 lacks the | 121 | ;; (3) Hideshow 5.x is developed and tested on GNU Emacs 20.4. |
| 73 | ;; function `forward-comment' (among other things). If someone writes | 122 | ;; XEmacs compatibility may have bitrotted since 4.29. |
| 74 | ;; this, please send me a copy. | ||
| 75 | ;; | 123 | ;; |
| 76 | ;; 2. Users of cc-mode.el should not hook hideshow into | 124 | ;; Correspondance welcome; please indicate version number. Send bug |
| 77 | ;; c-mode-common-hook since at that stage of the call sequence, the | 125 | ;; reports and inquiries to <ttn@netcom.com>. |
| 78 | ;; variables `comment-start' and `comment-end' are not yet provided. | ||
| 79 | ;; Instead, use c-mode-hook and c++-mode-hook as suggested above. | ||
| 80 | 126 | ||
| 81 | ;; - Thanks and feedback | 127 | ;; * Thanks |
| 82 | ;; | 128 | ;; |
| 83 | ;; Thanks go to the following people for valuable ideas, code and bug | 129 | ;; Thanks go to the following people for valuable ideas, code and |
| 84 | ;; reports. | 130 | ;; bug reports. |
| 85 | ;; adahome@ix.netcom.com Dean Andrews | ||
| 86 | ;; alfh@ifi.uio.no Alf-Ivar Holm | ||
| 87 | ;; gael@gnlab030.grenoble.hp.com Gael Marziou | ||
| 88 | ;; jan.djarv@sa.erisoft.se Jan Djarv | ||
| 89 | ;; preston.f.crow@dartmouth.edu Preston F. Crow | ||
| 90 | ;; qhslali@aom.ericsson.se Lars Lindberg | ||
| 91 | ;; sheff@edcsgw2.cr.usgs.gov Keith Sheffield | ||
| 92 | ;; ware@cis.ohio-state.edu Pete Ware | ||
| 93 | ;; d.love@dl.ac.uk Dave Love | ||
| 94 | ;; | 131 | ;; |
| 95 | ;; Special thanks go to Dan Nicolaescu <dann@ics.uci.edu>, who | 132 | ;; adahome@ix.netcom.com Dean Andrews |
| 96 | ;; reimplemented hideshow using overlays (rather than selective display), | 133 | ;; alfh@ifi.uio.no Alf-Ivar Holm |
| 97 | ;; added isearch magic, folded in custom.el compatibility, generalized | 134 | ;; bauer@itsm.uni-stuttgart.de Holger Bauer |
| 98 | ;; comment handling, incorporated mouse support, and maintained the code | 135 | ;; christoph.conrad@post.rwth-aachen.de Christoph Conrad |
| 99 | ;; in general. Version 4.0 is largely due to his efforts. | 136 | ;; d.love@dl.ac.uk Dave Love |
| 137 | ;; dirk@ida.ing.tu-bs.de Dirk Herrmann | ||
| 138 | ;; gael@gnlab030.grenoble.hp.com Gael Marziou | ||
| 139 | ;; jan.djarv@sa.erisoft.se Jan Djarv | ||
| 140 | ;; leray@dev-lme.pcc.philips.com Guillaume Leray | ||
| 141 | ;; moody@mwt.net Moody Ahmad | ||
| 142 | ;; preston.f.crow@dartmouth.edu Preston F. Crow | ||
| 143 | ;; qhslali@aom.ericsson.se Lars Lindberg | ||
| 144 | ;; reto@synopsys.com Reto Zimmermann | ||
| 145 | ;; sheff@edcsgw2.cr.usgs.gov Keith Sheffield | ||
| 146 | ;; smes@post1.com Chew Meng Kuan | ||
| 147 | ;; tonyl@eng.sun.com Tony Lam | ||
| 148 | ;; ware@cis.ohio-state.edu Pete Ware | ||
| 100 | ;; | 149 | ;; |
| 101 | ;; Correspondance welcome; please indicate version number. | 150 | ;; Special thanks go to Dan Nicolaescu <dann@ics.uci.edu>, who reimplemented |
| 151 | ;; hideshow using overlays (rather than selective display), added isearch | ||
| 152 | ;; magic, folded in custom.el compatibility, generalized comment handling, | ||
| 153 | ;; incorporated mouse support, and maintained the code in general. Version | ||
| 154 | ;; 4.0 is largely due to his efforts. | ||
| 155 | |||
| 156 | ;; * History | ||
| 157 | ;; | ||
| 158 | ;; Hideshow was inspired when I learned about selective display. It was | ||
| 159 | ;; reimplemented to use overlays for 4.0 (see above). WRT older history, | ||
| 160 | ;; entries in the masterfile corresponding to versions 1.x and 2.x have | ||
| 161 | ;; been lost. XEmacs support is reliable as of 4.29. State save and | ||
| 162 | ;; restore was added in 3.5 (not widely distributed), and reliable as of | ||
| 163 | ;; 4.30. Otherwise, the code seems stable. Passes checkdoc as of 4.32. | ||
| 164 | ;; Version 5.x uses new algorithms for block selection and traversal, | ||
| 165 | ;; unbundles state save and restore, and includes more isearch support. | ||
| 102 | 166 | ||
| 103 | ;;; Code: | 167 | ;;; Code: |
| 104 | 168 | ||
| 105 | (require 'easymenu) | 169 | (require 'easymenu) |
| 106 | 170 | ||
| 107 | ;;;---------------------------------------------------------------------------- | 171 | ;;--------------------------------------------------------------------------- |
| 108 | ;;; user-configurable variables | 172 | ;; user-configurable variables |
| 109 | 173 | ||
| 110 | (defgroup hideshow nil | 174 | (defgroup hideshow nil |
| 111 | "Minor mode for hiding and showing program and comment blocks." | 175 | "Minor mode for hiding and showing program and comment blocks." |
| @@ -114,59 +178,18 @@ | |||
| 114 | 178 | ||
| 115 | ;;;###autoload | 179 | ;;;###autoload |
| 116 | (defcustom hs-hide-comments-when-hiding-all t | 180 | (defcustom hs-hide-comments-when-hiding-all t |
| 117 | "Hide the comments too when you do an `hs-hide-all'." | 181 | "*Hide the comments too when you do an `hs-hide-all'." |
| 118 | :type 'boolean | 182 | :type 'boolean |
| 119 | :group 'hideshow) | 183 | :group 'hideshow) |
| 120 | 184 | ||
| 121 | ;;;###autoload | 185 | (defcustom hs-minor-mode-hook nil |
| 122 | (defcustom hs-show-hidden-short-form t | 186 | "*Hook called when hideshow minor mode is activated." |
| 123 | "Leave only the first line visible in a hidden block. | ||
| 124 | If non-nil only the first line is visible when a block is in the | ||
| 125 | hidden state, else both the first line and the last line are shown. | ||
| 126 | A nil value disables `hs-adjust-block-beginning', which see. | ||
| 127 | |||
| 128 | An example of how this works: (in C mode) | ||
| 129 | original: | ||
| 130 | |||
| 131 | /* My function main | ||
| 132 | some more stuff about main | ||
| 133 | */ | ||
| 134 | int | ||
| 135 | main(void) | ||
| 136 | { | ||
| 137 | int x=0; | ||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | |||
| 142 | hidden and `hs-show-hidden-short-form' is nil | ||
| 143 | /* My function main... | ||
| 144 | */ | ||
| 145 | int | ||
| 146 | main(void) | ||
| 147 | {... | ||
| 148 | } | ||
| 149 | |||
| 150 | hidden and `hs-show-hidden-short-form' is t | ||
| 151 | /* My function main... | ||
| 152 | int | ||
| 153 | main(void)... | ||
| 154 | |||
| 155 | For the last case you have to be on the line containing the | ||
| 156 | ellipsis when you do `hs-show-block'." | ||
| 157 | :type 'boolean | ||
| 158 | :group 'hideshow) | ||
| 159 | |||
| 160 | (defcustom hs-minor-mode-hook 'hs-hide-initial-comment-block | ||
| 161 | "Hook called when `hs-minor-mode' is installed. | ||
| 162 | A good value for this would be `hs-hide-initial-comment-block' to | ||
| 163 | hide all the comments at the beginning of the file." | ||
| 164 | :type 'hook | 187 | :type 'hook |
| 165 | :group 'hideshow) | 188 | :group 'hideshow) |
| 166 | 189 | ||
| 167 | (defcustom hs-isearch-open 'block | 190 | (defcustom hs-isearch-open 'block |
| 168 | "What kind of hidden blocks to open when doing `isearch'. | 191 | "*What kind of hidden blocks to open when doing `isearch'. |
| 169 | One of the following values: | 192 | One of the following symbols: |
| 170 | 193 | ||
| 171 | block -- open only blocks | 194 | block -- open only blocks |
| 172 | comment -- open only comments | 195 | comment -- open only comments |
| @@ -175,96 +198,61 @@ One of the following values: | |||
| 175 | 198 | ||
| 176 | This has effect iff `search-invisible' is set to `open'." | 199 | This has effect iff `search-invisible' is set to `open'." |
| 177 | :type '(choice (const :tag "open only blocks" block) | 200 | :type '(choice (const :tag "open only blocks" block) |
| 178 | (const :tag "open only comments" comment) | 201 | (const :tag "open only comments" comment) |
| 179 | (const :tag "open both blocks and comments" t) | 202 | (const :tag "open both blocks and comments" t) |
| 180 | (const :tag "don't open any of them" nil)) | 203 | (const :tag "don't open any of them" nil)) |
| 181 | :group 'hideshow) | 204 | :group 'hideshow) |
| 182 | 205 | ||
| 183 | ;;;###autoload | 206 | ;;;###autoload |
| 184 | (defvar hs-special-modes-alist | 207 | (defvar hs-special-modes-alist |
| 185 | '((c-mode "{" "}" nil nil hs-c-like-adjust-block-beginning) | 208 | '((c-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) |
| 186 | (c++-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) | 209 | (c++-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) |
| 187 | (java-mode "\\(\\(\\([ \t]*\\(\\(abstract\\|final\\|native\\|p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|s\\(tatic\\|ynchronized\\)\\)[ \t\n]+\\)*[.a-zA-Z0-9_:]+[ \t\n]*\\(\\[[ \t\n]*\\][ \t\n]*\\)?\\([a-zA-Z0-9_:]+[ \t\n]*\\)([^)]*)\\([ \n\t]+throws[ \t\n][^{]+\\)?\\)\\|\\([ \t]*static[^{]*\\)\\)[ \t\n]*{\\)" "}" "/[*/]" java-hs-forward-sexp hs-c-like-adjust-block-beginning)) | 210 | (bibtex-mode ("^@\\S(*\\(\\s(\\)" 1)) |
| 188 | ; I tested the java regexp using the following: | 211 | (java-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) |
| 189 | ;(defvar hsj-public) | 212 | ) |
| 190 | ;(defvar hsj-type) | ||
| 191 | ;(defvar hsj-fname) | ||
| 192 | ;(defvar hsj-par) | ||
| 193 | ;(defvar hsj-throws) | ||
| 194 | ;(defvar hsj-static) | ||
| 195 | |||
| 196 | ;(setq hsj-public | ||
| 197 | ; (concat "[ \t]*\\(" | ||
| 198 | ; (regexp-opt '("public" "private" "protected" "abstract" | ||
| 199 | ; "synchronized" "static" "final" "native") 1) | ||
| 200 | ; "[ \t\n]+\\)*")) | ||
| 201 | |||
| 202 | ;(setq hsj-type "[.a-zA-Z0-9_:]+[ \t\n]*\\(\\[[ \t\n]*\\][ \t\n]*\\)?") | ||
| 203 | ;(setq hsj-fname "\\([a-zA-Z0-9_:]+[ \t\n]*\\)") | ||
| 204 | ;(setq hsj-par "([^)]*)") | ||
| 205 | ;(setq hsj-throws "\\([ \n\t]+throws[ \t\n][^{]+\\)?") | ||
| 206 | |||
| 207 | ;(setq hsj-static "[ \t]*static[^{]*") | ||
| 208 | |||
| 209 | |||
| 210 | ;(setq hs-block-start-regexp (concat | ||
| 211 | ; "\\(" | ||
| 212 | ; "\\(" | ||
| 213 | ; "\\(" | ||
| 214 | ; hsj-public | ||
| 215 | ; hsj-type | ||
| 216 | ; hsj-fname | ||
| 217 | ; hsj-par | ||
| 218 | ; hsj-throws | ||
| 219 | ; "\\)" | ||
| 220 | ; "\\|" | ||
| 221 | ; "\\(" | ||
| 222 | ; hsj-static | ||
| 223 | ; "\\)" | ||
| 224 | ; "\\)" | ||
| 225 | ; "[ \t\n]*{" | ||
| 226 | ; "\\)" | ||
| 227 | ; )) | ||
| 228 | |||
| 229 | "*Alist for initializing the hideshow variables for different modes. | 213 | "*Alist for initializing the hideshow variables for different modes. |
| 230 | It has the form | 214 | Each element has the form |
| 231 | (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC). | 215 | (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC). |
| 232 | If present, hideshow will use these values as regexps for start, end | ||
| 233 | and comment-start, respectively. Since Algol-ish languages do not have | ||
| 234 | single-character block delimiters, the function `forward-sexp' used | ||
| 235 | by hideshow doesn't work. In this case, if a similar function is | ||
| 236 | available, you can register it and have hideshow use it instead of | ||
| 237 | `forward-sexp'. See the documentation for `hs-adjust-block-beginning' | ||
| 238 | to see what is the use of ADJUST-BEG-FUNC. | ||
| 239 | 216 | ||
| 240 | If any of those is left nil, hideshow will try to guess some values | 217 | If non-nil, hideshow will use these values as regexps to define blocks |
| 241 | using function `hs-grok-mode-type'. | 218 | and comments, respectively for major mode MODE. |
| 219 | |||
| 220 | START, END and COMMENT-START are regular expressions. A block is | ||
| 221 | defined as text surrounded by START and END. | ||
| 222 | |||
| 223 | As a special case, START may be a list of the form (COMPLEX-START | ||
| 224 | MDATA-SELECTOR), where COMPLEX-START is a regexp w/ multiple parts and | ||
| 225 | MDATA-SELECTOR an integer that specifies which sub-match is the proper | ||
| 226 | place to adjust point, before calling `hs-forward-sexp-func'. For | ||
| 227 | example, see the `hs-special-modes-alist' entry for `bibtex-mode'. | ||
| 242 | 228 | ||
| 243 | Note that the regexps should not contain leading or trailing whitespace.") | 229 | For some major modes, `forward-sexp' does not work properly. In those |
| 230 | cases, FORWARD-SEXP-FUNC specifies another function to use instead. | ||
| 231 | |||
| 232 | See the documentation for `hs-adjust-block-beginning' to see what is the | ||
| 233 | use of ADJUST-BEG-FUNC. | ||
| 234 | |||
| 235 | If any of the elements is left nil or omitted, hideshow tries to guess | ||
| 236 | appropriate values. The regexps should not contain leading or trailing | ||
| 237 | whitespace. Case does not matter.") | ||
| 244 | 238 | ||
| 245 | (defvar hs-hide-hook nil | 239 | (defvar hs-hide-hook nil |
| 246 | "*Hooks called at the end of commands to hide text. | 240 | "*Hook called (with `run-hooks') at the end of commands to hide text. |
| 247 | These commands include `hs-hide-all', `hs-hide-block' and `hs-hide-level'.") | 241 | These commands include `hs-hide-all', `hs-hide-block' and `hs-hide-level'.") |
| 248 | 242 | ||
| 249 | (defvar hs-show-hook nil | 243 | (defvar hs-show-hook nil |
| 250 | "*Hooks called at the end of commands to show text. | 244 | "*Hook called (with `run-hooks') at the end of commands to show text. |
| 251 | These commands include `hs-show-all', `hs-show-block' and `hs-show-region'.") | 245 | These commands include `hs-show-all', `hs-show-block' and `hs-show-region'.") |
| 252 | 246 | ||
| 253 | (defvar hs-minor-mode-prefix "\C-c" | 247 | ;;--------------------------------------------------------------------------- |
| 254 | "*Prefix key to use for hideshow commands in hideshow minor mode.") | 248 | ;; internal variables |
| 255 | |||
| 256 | ;;;---------------------------------------------------------------------------- | ||
| 257 | ;;; internal variables | ||
| 258 | 249 | ||
| 259 | (defvar hs-minor-mode nil | 250 | (defvar hs-minor-mode nil |
| 260 | "Non-nil if using hideshow mode as a minor mode of some other mode. | 251 | "Non-nil if using hideshow mode as a minor mode of some other mode. |
| 261 | Use the command `hs-minor-mode' to toggle this variable.") | 252 | Use the command `hs-minor-mode' to toggle or set this variable.") |
| 262 | 253 | ||
| 263 | (defvar hs-minor-mode-map nil | 254 | (defvar hs-minor-mode-map nil |
| 264 | "Mode map for hideshow minor mode.") | 255 | "Keymap for hideshow minor mode.") |
| 265 | |||
| 266 | ;(defvar hs-menu-bar nil | ||
| 267 | ; "Menu bar for hideshow minor mode (Xemacs only).") | ||
| 268 | 256 | ||
| 269 | (defvar hs-c-start-regexp nil | 257 | (defvar hs-c-start-regexp nil |
| 270 | "Regexp for beginning of comments. | 258 | "Regexp for beginning of comments. |
| @@ -274,6 +262,11 @@ surrounding whitespace is stripped.") | |||
| 274 | (defvar hs-block-start-regexp nil | 262 | (defvar hs-block-start-regexp nil |
| 275 | "Regexp for beginning of block.") | 263 | "Regexp for beginning of block.") |
| 276 | 264 | ||
| 265 | (defvar hs-block-start-mdata-select nil | ||
| 266 | "Element in `hs-block-start-regexp' match data to consider as block start. | ||
| 267 | The internal function `hs-forward-sexp' moves point to the beginning of this | ||
| 268 | element (using `match-beginning') before calling `hs-forward-sexp-func'.") | ||
| 269 | |||
| 277 | (defvar hs-block-end-regexp nil | 270 | (defvar hs-block-end-regexp nil |
| 278 | "Regexp for end of block.") | 271 | "Regexp for end of block.") |
| 279 | 272 | ||
| @@ -287,13 +280,14 @@ function is necessary.") | |||
| 287 | 280 | ||
| 288 | (defvar hs-adjust-block-beginning nil | 281 | (defvar hs-adjust-block-beginning nil |
| 289 | "Function used to tweak the block beginning. | 282 | "Function used to tweak the block beginning. |
| 290 | It has effect only if `hs-show-hidden-short-form' is non-nil. | 283 | The block is hidden from the position returned by this function, |
| 291 | The block it is hidden from the point returned by this function, | 284 | as opposed to hiding it from the position returned when searching |
| 292 | as opposed to hiding it from the point returned when searching | 285 | for `hs-block-start-regexp'. |
| 293 | `hs-block-start-regexp'. In c-like modes, if we wish to also hide the | 286 | |
| 294 | curly braces (if you think they occupy too much space on the screen), | 287 | For example, in c-like modes, if we wish to also hide the curly braces |
| 295 | this function should return the starting point (at the end of line) of | 288 | (if you think they occupy too much space on the screen), this function |
| 296 | the hidden region. | 289 | should return the starting point (at the end of line) of the hidden |
| 290 | region. | ||
| 297 | 291 | ||
| 298 | It is called with a single argument ARG which is the the position in | 292 | It is called with a single argument ARG which is the the position in |
| 299 | buffer after the block beginning. | 293 | buffer after the block beginning. |
| @@ -304,146 +298,157 @@ It should not move the point. | |||
| 304 | 298 | ||
| 305 | See `hs-c-like-adjust-block-beginning' for an example of using this.") | 299 | See `hs-c-like-adjust-block-beginning' for an example of using this.") |
| 306 | 300 | ||
| 307 | ;(defvar hs-emacs-type 'fsf | 301 | (defvar hs-headline nil |
| 308 | ; "Used to support both Emacs and Xemacs.") | 302 | "Text of the line where a hidden block begins, set during isearch. |
| 303 | You can display this in the mode line by adding the symbol `hs-headline' | ||
| 304 | to the variable `mode-line-format'. For example, | ||
| 305 | |||
| 306 | (unless (memq 'hs-headline mode-line-format) | ||
| 307 | (setq mode-line-format | ||
| 308 | (append '(\"-\" hs-headline) mode-line-format))) | ||
| 309 | |||
| 310 | Note that `mode-line-format' is buffer-local.") | ||
| 311 | |||
| 312 | ;;--------------------------------------------------------------------------- | ||
| 313 | ;; system dependency | ||
| 314 | |||
| 315 | ; ;; xemacs compatibility | ||
| 316 | ; (when (string-match "xemacs\\|lucid" emacs-version) | ||
| 317 | ; ;; use pre-packaged compatiblity layer | ||
| 318 | ; (require 'overlay)) | ||
| 319 | ; | ||
| 320 | ; ;; xemacs and emacs-19 compatibility | ||
| 321 | ; (when (or (not (fboundp 'add-to-invisibility-spec)) | ||
| 322 | ; (not (fboundp 'remove-from-invisibility-spec))) | ||
| 323 | ; ;; `buffer-invisibility-spec' mutators snarfed from Emacs 20.3 lisp/subr.el | ||
| 324 | ; (defun add-to-invisibility-spec (arg) | ||
| 325 | ; (cond | ||
| 326 | ; ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t)) | ||
| 327 | ; (setq buffer-invisibility-spec (list arg))) | ||
| 328 | ; (t | ||
| 329 | ; (setq buffer-invisibility-spec | ||
| 330 | ; (cons arg buffer-invisibility-spec))))) | ||
| 331 | ; (defun remove-from-invisibility-spec (arg) | ||
| 332 | ; (if buffer-invisibility-spec | ||
| 333 | ; (setq buffer-invisibility-spec | ||
| 334 | ; (delete arg buffer-invisibility-spec))))) | ||
| 335 | |||
| 336 | ;; hs-match-data | ||
| 337 | (defalias 'hs-match-data 'match-data) | ||
| 338 | |||
| 339 | ;;--------------------------------------------------------------------------- | ||
| 340 | ;; support functions | ||
| 341 | |||
| 342 | (defun hs-discard-overlays (from to) | ||
| 343 | (when (< to from) | ||
| 344 | (setq from (prog1 to (setq to from)))) | ||
| 345 | (mapcar (lambda (ov) | ||
| 346 | (when (overlay-get ov 'hs) | ||
| 347 | (delete-overlay ov))) | ||
| 348 | (overlays-in from to))) | ||
| 349 | |||
| 350 | (defun hs-isearch-show (ov) | ||
| 351 | (setq hs-headline nil) | ||
| 352 | (hs-flag-region (overlay-start ov) (overlay-end ov) nil)) | ||
| 353 | |||
| 354 | (defun hs-isearch-show-temporary (ov hide-p) | ||
| 355 | (setq hs-headline | ||
| 356 | (if hide-p | ||
| 357 | nil | ||
| 358 | (or hs-headline | ||
| 359 | (let ((start (overlay-start ov))) | ||
| 360 | (buffer-substring | ||
| 361 | (save-excursion (goto-char start) | ||
| 362 | (beginning-of-line) | ||
| 363 | (skip-chars-forward " \t") | ||
| 364 | (point)) | ||
| 365 | start))))) | ||
| 366 | (force-mode-line-update) | ||
| 367 | (overlay-put ov 'invisible (and hide-p 'hs))) | ||
| 309 | 368 | ||
| 310 | ;(eval-when-compile | ||
| 311 | ; (if (string-match "xemacs\\|lucid" emacs-version) | ||
| 312 | ; (progn | ||
| 313 | ; (defvar current-menubar nil "") | ||
| 314 | ; (defun set-buffer-menubar (arg1)) | ||
| 315 | ; (defun add-menu (arg1 arg2 arg3))))) | ||
| 316 | |||
| 317 | ;;;---------------------------------------------------------------------------- | ||
| 318 | ;;; support funcs | ||
| 319 | |||
| 320 | ;; snarfed from outline.el; | ||
| 321 | (defun hs-flag-region (from to flag) | 369 | (defun hs-flag-region (from to flag) |
| 322 | "Hide or show lines from FROM to TO, according to FLAG. | 370 | "Hide or show lines from FROM to TO, according to FLAG. |
| 323 | If FLAG is nil then text is shown, while if FLAG is non-nil the text | 371 | If FLAG is nil then text is shown, while if FLAG is non-nil the text is |
| 324 | is hidden. Actually flag is really either `comment' or `block' | 372 | hidden. Actually flag is really either `comment' or `block' depending |
| 325 | depending on what kind of block it is suppose to hide." | 373 | on what kind of block it is suppose to hide." |
| 326 | (save-excursion | ||
| 327 | (goto-char from) | ||
| 328 | (end-of-line) | ||
| 329 | (hs-discard-overlays (point) to 'invisible 'hs) | ||
| 330 | (if flag | ||
| 331 | (let ((overlay (make-overlay (point) to))) | ||
| 332 | ;; Make overlay hidden and intangible. | ||
| 333 | (overlay-put overlay 'invisible 'hs) | ||
| 334 | (overlay-put overlay 'hs t) | ||
| 335 | (when (or (eq hs-isearch-open t) (eq hs-isearch-open flag)) | ||
| 336 | (overlay-put overlay 'isearch-open-invisible | ||
| 337 | 'hs-isearch-open-invisible)) | ||
| 338 | (overlay-put overlay 'intangible t))))) | ||
| 339 | |||
| 340 | ;; This is set as an `isearch-open-invisible' property to hidden | ||
| 341 | ;; overlays. | ||
| 342 | (defun hs-isearch-open-invisible (ov) | ||
| 343 | (save-excursion | 374 | (save-excursion |
| 344 | (goto-char (overlay-start ov)) | 375 | ;; first clear it all out |
| 345 | (hs-show-block))) | 376 | (hs-discard-overlays from to) |
| 346 | 377 | ;; now create overlays if needed | |
| 347 | ;; Remove from the region BEG ... END all overlays | 378 | (when flag |
| 348 | ;; with a PROP property equal to VALUE. | 379 | (let ((overlay (make-overlay from to))) |
| 349 | ;; Overlays with a PROP property different from VALUE are not touched. | 380 | (overlay-put overlay 'invisible 'hs) |
| 350 | (defun hs-discard-overlays (beg end prop value) | 381 | (overlay-put overlay 'intangible t) |
| 351 | (if (< end beg) | 382 | (overlay-put overlay 'hs flag) |
| 352 | (setq beg (prog1 end (setq end beg)))) | 383 | (when (or (eq hs-isearch-open t) (eq hs-isearch-open flag)) |
| 353 | (save-excursion | 384 | (mapcar |
| 354 | (goto-char beg) | 385 | (lambda (pair) |
| 355 | (let ((overlays (overlays-in beg end)) | 386 | (overlay-put overlay (car pair) (cdr pair))) |
| 356 | o) | 387 | '((isearch-open-invisible . hs-isearch-show) |
| 357 | (while overlays | 388 | (isearch-open-invisible-temporary . hs-isearch-show-temporary)))) |
| 358 | (setq o (car overlays)) | 389 | overlay)))) |
| 359 | (if (eq (overlay-get o prop) value) | 390 | |
| 360 | (delete-overlay o)) | 391 | (defun hs-forward-sexp (match-data arg) |
| 361 | (setq overlays (cdr overlays)))))) | 392 | "Adjust point based on MATCH-DATA and call `hs-forward-sexp-func' w/ ARG. |
| 393 | Original match data is restored upon return." | ||
| 394 | (save-match-data | ||
| 395 | (set-match-data match-data) | ||
| 396 | (goto-char (match-beginning hs-block-start-mdata-select)) | ||
| 397 | (funcall hs-forward-sexp-func arg))) | ||
| 398 | |||
| 399 | (defun hs-hide-comment-region (beg end &optional repos-end) | ||
| 400 | "Hide a region from BEG to END, marking it as a comment. | ||
| 401 | Optional arg REPOS-END means reposition at end." | ||
| 402 | (hs-flag-region (progn (goto-char beg) (end-of-line) (point)) | ||
| 403 | (progn (goto-char end) (end-of-line) (point)) | ||
| 404 | 'comment) | ||
| 405 | (goto-char (if repos-end end beg))) | ||
| 362 | 406 | ||
| 363 | (defun hs-hide-block-at-point (&optional end comment-reg) | 407 | (defun hs-hide-block-at-point (&optional end comment-reg) |
| 364 | "Hide block iff on block beginning. | 408 | "Hide block iff on block beginning. |
| 365 | Optional arg END means reposition at end. | 409 | Optional arg END means reposition at end. |
| 366 | Optional arg COMMENT-REG is a list of the form (BEGIN . END) and | 410 | Optional arg COMMENT-REG is a list of the form (BEGIN END) and |
| 367 | specifies the limits of the comment, or nil if the block is not | 411 | specifies the limits of the comment, or nil if the block is not |
| 368 | a comment." | 412 | a comment. |
| 369 | (if comment-reg | 413 | |
| 370 | (progn | 414 | The block beginning is adjusted by `hs-adjust-block-beginning' |
| 371 | ;; goto the end of line at the end of the comment | 415 | and then further adjusted to be at the end of the line." |
| 372 | (goto-char (nth 1 comment-reg)) | ||
| 373 | (unless hs-show-hidden-short-form (forward-line -1)) | ||
| 374 | (end-of-line) | ||
| 375 | (hs-flag-region (car comment-reg) (point) 'comment) | ||
| 376 | (goto-char (if end (nth 1 comment-reg) (car comment-reg)))) | ||
| 377 | (if (looking-at hs-block-start-regexp) | ||
| 378 | (let* ((p ;; p is the point at the end of the block beginning | ||
| 379 | (if (and hs-show-hidden-short-form | ||
| 380 | hs-adjust-block-beginning) | ||
| 381 | ;; we need to adjust the block beginning | ||
| 382 | (funcall hs-adjust-block-beginning (match-end 0)) | ||
| 383 | (match-end 0))) | ||
| 384 | ;; q is the point at the end of the block | ||
| 385 | (q (progn (funcall hs-forward-sexp-func 1) (point)))) | ||
| 386 | ;; position the point so we can call `hs-flag-region' | ||
| 387 | (unless hs-show-hidden-short-form (forward-line -1)) | ||
| 388 | (end-of-line) | ||
| 389 | (if (and (< p (point)) (> (count-lines p q) | ||
| 390 | (if hs-show-hidden-short-form 1 2))) | ||
| 391 | (hs-flag-region p (point) 'block)) | ||
| 392 | (goto-char (if end q p)))))) | ||
| 393 | |||
| 394 | (defun hs-show-block-at-point (&optional end comment-reg) | ||
| 395 | "Show block iff on block beginning. | ||
| 396 | Optional arg END means reposition at end. | ||
| 397 | Optional arg COMMENT-REG is a list of the forme (BEGIN . END) and | ||
| 398 | specifies the limits of the comment. It should be nil when hiding | ||
| 399 | a block." | ||
| 400 | (if comment-reg | 416 | (if comment-reg |
| 401 | (when (car comment-reg) | 417 | (hs-hide-comment-region (car comment-reg) (cadr comment-reg) end) |
| 402 | (hs-flag-region (car comment-reg) (nth 1 comment-reg) nil) | ||
| 403 | (goto-char (if end (nth 1 comment-reg) (car comment-reg)))) | ||
| 404 | (if (looking-at hs-block-start-regexp) | 418 | (if (looking-at hs-block-start-regexp) |
| 405 | (let* ((p (point)) | 419 | (let* ((mdata (hs-match-data t)) |
| 406 | (q | 420 | (pure-p (match-end 0)) |
| 407 | (condition-case error ; probably unbalanced paren | 421 | (p |
| 408 | (progn | 422 | ;; `p' is the point at the end of the block beginning, |
| 409 | (funcall hs-forward-sexp-func 1) | 423 | ;; which may need to be adjusted |
| 410 | (point)) | 424 | (save-excursion |
| 411 | (error | 425 | (goto-char (funcall (or hs-adjust-block-beginning |
| 412 | ;; try to get out of rat's nest and expose the whole func | 426 | 'identity) |
| 413 | (if (/= (current-column) 0) (beginning-of-defun)) | 427 | pure-p)) |
| 414 | (setq p (point)) | 428 | ;; whatever the adjustment, we move to eol |
| 415 | (re-search-forward (concat "^" hs-block-start-regexp) | 429 | (end-of-line) |
| 416 | (point-max) t 2) | 430 | (point))) |
| 417 | (point))))) | 431 | (q |
| 418 | (hs-flag-region p q nil) | 432 | ;; `q' is the point at the end of the block |
| 419 | (goto-char (if end (1+ (point)) p)))))) | 433 | (progn (hs-forward-sexp mdata 1) |
| 434 | (end-of-line) | ||
| 435 | (point)))) | ||
| 436 | (if (and (< p (point)) (> (count-lines p q) 1)) | ||
| 437 | (overlay-put (hs-flag-region p q 'block) | ||
| 438 | 'hs-ofs | ||
| 439 | (- pure-p p))) | ||
| 440 | (goto-char (if end q (min p pure-p))))))) | ||
| 420 | 441 | ||
| 421 | (defun hs-safety-is-job-n () | 442 | (defun hs-safety-is-job-n () |
| 422 | "Warn if `buffer-invisibility-spec' does not contain hs." | 443 | "Warn if `buffer-invisibility-spec' does not contain symbol `hs'." |
| 423 | (if (or buffer-invisibility-spec (assq 'hs buffer-invisibility-spec) ) | 444 | (unless (and (listp buffer-invisibility-spec) |
| 424 | nil | 445 | (assq 'hs buffer-invisibility-spec)) |
| 425 | (message "Warning: `buffer-invisibility-spec' does not contain hs!!") | 446 | (message "Warning: `buffer-invisibility-spec' does not contain hs!!") |
| 426 | (sit-for 2))) | 447 | (sit-for 2))) |
| 427 | 448 | ||
| 428 | (defun hs-hide-initial-comment-block () | ||
| 429 | (interactive) | ||
| 430 | "Hide the first block of comments in a file. | ||
| 431 | This is useful when a part of `hs-minor-mode-hook', especially with | ||
| 432 | huge header-comment RCS logs." | ||
| 433 | (let ((p (point)) | ||
| 434 | c-reg) | ||
| 435 | (goto-char (point-min)) | ||
| 436 | (skip-chars-forward " \t\n^L") | ||
| 437 | (setq c-reg (hs-inside-comment-p)) | ||
| 438 | ;; see if we have enough comment lines to hide | ||
| 439 | (if (and c-reg (> (count-lines (car c-reg) (nth 1 c-reg)) | ||
| 440 | (if hs-show-hidden-short-form 1 2))) | ||
| 441 | (hs-hide-block) | ||
| 442 | (goto-char p)))) | ||
| 443 | |||
| 444 | (defun hs-inside-comment-p () | 449 | (defun hs-inside-comment-p () |
| 445 | "Return non-nil if point is inside a comment, otherwise nil. | 450 | "Return non-nil if point is inside a comment, otherwise nil. |
| 446 | Actually, returns a list containing the buffer position of the start | 451 | Actually, return a list containing the buffer position of the start |
| 447 | and the end of the comment. A comment block can be hidden only if on | 452 | and the end of the comment. A comment block can be hidden only if on |
| 448 | its starting line there is only whitespace preceding the actual comment | 453 | its starting line there is only whitespace preceding the actual comment |
| 449 | beginning. If we are inside of a comment but this condition is not met, | 454 | beginning. If we are inside of a comment but this condition is not met, |
| @@ -455,140 +460,120 @@ as cdr." | |||
| 455 | ;; forward and backward as long as we have comments | 460 | ;; forward and backward as long as we have comments |
| 456 | (let ((q (point))) | 461 | (let ((q (point))) |
| 457 | (when (or (looking-at hs-c-start-regexp) | 462 | (when (or (looking-at hs-c-start-regexp) |
| 458 | (re-search-backward hs-c-start-regexp (point-min) t)) | 463 | (re-search-backward hs-c-start-regexp (point-min) t)) |
| 459 | (forward-comment (- (buffer-size))) | 464 | (forward-comment (- (buffer-size))) |
| 460 | (skip-chars-forward " \t\n") | 465 | (skip-chars-forward " \t\n\f") |
| 461 | (let ((p (point)) | 466 | (let ((p (point)) |
| 462 | (not-hidable nil)) | 467 | (not-hidable nil)) |
| 463 | (beginning-of-line) | 468 | (beginning-of-line) |
| 464 | (unless (looking-at (concat "[ \t]*" hs-c-start-regexp)) | 469 | (unless (looking-at (concat "[ \t]*" hs-c-start-regexp)) |
| 465 | ;; we are in this situation: (example) | 470 | ;; we are in this situation: (example) |
| 466 | ;; (defun bar () | 471 | ;; (defun bar () |
| 467 | ;; (foo) | 472 | ;; (foo) |
| 468 | ;; ) ; comment | 473 | ;; ) ; comment |
| 469 | ;; ^ | 474 | ;; ^ |
| 470 | ;; the point was here before doing (beginning-of-line) | 475 | ;; the point was here before doing (beginning-of-line) |
| 471 | ;; here we should advance till the next comment which | 476 | ;; here we should advance till the next comment which |
| 472 | ;; eventually has only white spaces preceding it on the same | 477 | ;; eventually has only white spaces preceding it on the same |
| 473 | ;; line | 478 | ;; line |
| 474 | (goto-char p) | 479 | (goto-char p) |
| 475 | (forward-comment 1) | 480 | (forward-comment 1) |
| 476 | (skip-chars-forward " \t\n") | 481 | (skip-chars-forward " \t\n\f") |
| 477 | (setq p (point)) | 482 | (setq p (point)) |
| 478 | (while (and (< (point) q) | 483 | (while (and (< (point) q) |
| 479 | (> (point) p) | 484 | (> (point) p) |
| 480 | (not (looking-at hs-c-start-regexp))) | 485 | (not (looking-at hs-c-start-regexp))) |
| 481 | (setq p (point)) ;; use this to avoid an infinit cycle. | 486 | (setq p (point));; use this to avoid an infinite cycle |
| 482 | (forward-comment 1) | 487 | (forward-comment 1) |
| 483 | (skip-chars-forward " \t\n")) | 488 | (skip-chars-forward " \t\n\f")) |
| 484 | (if (or (not (looking-at hs-c-start-regexp)) | 489 | (if (or (not (looking-at hs-c-start-regexp)) |
| 485 | (> (point) q)) | 490 | (> (point) q)) |
| 486 | ;; we cannot hide this comment block | 491 | ;; we cannot hide this comment block |
| 487 | (setq not-hidable t))) | 492 | (setq not-hidable t))) |
| 488 | ;; goto the end of the comment | 493 | ;; goto the end of the comment |
| 489 | (forward-comment (buffer-size)) | 494 | (forward-comment (buffer-size)) |
| 490 | (skip-chars-backward " \t\n") | 495 | (skip-chars-backward " \t\n\f") |
| 491 | (end-of-line) | 496 | (end-of-line) |
| 492 | (if (>= (point) q) | 497 | (if (>= (point) q) |
| 493 | (list (if not-hidable nil p) (point)))))))) | 498 | (list (if not-hidable nil p) (point)))))))) |
| 494 | 499 | ||
| 495 | (defun hs-grok-mode-type () | 500 | (defun hs-grok-mode-type () |
| 496 | "Set up hideshow variables for new buffers. | 501 | "Set up hideshow variables for new buffers. |
| 497 | If `hs-special-modes-alist' has information associated with the | 502 | If `hs-special-modes-alist' has information associated with the |
| 498 | current buffer's major mode, use that. | 503 | current buffer's major mode, use that. |
| 499 | Otherwise, guess start, end and comment-start regexps; forward-sexp | 504 | Otherwise, guess start, end and `comment-start' regexps; `forward-sexp' |
| 500 | function; and adjust-block-beginning function." | 505 | function; and adjust-block-beginning function." |
| 501 | (if (and (boundp 'comment-start) | 506 | (if (and (boundp 'comment-start) |
| 502 | (boundp 'comment-end) | 507 | (boundp 'comment-end) |
| 503 | comment-start comment-end) | 508 | comment-start comment-end) |
| 504 | (let ((lookup (assoc major-mode hs-special-modes-alist))) | 509 | (let* ((lookup (assoc major-mode hs-special-modes-alist)) |
| 505 | (setq hs-block-start-regexp (or (nth 1 lookup) "\\s\(") | 510 | (start-elem (or (nth 1 lookup) "\\s("))) |
| 506 | hs-block-end-regexp (or (nth 2 lookup) "\\s\)") | 511 | (if (listp start-elem) |
| 507 | hs-c-start-regexp (or (nth 3 lookup) | 512 | ;; handle (START-REGEXP MDATA-SELECT) |
| 508 | (let ((c-start-regexp | 513 | (setq hs-block-start-regexp (car start-elem) |
| 509 | (regexp-quote comment-start))) | 514 | hs-block-start-mdata-select (cadr start-elem)) |
| 510 | (if (string-match " +$" c-start-regexp) | 515 | ;; backwards compatibility: handle simple START-REGEXP |
| 511 | (substring c-start-regexp 0 (1- (match-end 0))) | 516 | (setq hs-block-start-regexp start-elem |
| 512 | c-start-regexp))) | 517 | hs-block-start-mdata-select 0)) |
| 513 | hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp) | 518 | (setq hs-block-end-regexp (or (nth 2 lookup) "\\s)") |
| 514 | hs-adjust-block-beginning (nth 5 lookup))) | 519 | hs-c-start-regexp (or (nth 3 lookup) |
| 515 | (error "%s Mode doesn't support Hideshow Mode" mode-name))) | 520 | (let ((c-start-regexp |
| 521 | (regexp-quote comment-start))) | ||
| 522 | (if (string-match " +$" c-start-regexp) | ||
| 523 | (substring c-start-regexp | ||
| 524 | 0 (1- (match-end 0))) | ||
| 525 | c-start-regexp))) | ||
| 526 | hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp) | ||
| 527 | hs-adjust-block-beginning (nth 5 lookup))) | ||
| 528 | (progn | ||
| 529 | (setq hs-minor-mode nil) | ||
| 530 | (error "%s Mode doesn't support Hideshow Minor Mode" mode-name)))) | ||
| 516 | 531 | ||
| 517 | (defun hs-find-block-beginning () | 532 | (defun hs-find-block-beginning () |
| 518 | "Reposition point at block-start. | 533 | "Reposition point at block-start. |
| 519 | Return point, or nil if top-level." | 534 | Return point, or nil if top-level." |
| 520 | (let (done | 535 | (let ((done nil) |
| 521 | (try-again t) | 536 | (here (point))) |
| 522 | (here (point)) | 537 | ;; look if current line is block start |
| 523 | (both-regexps (concat "\\(" hs-block-start-regexp "\\)\\|\\(" | 538 | (if (looking-at hs-block-start-regexp) |
| 524 | hs-block-end-regexp "\\)")) | 539 | (point) |
| 525 | (buf-size (buffer-size))) | 540 | ;; look backward for the start of a block that contains the cursor |
| 526 | (beginning-of-line) | 541 | (while (and (re-search-backward hs-block-start-regexp nil t) |
| 527 | ;; A block beginning can span on multiple lines, if the point | 542 | (not (setq done |
| 528 | ;; is on one of those lines, trying a regexp search from | 543 | (< here (save-excursion |
| 529 | ;; that point would fail to find the block beginning, so we look | 544 | (hs-forward-sexp (hs-match-data t) 1) |
| 530 | ;; backwards for the block beginning, or a block end. | 545 | (point))))))) |
| 531 | (while try-again | 546 | (if done |
| 532 | (setq try-again nil) | 547 | (point) |
| 533 | (if (and (re-search-backward both-regexps (point-min) t) | 548 | (goto-char here) |
| 534 | (match-beginning 1)) ; found a block beginning | 549 | nil)))) |
| 535 | (if (save-match-data (hs-inside-comment-p)) | ||
| 536 | ;;but it was inside a comment, so we have to look for | ||
| 537 | ;;it again | ||
| 538 | (setq try-again t) | ||
| 539 | ;; that's what we were looking for | ||
| 540 | (setq done (match-beginning 0))) | ||
| 541 | ;; we found a block end, or we reached the beginning of the | ||
| 542 | ;; buffer look to see if we were on a block beginning when we | ||
| 543 | ;; started | ||
| 544 | (if (and | ||
| 545 | (re-search-forward hs-block-start-regexp (point-max) t) | ||
| 546 | (or | ||
| 547 | (and (>= here (match-beginning 0)) (< here (match-end 0))) | ||
| 548 | (and hs-show-hidden-short-form hs-adjust-block-beginning | ||
| 549 | (save-match-data | ||
| 550 | (= 1 (count-lines | ||
| 551 | (funcall hs-adjust-block-beginning | ||
| 552 | (match-end 0)) here)))))) | ||
| 553 | (setq done (match-beginning 0))))) | ||
| 554 | (goto-char here) | ||
| 555 | (while (and (not done) | ||
| 556 | ;; This had problems because the regexp can match something | ||
| 557 | ;; inside of a comment! | ||
| 558 | ;; Since inside a comment we can have incomplete sexps | ||
| 559 | ;; this would have signaled an error. | ||
| 560 | (or (forward-comment (- buf-size)) t); `or' is a hack to | ||
| 561 | ; make it return t | ||
| 562 | (re-search-backward both-regexps (point-min) t)) | ||
| 563 | (if (match-beginning 1) ; start of start-regexp | ||
| 564 | (setq done (match-beginning 0)) | ||
| 565 | (goto-char (match-end 0)) ; end of end-regexp | ||
| 566 | (funcall hs-forward-sexp-func -1))) | ||
| 567 | (goto-char (or done here)) | ||
| 568 | done)) | ||
| 569 | 550 | ||
| 570 | (defun hs-hide-level-recursive (arg minp maxp) | 551 | (defun hs-hide-level-recursive (arg minp maxp) |
| 571 | "Hide blocks ARG levels below this block recursively." | 552 | "Recursively hide blocks ARG levels below point in region (MINP MAXP)." |
| 572 | (when (hs-find-block-beginning) | 553 | (when (hs-find-block-beginning) |
| 573 | (setq minp (1+ (point))) | 554 | (setq minp (1+ (point))) |
| 574 | (forward-sexp) | 555 | (funcall hs-forward-sexp-func 1) |
| 575 | (setq maxp (1- (point)))) | 556 | (setq maxp (1- (point)))) |
| 576 | (hs-flag-region minp maxp ?\n) ; eliminate weirdness | 557 | (hs-flag-region minp maxp nil) ; eliminate weirdness |
| 577 | (goto-char minp) | 558 | (goto-char minp) |
| 578 | (while (progn | 559 | (while (progn |
| 579 | (forward-comment (buffer-size)) | 560 | (forward-comment (buffer-size)) |
| 580 | (re-search-forward hs-block-start-regexp maxp t)) | 561 | (and (< (point) maxp) |
| 562 | (re-search-forward hs-block-start-regexp maxp t))) | ||
| 581 | (if (> arg 1) | 563 | (if (> arg 1) |
| 582 | (hs-hide-level-recursive (1- arg) minp maxp) | 564 | (hs-hide-level-recursive (1- arg) minp maxp) |
| 583 | (goto-char (match-beginning 0)) | 565 | (goto-char (match-beginning hs-block-start-mdata-select)) |
| 584 | (hs-hide-block-at-point t))) | 566 | (hs-hide-block-at-point t))) |
| 585 | (hs-safety-is-job-n) | 567 | (hs-safety-is-job-n) |
| 586 | (goto-char maxp)) | 568 | (goto-char maxp)) |
| 587 | 569 | ||
| 588 | (defmacro hs-life-goes-on (&rest body) | 570 | (defmacro hs-life-goes-on (&rest body) |
| 589 | "Execute optional BODY iff variable `hs-minor-mode' is non-nil." | 571 | "Evaluate BODY forms iff variable `hs-minor-mode' is non-nil. |
| 590 | `(let ((inhibit-point-motion-hooks t)) | 572 | In the dynamic context of this macro, `inhibit-point-motion-hooks' |
| 591 | (when hs-minor-mode | 573 | and `case-fold-search' are both t." |
| 574 | `(when hs-minor-mode | ||
| 575 | (let ((inhibit-point-motion-hooks t) | ||
| 576 | (case-fold-search t)) | ||
| 592 | ,@body))) | 577 | ,@body))) |
| 593 | 578 | ||
| 594 | (put 'hs-life-goes-on 'edebug-form-spec '(&rest form)) | 579 | (put 'hs-life-goes-on 'edebug-form-spec '(&rest form)) |
| @@ -598,51 +583,39 @@ Return point, or nil if top-level." | |||
| 598 | (save-excursion | 583 | (save-excursion |
| 599 | (let ((c-reg (hs-inside-comment-p))) | 584 | (let ((c-reg (hs-inside-comment-p))) |
| 600 | (if (and c-reg (nth 0 c-reg)) | 585 | (if (and c-reg (nth 0 c-reg)) |
| 601 | ;; point is inside a comment, and that comment is hidable | 586 | ;; point is inside a comment, and that comment is hidable |
| 602 | (goto-char (nth 0 c-reg)) | 587 | (goto-char (nth 0 c-reg)) |
| 603 | (if (and (not c-reg) (hs-find-block-beginning) | 588 | (if (and (not c-reg) |
| 604 | (looking-at hs-block-start-regexp)) | 589 | (hs-find-block-beginning) |
| 605 | ;; point is inside a block | 590 | (looking-at hs-block-start-regexp)) |
| 606 | (goto-char (match-end 0))))) | 591 | ;; point is inside a block |
| 592 | (goto-char (match-end 0))))) | ||
| 607 | (end-of-line) | 593 | (end-of-line) |
| 608 | (let ((overlays (overlays-at (point))) | 594 | (let ((overlays (overlays-at (point))) |
| 609 | (found nil)) | 595 | (found nil)) |
| 610 | (while (and (not found) (overlayp (car overlays))) | 596 | (while (and (not found) (overlayp (car overlays))) |
| 611 | (setq found (overlay-get (car overlays) 'hs) | 597 | (setq found (overlay-get (car overlays) 'hs) |
| 612 | overlays (cdr overlays))) | 598 | overlays (cdr overlays))) |
| 613 | found))) | 599 | found))) |
| 614 | 600 | ||
| 615 | (defun java-hs-forward-sexp (arg) | 601 | (defun hs-c-like-adjust-block-beginning (initial) |
| 616 | "Function used by `hs-minor-mode' for `forward-sexp' in Java mode." | 602 | "Adjust INITIAL, the buffer position after `hs-block-start-regexp'. |
| 617 | (if (< arg 0) | 603 | Actually, point is never moved; a new position is returned that is |
| 618 | (backward-sexp 1) | 604 | the end of the C-function header. This adjustment function is meant |
| 619 | (if (looking-at hs-block-start-regexp) | 605 | to be assigned to `hs-adjust-block-beginning' for C-like modes." |
| 620 | (progn | ||
| 621 | (goto-char (match-end 0)) | ||
| 622 | (forward-char -1) | ||
| 623 | (forward-sexp 1)) | ||
| 624 | (forward-sexp 1)))) | ||
| 625 | |||
| 626 | (defun hs-c-like-adjust-block-beginning (arg) | ||
| 627 | "Function to be assigned to `hs-adjust-block-beginning' for C-like modes. | ||
| 628 | Arg is a position in buffer just after {. This goes back to the end of | ||
| 629 | the function header. The purpose is to save some space on the screen | ||
| 630 | when displaying hidden blocks." | ||
| 631 | (save-excursion | 606 | (save-excursion |
| 632 | (goto-char arg) | 607 | (goto-char (1- initial)) |
| 633 | (forward-char -1) | ||
| 634 | (forward-comment (- (buffer-size))) | 608 | (forward-comment (- (buffer-size))) |
| 635 | (point))) | 609 | (point))) |
| 636 | 610 | ||
| 637 | ;;;---------------------------------------------------------------------------- | 611 | ;;--------------------------------------------------------------------------- |
| 638 | ;;; commands | 612 | ;; commands |
| 639 | 613 | ||
| 640 | ;;;###autoload | ||
| 641 | (defun hs-hide-all () | 614 | (defun hs-hide-all () |
| 642 | "Hide all top-level blocks, displaying only first and last lines. | 615 | "Hide all top level blocks, displaying only first and last lines. |
| 643 | Move point to the beginning of the line, and it run the normal hook | 616 | Move point to the beginning of the line, and run the normal hook |
| 644 | `hs-hide-hook'. See documentation for `run-hooks'. | 617 | `hs-hide-hook'. See documentation for `run-hooks'. |
| 645 | If `hs-hide-comments-when-hiding-all' is t, also hide the comments." | 618 | If `hs-hide-comments-when-hiding-all' is non-nil, also hide the comments." |
| 646 | (interactive) | 619 | (interactive) |
| 647 | (hs-life-goes-on | 620 | (hs-life-goes-on |
| 648 | (message "Hiding all blocks ...") | 621 | (message "Hiding all blocks ...") |
| @@ -650,46 +623,44 @@ If `hs-hide-comments-when-hiding-all' is t, also hide the comments." | |||
| 650 | (hs-flag-region (point-min) (point-max) nil) ; eliminate weirdness | 623 | (hs-flag-region (point-min) (point-max) nil) ; eliminate weirdness |
| 651 | (goto-char (point-min)) | 624 | (goto-char (point-min)) |
| 652 | (if hs-hide-comments-when-hiding-all | 625 | (if hs-hide-comments-when-hiding-all |
| 653 | (let (c-reg | 626 | (let ((c-reg nil) |
| 654 | (count 0) | 627 | (count 0) |
| 655 | (block-and-comment-re ;; this should match | 628 | (block-and-comment-re |
| 656 | (concat "\\(^" ;; the block beginning and comment start | 629 | (concat "\\(" |
| 657 | hs-block-start-regexp | 630 | hs-block-start-regexp |
| 658 | "\\)\\|\\(" hs-c-start-regexp "\\)"))) | 631 | "\\)\\|\\(" |
| 659 | (while (re-search-forward block-and-comment-re (point-max) t) | 632 | hs-c-start-regexp |
| 660 | (if (match-beginning 1) ;; we have found a block beginning | 633 | "\\)"))) |
| 661 | (progn | 634 | (while (re-search-forward block-and-comment-re (point-max) t) |
| 662 | (goto-char (match-beginning 1)) | 635 | (if (match-beginning 1) ;; we have found a block beginning |
| 663 | (hs-hide-block-at-point t) | 636 | (progn |
| 664 | (message "Hiding ... %d" (setq count (1+ count)))) | 637 | (goto-char (match-beginning 1)) |
| 665 | ;;found a comment | 638 | (hs-hide-block-at-point t) |
| 666 | (setq c-reg (hs-inside-comment-p)) | 639 | (message "Hiding ... %d" (setq count (1+ count)))) |
| 667 | (if (and c-reg (car c-reg)) | 640 | ;;found a comment |
| 668 | (if (> (count-lines (car c-reg) (nth 1 c-reg)) | 641 | (setq c-reg (hs-inside-comment-p)) |
| 669 | (if hs-show-hidden-short-form 1 2)) | 642 | (if (and c-reg (car c-reg)) |
| 670 | (progn | 643 | (if (> (count-lines (car c-reg) (nth 1 c-reg)) 1) |
| 671 | (hs-hide-block-at-point t c-reg) | 644 | (progn |
| 672 | (message "Hiding ... %d" (setq count (1+ count)))) | 645 | (hs-hide-block-at-point t c-reg) |
| 673 | (goto-char (nth 1 c-reg))))))) | 646 | (message "Hiding ... %d" (setq count (1+ count)))) |
| 647 | (goto-char (nth 1 c-reg))))))) | ||
| 674 | (let ((count 0) | 648 | (let ((count 0) |
| 675 | (top-level-re (concat "^" hs-block-start-regexp)) | 649 | (buf-size (buffer-size))) |
| 676 | (buf-size (buffer-size))) | 650 | (while |
| 677 | (while | 651 | (progn |
| 678 | (progn | 652 | (forward-comment buf-size) |
| 679 | (forward-comment buf-size) | 653 | (re-search-forward hs-block-start-regexp (point-max) t)) |
| 680 | (re-search-forward top-level-re (point-max) t)) | 654 | (goto-char (match-beginning 0)) |
| 681 | (goto-char (match-beginning 0)) | 655 | (hs-hide-block-at-point t) |
| 682 | (hs-hide-block-at-point t) | 656 | (message "Hiding ... %d" (setq count (1+ count)))))) |
| 683 | (message "Hiding ... %d" (setq count (1+ count)))))) | ||
| 684 | (hs-safety-is-job-n)) | 657 | (hs-safety-is-job-n)) |
| 685 | (beginning-of-line) | 658 | (beginning-of-line) |
| 686 | (message "Hiding all blocks ... done") | 659 | (message "Hiding all blocks ... done") |
| 687 | (run-hooks 'hs-hide-hook))) | 660 | (run-hooks 'hs-hide-hook))) |
| 688 | 661 | ||
| 689 | (defun hs-show-all () | 662 | (defun hs-show-all () |
| 690 | "Show all top-level blocks. | 663 | "Show everything then run `hs-show-hook'. See `run-hooks'." |
| 691 | Point is unchanged; run the normal hook `hs-show-hook'. | ||
| 692 | See documentation for `run-hooks'." | ||
| 693 | (interactive) | 664 | (interactive) |
| 694 | (hs-life-goes-on | 665 | (hs-life-goes-on |
| 695 | (message "Showing all blocks ...") | 666 | (message "Showing all blocks ...") |
| @@ -698,9 +669,7 @@ See documentation for `run-hooks'." | |||
| 698 | (run-hooks 'hs-show-hook))) | 669 | (run-hooks 'hs-show-hook))) |
| 699 | 670 | ||
| 700 | (defun hs-hide-block (&optional end) | 671 | (defun hs-hide-block (&optional end) |
| 701 | "Select a block and hide it. | 672 | "Select a block and hide it. With prefix arg, reposition at END. |
| 702 | With prefix arg, reposition at end. Block is defined as a sexp for | ||
| 703 | Lispish modes, mode-specific otherwise. Comments are blocks, too. | ||
| 704 | Upon completion, point is repositioned and the normal hook | 673 | Upon completion, point is repositioned and the normal hook |
| 705 | `hs-hide-hook' is run. See documentation for `run-hooks'." | 674 | `hs-hide-hook' is run. See documentation for `run-hooks'." |
| 706 | (interactive "P") | 675 | (interactive "P") |
| @@ -708,36 +677,60 @@ Upon completion, point is repositioned and the normal hook | |||
| 708 | (let ((c-reg (hs-inside-comment-p))) | 677 | (let ((c-reg (hs-inside-comment-p))) |
| 709 | (cond | 678 | (cond |
| 710 | ((and c-reg (or (null (nth 0 c-reg)) | 679 | ((and c-reg (or (null (nth 0 c-reg)) |
| 711 | (<= (count-lines (car c-reg) (nth 1 c-reg)) | 680 | (<= (count-lines (car c-reg) (nth 1 c-reg)) 1))) |
| 712 | (if hs-show-hidden-short-form 1 2)))) | 681 | (message "(not enough comment lines to hide)")) |
| 713 | (message "Not enough comment lines to hide!")) | 682 | ((or c-reg |
| 714 | ((or c-reg (looking-at hs-block-start-regexp) | 683 | (looking-at hs-block-start-regexp) |
| 715 | (hs-find-block-beginning)) | 684 | (hs-find-block-beginning)) |
| 716 | (hs-hide-block-at-point end c-reg) | 685 | (hs-hide-block-at-point end c-reg) |
| 717 | (hs-safety-is-job-n) | 686 | (hs-safety-is-job-n) |
| 718 | (run-hooks 'hs-hide-hook)))))) | 687 | (run-hooks 'hs-hide-hook)))))) |
| 719 | 688 | ||
| 720 | (defun hs-show-block (&optional end) | 689 | (defun hs-show-block (&optional end) |
| 721 | "Select a block and show it. | 690 | "Select a block and show it. |
| 722 | With prefix arg, reposition at end. Upon completion, point is | 691 | With prefix arg, reposition at END. Upon completion, point is |
| 723 | repositioned and the normal hook `hs-show-hook' is run. | 692 | repositioned and the normal hook `hs-show-hook' is run. |
| 724 | See documentation for `hs-hide-block' and `run-hooks'." | 693 | See documentation for functions `hs-hide-block' and `run-hooks'." |
| 725 | (interactive "P") | 694 | (interactive "P") |
| 726 | (hs-life-goes-on | 695 | (hs-life-goes-on |
| 727 | (let ((c-reg (hs-inside-comment-p))) | 696 | (or |
| 728 | (if (or c-reg | 697 | ;; first see if we have something at the end of the line |
| 729 | (looking-at hs-block-start-regexp) | 698 | (catch 'eol-begins-hidden-region-p |
| 730 | (hs-find-block-beginning)) | 699 | (let ((here (point))) |
| 731 | (progn | 700 | (mapcar (lambda (ov) |
| 732 | (hs-show-block-at-point end c-reg) | 701 | (when (overlay-get ov 'hs) |
| 733 | (hs-safety-is-job-n) | 702 | (goto-char |
| 734 | (run-hooks 'hs-show-hook)))))) | 703 | (cond |
| 704 | (end (overlay-end ov)) | ||
| 705 | ((eq 'comment (overlay-get ov 'hs)) here) | ||
| 706 | (t (+ (overlay-start ov) (overlay-get ov 'hs-ofs))))) | ||
| 707 | (delete-overlay ov) | ||
| 708 | (throw 'eol-begins-hidden-region-p t))) | ||
| 709 | (save-excursion (end-of-line) (overlays-at (point)))) | ||
| 710 | nil)) | ||
| 711 | ;; not immediately obvious, look for a suitable block | ||
| 712 | (let ((c-reg (hs-inside-comment-p)) | ||
| 713 | p q) | ||
| 714 | (cond (c-reg | ||
| 715 | (when (car c-reg) | ||
| 716 | (setq p (car c-reg) | ||
| 717 | q (cadr c-reg)))) | ||
| 718 | ((and (hs-find-block-beginning) | ||
| 719 | (looking-at hs-block-start-regexp)) ; fresh match-data, ugh | ||
| 720 | (setq p (point) | ||
| 721 | q (progn (hs-forward-sexp (hs-match-data t) 1) (point))))) | ||
| 722 | (when (and p q) | ||
| 723 | (hs-flag-region p q nil) | ||
| 724 | (goto-char (if end q (1+ p))))) | ||
| 725 | (hs-safety-is-job-n) | ||
| 726 | (run-hooks 'hs-show-hook)))) | ||
| 735 | 727 | ||
| 736 | (defun hs-show-region (beg end) | 728 | (defun hs-show-region (beg end) |
| 737 | "Show all lines from BEG to END, without doing any block analysis. | 729 | "Show all lines from BEG to END, without doing any block analysis. |
| 738 | Note: `hs-show-region' is intended for use when `hs-show-block' signals | 730 | Note: `hs-show-region' is intended for use when `hs-show-block' signals |
| 739 | \"unbalanced parentheses\" and so is an emergency measure only. You may | 731 | \"unbalanced parentheses\" and so is an emergency measure only. You may |
| 740 | become very confused if you use this command indiscriminately." | 732 | become very confused if you use this command indiscriminately. |
| 733 | The hook `hs-show-hook' is run; see `run-hooks'." | ||
| 741 | (interactive "r") | 734 | (interactive "r") |
| 742 | (hs-life-goes-on | 735 | (hs-life-goes-on |
| 743 | (hs-flag-region beg end nil) | 736 | (hs-flag-region beg end nil) |
| @@ -745,7 +738,8 @@ become very confused if you use this command indiscriminately." | |||
| 745 | (run-hooks 'hs-show-hook))) | 738 | (run-hooks 'hs-show-hook))) |
| 746 | 739 | ||
| 747 | (defun hs-hide-level (arg) | 740 | (defun hs-hide-level (arg) |
| 748 | "Hide all blocks ARG levels below this block." | 741 | "Hide all blocks ARG levels below this block. |
| 742 | The hook `hs-hide-hook' is run; see `run-hooks'." | ||
| 749 | (interactive "p") | 743 | (interactive "p") |
| 750 | (hs-life-goes-on | 744 | (hs-life-goes-on |
| 751 | (save-excursion | 745 | (save-excursion |
| @@ -755,15 +749,32 @@ become very confused if you use this command indiscriminately." | |||
| 755 | (hs-safety-is-job-n) | 749 | (hs-safety-is-job-n) |
| 756 | (run-hooks 'hs-hide-hook))) | 750 | (run-hooks 'hs-hide-hook))) |
| 757 | 751 | ||
| 758 | ;;;###autoload | ||
| 759 | (defun hs-mouse-toggle-hiding (e) | 752 | (defun hs-mouse-toggle-hiding (e) |
| 760 | "Toggle hiding/showing of a block. | 753 | "Toggle hiding/showing of a block. |
| 761 | Should be bound to a mouse key." | 754 | This command should be bound to a mouse key. |
| 755 | Argument E is a mouse event used by `mouse-set-point'. | ||
| 756 | See `hs-hide-block' and `hs-show-block'." | ||
| 762 | (interactive "@e") | 757 | (interactive "@e") |
| 763 | (mouse-set-point e) | 758 | (hs-life-goes-on |
| 764 | (if (hs-already-hidden-p) | 759 | (mouse-set-point e) |
| 765 | (hs-show-block) | 760 | (if (hs-already-hidden-p) |
| 766 | (hs-hide-block))) | 761 | (hs-show-block) |
| 762 | (hs-hide-block)))) | ||
| 763 | |||
| 764 | (defun hs-hide-initial-comment-block () | ||
| 765 | "Hide the first block of comments in a file. | ||
| 766 | This can be useful if you have huge RCS logs in those comments." | ||
| 767 | (interactive) | ||
| 768 | (hs-life-goes-on | ||
| 769 | (let ((c-reg (save-excursion | ||
| 770 | (goto-char (point-min)) | ||
| 771 | (skip-chars-forward " \t\n\f") | ||
| 772 | (hs-inside-comment-p)))) | ||
| 773 | (when c-reg | ||
| 774 | (let ((beg (car c-reg)) (end (cadr c-reg))) | ||
| 775 | ;; see if we have enough comment lines to hide | ||
| 776 | (when (> (count-lines beg end) 1) | ||
| 777 | (hs-hide-comment-region beg end))))))) | ||
| 767 | 778 | ||
| 768 | ;;;###autoload | 779 | ;;;###autoload |
| 769 | (defun hs-minor-mode (&optional arg) | 780 | (defun hs-minor-mode (&optional arg) |
| @@ -772,12 +783,11 @@ With ARG, turn hideshow minor mode on if ARG is positive, off otherwise. | |||
| 772 | When hideshow minor mode is on, the menu bar is augmented with hideshow | 783 | When hideshow minor mode is on, the menu bar is augmented with hideshow |
| 773 | commands and the hideshow commands are enabled. | 784 | commands and the hideshow commands are enabled. |
| 774 | The value '(hs . t) is added to `buffer-invisibility-spec'. | 785 | The value '(hs . t) is added to `buffer-invisibility-spec'. |
| 775 | Last, the normal hook `hs-minor-mode-hook' is run; see the doc | 786 | Last, the normal hook `hs-minor-mode-hook' is run; see `run-hooks'. |
| 776 | for `run-hooks'. | ||
| 777 | 787 | ||
| 778 | The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block', | 788 | The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block', |
| 779 | `hs-show-block', `hs-hide-level' and `hs-show-region'. | 789 | `hs-show-block', `hs-hide-level' and `hs-show-region'. There is also |
| 780 | Also see the documentation for the variable `hs-show-hidden-short-form'. | 790 | `hs-hide-initial-comment-block' and `hs-mouse-toggle-hiding'. |
| 781 | 791 | ||
| 782 | Turning hideshow minor mode off reverts the menu bar and the | 792 | Turning hideshow minor mode off reverts the menu bar and the |
| 783 | variables to default values and disables the hideshow commands. | 793 | variables to default values and disables the hideshow commands. |
| @@ -786,34 +796,23 @@ Key bindings: | |||
| 786 | \\{hs-minor-mode-map}" | 796 | \\{hs-minor-mode-map}" |
| 787 | 797 | ||
| 788 | (interactive "P") | 798 | (interactive "P") |
| 789 | (setq hs-minor-mode | 799 | (setq hs-headline nil |
| 790 | (if (null arg) | 800 | hs-minor-mode (if (null arg) |
| 791 | (not hs-minor-mode) | 801 | (not hs-minor-mode) |
| 792 | (> (prefix-numeric-value arg) 0))) | 802 | (> (prefix-numeric-value arg) 0))) |
| 793 | (if hs-minor-mode | 803 | (if hs-minor-mode |
| 794 | (progn | 804 | (progn |
| 795 | ; (if (eq hs-emacs-type 'lucid) | 805 | (easy-menu-add hs-minor-mode-menu) |
| 796 | ; (progn | 806 | (make-variable-buffer-local 'line-move-ignore-invisible) |
| 797 | ; (set-buffer-menubar (copy-sequence current-menubar)) | 807 | (setq line-move-ignore-invisible t) |
| 798 | ; (add-menu nil (car hs-menu-bar) (cdr hs-menu-bar)))) | 808 | (add-to-invisibility-spec '(hs . t)) ; hs invisible |
| 799 | (make-local-variable 'line-move-ignore-invisible) | 809 | (hs-grok-mode-type) |
| 800 | (setq line-move-ignore-invisible t) | 810 | (run-hooks 'hs-minor-mode-hook)) |
| 801 | (add-to-invisibility-spec '(hs . t)) ;;hs invisible | 811 | (easy-menu-remove hs-minor-mode-menu) |
| 802 | (hs-grok-mode-type) | ||
| 803 | (run-hooks 'hs-minor-mode-hook)) | ||
| 804 | ; (if (eq hs-emacs-type 'lucid) | ||
| 805 | ; (set-buffer-menubar (delete hs-menu-bar current-menubar))) | ||
| 806 | (remove-from-invisibility-spec '(hs . t)))) | 812 | (remove-from-invisibility-spec '(hs . t)))) |
| 807 | 813 | ||
| 808 | 814 | ;;--------------------------------------------------------------------------- | |
| 809 | ;;;---------------------------------------------------------------------------- | 815 | ;; load-time actions |
| 810 | ;;; load-time setup routines | ||
| 811 | |||
| 812 | ;; which emacs being used? | ||
| 813 | ;(setq hs-emacs-type | ||
| 814 | ; (if (string-match "xemacs\\|lucid" emacs-version) | ||
| 815 | ; 'lucid | ||
| 816 | ; 'fsf)) | ||
| 817 | 816 | ||
| 818 | ;; keymaps and menus | 817 | ;; keymaps and menus |
| 819 | (if hs-minor-mode-map | 818 | (if hs-minor-mode-map |
| @@ -823,22 +822,23 @@ Key bindings: | |||
| 823 | hs-minor-mode-map | 822 | hs-minor-mode-map |
| 824 | "Menu used when hideshow minor mode is active." | 823 | "Menu used when hideshow minor mode is active." |
| 825 | (cons "Hide/Show" | 824 | (cons "Hide/Show" |
| 826 | (mapcar | 825 | (mapcar |
| 827 | ;; populate keymap then massage entry for easymenu | 826 | ;; Interpret each table entry as follows: first, populate keymap |
| 828 | (lambda (ent) | 827 | ;; with elements 2 and 1; then, for easymenu, use entry directly |
| 829 | (define-key hs-minor-mode-map (aref ent 2) (aref ent 1)) | 828 | ;; unless element 0 is nil, in which case the entry is "omitted". |
| 830 | (aset ent 2 (not (vectorp (aref ent 2)))) ; disable mousy stuff | 829 | (lambda (ent) |
| 831 | ent) | 830 | (define-key hs-minor-mode-map (aref ent 2) (aref ent 1)) |
| 832 | ;; I believe there is nothing bound on these keys | 831 | (if (aref ent 0) ent "-----")) |
| 833 | ;; menu entry command key | 832 | ;; I believe there is nothing bound on these keys. |
| 834 | '(["Hide Block" hs-hide-block "\C-ch"] | 833 | ;; menu entry command key |
| 835 | ["Show Block" hs-show-block "\C-cs"] | 834 | '(["Hide Block" hs-hide-block "\C-ch"] |
| 836 | ["Hide All" hs-hide-all "\C-cH"] | 835 | ["Show Block" hs-show-block "\C-cs"] |
| 837 | ["Show All" hs-show-all "\C-cS"] | 836 | ["Hide All" hs-hide-all "\C-cH"] |
| 838 | ["Hide Level" hs-hide-level "\C-cL"] | 837 | ["Show All" hs-show-all "\C-cS"] |
| 839 | ["Show Region" hs-show-region "\C-cR"] | 838 | ["Hide Level" hs-hide-level "\C-cL"] |
| 840 | ["Toggle Hiding" hs-mouse-toggle-hiding [S-mouse-2]] | 839 | ["Show Region" hs-show-region "\C-cR"] |
| 841 | ))))) | 840 | [nil hs-mouse-toggle-hiding [(shift button2)]] |
| 841 | ))))) | ||
| 842 | 842 | ||
| 843 | ;; some housekeeping | 843 | ;; some housekeeping |
| 844 | (or (assq 'hs-minor-mode minor-mode-map-alist) | 844 | (or (assq 'hs-minor-mode minor-mode-map-alist) |
| @@ -851,17 +851,18 @@ Key bindings: | |||
| 851 | 851 | ||
| 852 | ;; make some variables permanently buffer-local | 852 | ;; make some variables permanently buffer-local |
| 853 | (mapcar (lambda (var) | 853 | (mapcar (lambda (var) |
| 854 | (make-variable-buffer-local var) | 854 | (make-variable-buffer-local var) |
| 855 | (put var 'permanent-local t)) | 855 | (put var 'permanent-local t)) |
| 856 | '(hs-minor-mode | 856 | '(hs-minor-mode |
| 857 | hs-c-start-regexp | 857 | hs-c-start-regexp |
| 858 | hs-block-start-regexp | 858 | hs-block-start-regexp |
| 859 | hs-block-end-regexp | 859 | hs-block-start-mdata-select |
| 860 | hs-forward-sexp-func | 860 | hs-block-end-regexp |
| 861 | hs-adjust-block-beginning)) | 861 | hs-forward-sexp-func |
| 862 | 862 | hs-adjust-block-beginning)) | |
| 863 | ;;;---------------------------------------------------------------------------- | 863 | |
| 864 | ;;; that's it | 864 | ;;--------------------------------------------------------------------------- |
| 865 | ;; that's it | ||
| 865 | 866 | ||
| 866 | (provide 'hideshow) | 867 | (provide 'hideshow) |
| 867 | 868 | ||