comparison lisp/modes/hideif.el @ 2:ac2d302a0011 r19-15b2

Import from CVS: tag r19-15b2
author cvs
date Mon, 13 Aug 2007 08:46:35 +0200
parents 376386a54a3c
children 56c54cf7c5b6
comparison
equal deleted inserted replaced
1:c0c6a60d29db 2:ac2d302a0011
1 ;;; hide-ifdef-mode.el --- hides selected code within ifdef. 1 ;;; hide-ifdef-mode.el --- hides selected code within ifdef.
2 ;; Keywords: c 2
3 3 ;; Copyright (C) 1988, 1994 Free Software Foundation, Inc.
4 ;;; Copyright (C) 1988 Brian Marick and Daniel LaLiberte 4
5 ;;; Written by Brian Marick, at Gould, Computer Systems Division, Urbana IL. 5 ;; Author: Dan LaLiberte <liberte@a.cs.uiuc.edu>
6 ;;; Extensively modified by Daniel LaLiberte (while at Gould). 6 ;; Maintainer: FSF
7 ;;; 7 ;; Keywords: c, outlines
8 ;;; You may freely modify and distribute this, but keep a record 8
9 ;;; of modifications and send comments to: 9 ;; This file is part of XEmacs.
10 ;;; liberte@a.cs.uiuc.edu or ihnp4!uiucdcs!liberte 10
11 ;;; I will continue to upgrade hide-ifdef-mode 11 ;; XEmacs is free software; you can redistribute it and/or modify it
12 ;;; with your contributions and will eventually offer it to FSF. 12 ;; under the terms of the GNU General Public License as published by
13 13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;;; Revision 1.7 88/02/16 03:12:58 liberte 14 ;; any later version.
15 ;;; Fixed comments and doc strings. 15
16 ;;; Added optional prefix arg for ifdef motion commands. 16 ;; XEmacs is distributed in the hope that it will be useful, but
17 ;;; 17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;;; Revision 1.6 88/02/05 00:36:18 liberte 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;;; Bug fixes. 19 ;; General Public License for more details.
20 ;;; 1. A multi-line comment that starts on an #ifdef line 20
21 ;;; now ends on that line. 21 ;; You should have received a copy of the GNU General Public License
22 ;;; 2. Fix bad function name: hide-hif-ifdef-toggle-read-only 22 ;; along with XEmacs; see the file COPYING. If not, write to the Free
23 ;;; 3. Make ifdef-block hiding work outside of ifdefs. 23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 ;;; 24 ;; 02111-1307, USA.
25 ;;; Revision 1.5 88/01/31 23:19:31 liberte 25
26 ;;; Major clean up. 26 ;;; Synched up with: FSF 19.34.
27 ;;; Prefix internal names with "hif-".
28 ;;;
29 ;;; Revision 1.4 88/01/30 14:09:38 liberte
30 ;;; Add hide-ifdef-hiding and hide-ifdef-mode to minor-mode-alist.
31 ;;;
32 ;;; Revision 1.3 88/01/29 00:38:19 liberte
33 ;;; Fix three bugs.
34 ;;; 1. Function "defined" is just like lookup.
35 ;;; 2. Skip to newline or cr in case text is hidden.
36 ;;; 3. Use car of token list if just one symbol.
37 ;;;
38 ;;; Revision 1.2 88/01/28 23:32:46 liberte
39 ;;; Use hide-ifdef-mode-prefix-key.
40 ;;; Copy current-local-map so other buffers do not get
41 ;;; hide-ifdef-mode bindings.
42 ;;;
43 ;;;--------------------------------------------------------------
44 27
45 ;;; Commentary: 28 ;;; Commentary:
46 29
47 ;;; To initialize, toggle the hide-ifdef minor mode with 30 ;; To initialize, toggle the hide-ifdef minor mode with
48 ;;; 31 ;;
49 ;;; M-x hide-ifdef-mode 32 ;; M-x hide-ifdef-mode
50 ;;; 33 ;;
51 ;;; This will set up key bindings and call hide-ifdef-mode-hook if it 34 ;; This will set up key bindings and call hide-ifdef-mode-hook if it
52 ;;; has a value. To explicitly hide ifdefs using a buffer-local 35 ;; has a value. To explicitly hide ifdefs using a buffer-local
53 ;;; define list (default empty), type 36 ;; define list (default empty), type
54 ;;; 37 ;;
55 ;;; M-x hide-ifdefs or C-c h 38 ;; M-x hide-ifdefs or C-c @ h
56 ;;; 39 ;;
57 ;;; Hide-ifdef suppresses the display of code that the preprocessor wouldn't 40 ;; Hide-ifdef suppresses the display of code that the preprocessor wouldn't
58 ;;; pass through. The support of constant expressions in #if lines is 41 ;; pass through. The support of constant expressions in #if lines is
59 ;;; limited to identifiers, parens, and the operators: &&, ||, !, and 42 ;; limited to identifiers, parens, and the operators: &&, ||, !, and
60 ;;; "defined". Please extend this. 43 ;; "defined". Please extend this.
61 ;;; 44 ;;
62 ;;; The hidden code is marked by ellipses (...). Be 45 ;; The hidden code is marked by ellipses (...). Be
63 ;;; cautious when editing near ellipses, since the hidden text is 46 ;; cautious when editing near ellipses, since the hidden text is
64 ;;; still in the buffer, and you can move the point into it and modify 47 ;; still in the buffer, and you can move the point into it and modify
65 ;;; text unawares. If you don't want to see the ellipses, set 48 ;; text unawares. If you don't want to see the ellipses, set
66 ;;; selective-display-ellipses to nil. But this can be dangerous. 49 ;; selective-display-ellipses to nil. But this can be dangerous.
67 ;;; You can make your buffer read-only while hide-ifdef-hiding by setting 50 ;; You can make your buffer read-only while hide-ifdef-hiding by setting
68 ;;; hide-ifdef-read-only to a non-nil value. You can toggle this 51 ;; hide-ifdef-read-only to a non-nil value. You can toggle this
69 ;;; variable with hide-ifdef-toggle-read-only (C-c C-q). 52 ;; variable with hide-ifdef-toggle-read-only (C-c @ C-q).
70 ;;; 53 ;;
71 ;;; You can undo the effect of hide-ifdefs by typing 54 ;; You can undo the effect of hide-ifdefs by typing
72 ;;; 55 ;;
73 ;;; M-x show-ifdefs or C-c s 56 ;; M-x show-ifdefs or C-c @ s
74 ;;; 57 ;;
75 ;;; Use M-x hide-ifdef-define (C-c d) to define a symbol. 58 ;; Use M-x hide-ifdef-define (C-c @ d) to define a symbol.
76 ;;; Use M-x hide-ifdef-undef (C-c u) to undefine a symbol. 59 ;; Use M-x hide-ifdef-undef (C-c @ u) to undefine a symbol.
77 ;;; 60 ;;
78 ;;; If you define or undefine a symbol while hide-ifdef-mode is in effect, 61 ;; If you define or undefine a symbol while hide-ifdef-mode is in effect,
79 ;;; the display will be updated. Only the define list for the current 62 ;; the display will be updated. Only the define list for the current
80 ;;; buffer will be affected. You can save changes to the local define 63 ;; buffer will be affected. You can save changes to the local define
81 ;;; list with hide-ifdef-set-define-alist. This adds entries 64 ;; list with hide-ifdef-set-define-alist. This adds entries
82 ;;; to hide-ifdef-define-alist. 65 ;; to hide-ifdef-define-alist.
83 ;;; 66 ;;
84 ;;; If you have defined a hide-ifdef-mode-hook, you can set 67 ;; If you have defined a hide-ifdef-mode-hook, you can set
85 ;;; up a list of symbols that may be used by hide-ifdefs as in the 68 ;; up a list of symbols that may be used by hide-ifdefs as in the
86 ;;; following example: 69 ;; following example:
87 ;;; 70 ;;
88 ;;; (setq hide-ifdef-mode-hook 71 ;; (setq hide-ifdef-mode-hook
89 ;;; '(lambda () 72 ;; '(lambda ()
90 ;;; (if (not hide-ifdef-define-alist) 73 ;; (if (not hide-ifdef-define-alist)
91 ;;; (setq hide-ifdef-define-alist 74 ;; (setq hide-ifdef-define-alist
92 ;;; '((list1 ONE TWO) 75 ;; '((list1 ONE TWO)
93 ;;; (list2 TWO THREE) 76 ;; (list2 TWO THREE)
94 ;;; ))) 77 ;; )))
95 ;;; (hide-ifdef-use-define-alist 'list2) ; use list2 by default 78 ;; (hide-ifdef-use-define-alist 'list2) ; use list2 by default
96 ;;; )) 79 ;; ))
97 ;;; 80 ;;
98 ;;; You can call hide-ifdef-use-define-alist (C-c u) at any time to specify 81 ;; You can call hide-ifdef-use-define-alist (C-c u) at any time to specify
99 ;;; another list to use. 82 ;; another list to use.
100 ;;; 83 ;;
101 ;;; To cause ifdefs to be hidden as soon as hide-ifdef-mode is called, 84 ;; To cause ifdefs to be hidden as soon as hide-ifdef-mode is called,
102 ;;; set hide-ifdef-initially to non-nil. 85 ;; set hide-ifdef-initially to non-nil.
103 ;;; 86 ;;
104 ;;; If you set hide-ifdef-lines to t, hide-ifdefs hides all the #ifdef lines. 87 ;; If you set hide-ifdef-lines to t, hide-ifdefs hides all the #ifdef lines.
105 ;;; In the absence of highlighting, that might be a bad idea. If you set 88 ;; In the absence of highlighting, that might be a bad idea. If you set
106 ;;; hide-ifdef-lines to nil (the default), the surrounding preprocessor 89 ;; hide-ifdef-lines to nil (the default), the surrounding preprocessor
107 ;;; lines will be displayed. That can be confusing in its own 90 ;; lines will be displayed. That can be confusing in its own
108 ;;; right. Other variations on display are possible, but not much 91 ;; right. Other variations on display are possible, but not much
109 ;;; better. 92 ;; better.
110 ;;; 93 ;;
111 ;;; You can explicitly hide or show individual ifdef blocks irrespective 94 ;; You can explicitly hide or show individual ifdef blocks irrespective
112 ;;; of the define list by using hide-ifdef-block and show-ifdef-block. 95 ;; of the define list by using hide-ifdef-block and show-ifdef-block.
113 ;;; 96 ;;
114 ;;; You can move the point between ifdefs with forward-ifdef, backward-ifdef, 97 ;; You can move the point between ifdefs with forward-ifdef, backward-ifdef,
115 ;;; up-ifdef, down-ifdef, next-ifdef, and previous-ifdef. 98 ;; up-ifdef, down-ifdef, next-ifdef, and previous-ifdef.
116 ;;; 99 ;;
117 ;;; If you have minor-mode-alist in your modeline (the default) two labels 100 ;; If you have minor-mode-alist in your mode line (the default) two labels
118 ;;; may appear. "Ifdef" will appear when hide-ifdef-mode is active. "Hiding" 101 ;; may appear. "Ifdef" will appear when hide-ifdef-mode is active. "Hiding"
119 ;;; will appear when text may be hidden ("hide-ifdef-hiding" is non-nil). 102 ;; will appear when text may be hidden ("hide-ifdef-hiding" is non-nil).
103 ;;
104 ;; Written by Brian Marick, at Gould, Computer Systems Division, Urbana IL.
105 ;; Extensively modified by Daniel LaLiberte (while at Gould).
106 ;;
107 ;; You may freely modify and distribute this, but keep a record
108 ;; of modifications and send comments to:
109 ;; liberte@a.cs.uiuc.edu or ihnp4!uiucdcs!liberte
110 ;; I will continue to upgrade hide-ifdef-mode
111 ;; with your contributions.
120 112
121 ;;; Code: 113 ;;; Code:
122 114
115 (require 'cc-mode)
116
117 (defvar hide-ifdef-mode-submap nil
118 "Keymap used with Hide-Ifdef mode.")
119
123 (defvar hide-ifdef-mode-map nil 120 (defvar hide-ifdef-mode-map nil
124 "Keymap used with hide-ifdef mode") 121 "Keymap used with Hide-Ifdef mode.")
125 122
126 (defconst hide-ifdef-mode-prefix-key "\C-c" 123 (defconst hide-ifdef-mode-prefix-key "\C-c@"
127 "Prefix key for all hide-ifdef-mode commands.") 124 "Prefix key for all Hide-Ifdef mode commands.")
128 125
129 (defvar hide-ifdef-mode-map-before nil 126 ;; Set up the submap that goes after the prefix key.
130 "Buffer-local variable to store a copy of the local keymap 127 (if hide-ifdef-mode-submap
131 before hide-ifdef-mode modifies it.") 128 () ; Don't redefine it.
132 129 (setq hide-ifdef-mode-submap (make-sparse-keymap))
133 (defun define-hide-ifdef-mode-map () 130 (define-key hide-ifdef-mode-submap "d" 'hide-ifdef-define)
134 (if hide-ifdef-mode-map 131 (define-key hide-ifdef-mode-submap "u" 'hide-ifdef-undef)
135 () ; dont redefine it. 132 (define-key hide-ifdef-mode-submap "D" 'hide-ifdef-set-define-alist)
136 (setq hide-ifdef-mode-map (make-sparse-keymap)) 133 (define-key hide-ifdef-mode-submap "U" 'hide-ifdef-use-define-alist)
137 (define-key hide-ifdef-mode-map "d" 'hide-ifdef-define) 134
138 (define-key hide-ifdef-mode-map "u" 'hide-ifdef-undef) 135 (define-key hide-ifdef-mode-submap "h" 'hide-ifdefs)
139 (define-key hide-ifdef-mode-map "D" 'hide-ifdef-set-define-alist) 136 (define-key hide-ifdef-mode-submap "s" 'show-ifdefs)
140 (define-key hide-ifdef-mode-map "U" 'hide-ifdef-use-define-alist) 137 (define-key hide-ifdef-mode-submap "\C-d" 'hide-ifdef-block)
141 138 (define-key hide-ifdef-mode-submap "\C-s" 'show-ifdef-block)
142 (define-key hide-ifdef-mode-map "h" 'hide-ifdefs) 139
143 (define-key hide-ifdef-mode-map "s" 'show-ifdefs) 140 (define-key hide-ifdef-mode-submap "\C-q" 'hide-ifdef-toggle-read-only)
144 (define-key hide-ifdef-mode-map "\C-h" 'hide-ifdef-block) 141 (let ((where (where-is-internal 'toggle-read-only '(keymap) t)))
145 (define-key hide-ifdef-mode-map "\C-s" 'show-ifdef-block) 142 (if where
146 143 (define-key hide-ifdef-mode-submap
147 (define-key hide-ifdef-mode-map "\C-f" 'forward-ifdef) 144 where
148 (define-key hide-ifdef-mode-map "\C-b" 'backward-ifdef) 145 'hide-ifdef-toggle-outside-read-only)))
149 (define-key hide-ifdef-mode-map "\C-d" 'down-ifdef)
150 (define-key hide-ifdef-mode-map "\C-u" 'up-ifdef)
151 (define-key hide-ifdef-mode-map "\C-n" 'next-ifdef)
152 (define-key hide-ifdef-mode-map "\C-p" 'previous-ifdef)
153 (define-key hide-ifdef-mode-map "\C-q" 'hide-ifdef-toggle-read-only)
154 (define-key hide-ifdef-mode-map
155 (where-is-internal 'toggle-read-only nil t)
156 'hide-ifdef-toggle-outside-read-only)
157 )
158 (fset 'hide-ifdef-mode-map hide-ifdef-mode-map) ; the function is the map
159 ) 146 )
160 147
161 (defun hif-update-mode-line () 148 ;; Set up the mode's main map, which leads via the prefix key to the submap.
162 "Update mode-line by setting buffer-modified to itself." 149 (if hide-ifdef-mode-map
163 (set-buffer-modified-p (buffer-modified-p))) 150 ()
164 151 (setq hide-ifdef-mode-map (make-sparse-keymap))
152 (define-key hide-ifdef-mode-map hide-ifdef-mode-prefix-key
153 hide-ifdef-mode-submap))
165 154
166 (defvar hide-ifdef-mode nil 155 (defvar hide-ifdef-mode nil
167 "non-nil when hide-ifdef-mode is activated.") 156 "Non-nil when hide-ifdef-mode is activated.")
168 157
169 (defvar hide-ifdef-hiding nil 158 (defvar hide-ifdef-hiding nil
170 "non-nil when text may be hidden.") 159 "Non-nil when text may be hidden.")
171 160
172 (or (assq 'hide-ifdef-hiding minor-mode-alist) 161 (or (assq 'hide-ifdef-hiding minor-mode-alist)
173 (setq minor-mode-alist 162 (setq minor-mode-alist
174 (cons '(hide-ifdef-hiding " Hiding") 163 (cons '(hide-ifdef-hiding " Hiding")
175 minor-mode-alist))) 164 minor-mode-alist)))
180 ; minor-mode-alist))) 169 ; minor-mode-alist)))
181 ;; XEmacs: do it right. 170 ;; XEmacs: do it right.
182 ;;;###autoload 171 ;;;###autoload
183 (add-minor-mode 'hide-ifdef-mode " Ifdef") 172 (add-minor-mode 'hide-ifdef-mode " Ifdef")
184 173
174 ;; fix c-mode syntax table so we can recognize whole symbols.
175 (defvar hide-ifdef-syntax-table
176 (copy-syntax-table c-mode-syntax-table)
177 "Syntax table used for tokenizing #if expressions.")
178
179 (modify-syntax-entry ?_ "w" hide-ifdef-syntax-table)
180 (modify-syntax-entry ?& "." hide-ifdef-syntax-table)
181 (modify-syntax-entry ?\| "." hide-ifdef-syntax-table)
182
183 ;;;###autoload
185 (defun hide-ifdef-mode (arg) 184 (defun hide-ifdef-mode (arg)
186 "Toggle hide-ifdef-mode. Thus this is a minor mode, albeit a large one. 185 "Toggle Hide-Ifdef mode. This is a minor mode, albeit a large one.
187 With arg, turn hide-ifdef-mode on iff arg is positive. 186 With ARG, turn Hide-Ifdef mode on if arg is positive, off otherwise.
188 In hide-ifdef-mode, code within #ifdef constructs that the C preprocessor 187 In Hide-Ifdef mode, code within #ifdef constructs that the C preprocessor
189 would eliminate may be hidden from view. Several variables affect 188 would eliminate may be hidden from view. Several variables affect
190 how the hiding is done: 189 how the hiding is done:
191 190
192 hide-ifdef-env 191 hide-ifdef-env
193 An association list of defined and undefined symbols for the 192 An association list of defined and undefined symbols for the
194 current buffer. Initially, the global value of hide-ifdef-env is used. 193 current buffer. Initially, the global value of `hide-ifdef-env'
194 is used.
195 195
196 hide-ifdef-define-alist 196 hide-ifdef-define-alist
197 An association list of defined symbol lists. 197 An association list of defined symbol lists.
198 Use hide-ifdef-set-define-alist to save the current hide-ifdef-env 198 Use `hide-ifdef-set-define-alist' to save the current `hide-ifdef-env'
199 and hide-ifdef-use-define-alist to set the current hide-ifdef-env 199 and `hide-ifdef-use-define-alist' to set the current `hide-ifdef-env'
200 from one of the lists in hide-ifdef-define-alist. 200 from one of the lists in `hide-ifdef-define-alist'.
201 201
202 hide-ifdef-lines 202 hide-ifdef-lines
203 Set to non-nil to not show #if, #ifdef, #ifndef, #else, and 203 Set to non-nil to not show #if, #ifdef, #ifndef, #else, and
204 #endif lines when hiding. 204 #endif lines when hiding.
205 205
206 hide-ifdef-initially 206 hide-ifdef-initially
207 Indicates whether hide-ifdefs should be called when hide-ifdef-mode 207 Indicates whether `hide-ifdefs' should be called when Hide-Ifdef mode
208 is activated. 208 is activated.
209 209
210 hide-ifdef-read-only 210 hide-ifdef-read-only
211 Set to non-nil if you want to make buffers read only while hiding. 211 Set to non-nil if you want to make buffers read only while hiding.
212 After show-ifdefs, read-only status is restored to previous value. 212 After `show-ifdefs', read-only status is restored to previous value.
213 213
214 \\{hide-ifdef-mode-map}" 214 \\{hide-ifdef-mode-map}"
215 215
216 (interactive "P") 216 (interactive "P")
217 (make-local-variable 'hide-ifdef-mode) 217 (make-local-variable 'hide-ifdef-mode)
218 (setq hide-ifdef-mode 218 (setq hide-ifdef-mode
219 (if (null arg) 219 (if (null arg)
220 (not hide-ifdef-mode) 220 (not hide-ifdef-mode)
221 (> (prefix-numeric-value arg) 0))) 221 (> (prefix-numeric-value arg) 0)))
222 222
223 (hif-update-mode-line) 223 ;; XEmacs change
224 (redraw-modeline)
224 225
225 (if hide-ifdef-mode 226 (if hide-ifdef-mode
226 (progn 227 (progn
227 ; fix c-mode syntax table so we can recognize whole symbols. 228 ; fix c-mode syntax table so we can recognize whole symbols.
228 (modify-syntax-entry ?_ "w") 229 ;; XEmacs: Maybe we don't need this any more with cc-mode? -sb
229 (modify-syntax-entry ?& ".") 230 ;; (modify-syntax-entry ?_ "w")
230 (modify-syntax-entry ?\| ".") 231 ;; (modify-syntax-entry ?& ".")
232 ;; (modify-syntax-entry ?\| ".")
231 233
232 ; inherit global values 234 ; inherit global values
233 (make-local-variable 'hide-ifdef-env) 235 (make-local-variable 'hide-ifdef-env)
234 (setq hide-ifdef-env (default-value 'hide-ifdef-env)) 236 (setq hide-ifdef-env (default-value 'hide-ifdef-env))
235 237
237 (setq hide-ifdef-hiding (default-value 'hide-ifdef-hiding)) 239 (setq hide-ifdef-hiding (default-value 'hide-ifdef-hiding))
238 240
239 (make-local-variable 'hif-outside-read-only) 241 (make-local-variable 'hif-outside-read-only)
240 (setq hif-outside-read-only buffer-read-only) 242 (setq hif-outside-read-only buffer-read-only)
241 243
242 (make-local-variable 'hide-ifdef-mode-map-before)
243 (setq hide-ifdef-mode-map-before (current-local-map))
244 (use-local-map (copy-keymap (current-local-map)))
245 (local-unset-key hide-ifdef-mode-prefix-key)
246 (local-set-key hide-ifdef-mode-prefix-key 'hide-ifdef-mode-map)
247 (define-hide-ifdef-mode-map)
248
249 (run-hooks 'hide-ifdef-mode-hook) 244 (run-hooks 'hide-ifdef-mode-hook)
250 245
251 (if hide-ifdef-initially 246 (if hide-ifdef-initially
252 (hide-ifdefs) 247 (hide-ifdefs)
253 (show-ifdefs)) 248 (show-ifdefs))
254 (message "Enter hide-ifdef-mode.") 249 (message "Enter Hide-Ifdef mode")
255 ) 250 )
256 ; else end hide-ifdef-mode 251 ; else end hide-ifdef-mode
257 (if hide-ifdef-hiding 252 (if hide-ifdef-hiding
258 (show-ifdefs)) 253 (show-ifdefs))
259 (use-local-map hide-ifdef-mode-map-before) 254 (message "Exit Hide-Ifdef mode")
260 (message "Exit hide-ifdef-mode.")
261 )) 255 ))
262 256
263 257
264 ;; from outline.el with docstring fixed. 258 ;; from outline.el with docstring fixed.
265 (defun hif-outline-flag-region (from to flag) 259 (defun hif-outline-flag-region (from to flag)
266 "Hides or shows lines from FROM to TO, according to FLAG. If FLAG 260 "Hides or shows lines from FROM to TO, according to FLAG.
267 is \\n (newline character) then text is shown, while if FLAG is \\^M 261 If FLAG is \\n (newline character) then text is shown, while if FLAG is \\^M
268 \(control-M) the text is hidden." 262 \(control-M) the text is hidden."
269 (let ((modp (buffer-modified-p))) 263 (let ((modp (buffer-modified-p)))
270 (unwind-protect (progn 264 (unwind-protect (progn
271 (subst-char-in-region from to 265 (subst-char-in-region from to
272 (if (= flag ?\n) ?\^M ?\n) 266 (if (= flag ?\n) ?\^M ?\n)
277 (defun hif-show-all () 271 (defun hif-show-all ()
278 "Show all of the text in the current buffer." 272 "Show all of the text in the current buffer."
279 (interactive) 273 (interactive)
280 (hif-outline-flag-region (point-min) (point-max) ?\n)) 274 (hif-outline-flag-region (point-min) (point-max) ?\n))
281 275
276 ;; By putting this on after-revert-hook, we arrange that it only
277 ;; does anything when revert-buffer avoids turning off the mode.
278 ;; (That can happen in VC.)
279 (defun hif-before-revert-function ()
280 (and hide-ifdef-mode hide-ifdef-hiding
281 (hide-ifdefs t)))
282 (add-hook 'after-revert-hook 'hif-before-revert-function)
283
282 (defun hide-ifdef-region (start end) 284 (defun hide-ifdef-region (start end)
283 "START is the start of a #if or #else form. END is the ending part. 285 "START is the start of a #if or #else form. END is the ending part.
284 Everything including these lines is made invisible." 286 Everything including these lines is made invisible."
285 (hif-outline-flag-region start end ?\^M) 287 (hif-outline-flag-region start end ?\^M)
286 ) 288 )
292 294
293 295
294 296
295 ;===%%SF%% evaluation (Start) === 297 ;===%%SF%% evaluation (Start) ===
296 298
299 ;; It is not useful to set this to anything but `eval'.
300 ;; In fact, the variable might as well be eliminated.
297 (defvar hide-ifdef-evaluator 'eval 301 (defvar hide-ifdef-evaluator 'eval
298 "The evaluator is given a canonical form and returns T if text under 302 "The function to use to evaluate a form.
303 The evaluator is given a canonical form and returns t if text under
299 that form should be displayed.") 304 that form should be displayed.")
300 305
301 (defvar hif-undefined-symbol nil 306 (defvar hif-undefined-symbol nil
302 "...is by default considered to be false.") 307 "...is by default considered to be false.")
303 308
349 (` (hif-lookup (quote (, (car token-list))))) 354 (` (hif-lookup (quote (, (car token-list)))))
350 (hif-parse-if-exp token-list)) 355 (hif-parse-if-exp token-list))
351 ) 356 )
352 357
353 ; pattern to match initial identifier, !, &&, ||, (, or ). 358 ; pattern to match initial identifier, !, &&, ||, (, or ).
354 (defconst hif-token-regexp "^\\(!\\|&&\\|||\\|[()]\\|\\w+\\)") 359 ; Added ==, + and -: garyo@avs.com 8/9/94
360 (defconst hif-token-regexp "^\\(!\\|&&\\|||\\|[!=]=\\|[()+-]\\|\\w+\\)")
355 (defconst hif-end-of-comment "\\*/") 361 (defconst hif-end-of-comment "\\*/")
356 362
357 363
358 (defun hif-tokenize (expr-string) 364 (defun hif-tokenize (expr-string)
359 "Separate string into a list of tokens" 365 "Separate string into a list of tokens"
360 (let ((token-list nil) 366 (let ((token-list nil)
361 (expr-start 0) 367 (expr-start 0)
362 (expr-length (length expr-string))) 368 (expr-length (length expr-string))
363 369 (current-syntax-table (syntax-table)))
364 (while (< expr-start expr-length) 370 (unwind-protect
365 ; (message "expr-start = %d" expr-start) (sit-for 1) 371 (progn
366 (cond 372 (set-syntax-table hide-ifdef-syntax-table)
367 ((string-match "^[ \t]+" expr-string expr-start) 373 (while (< expr-start expr-length)
368 ; skip whitespace 374 ; (message "expr-start = %d" expr-start) (sit-for 1)
369 (setq expr-start (match-end 0)) 375 (cond
370 ; stick newline in string so ^ matches on the next string-match 376 ((string-match "^[ \t]+" expr-string expr-start)
371 (aset expr-string (1- expr-start) ?\n) 377 ;; skip whitespace
372 ) 378 (setq expr-start (match-end 0))
373 379 ;; stick newline in string so ^ matches on the next string-match
374 ((string-match "^/\\*" expr-string expr-start) 380 (aset expr-string (1- expr-start) ?\n))
375 (setq expr-start (match-end 0)) 381
376 (aset expr-string (1- expr-start) ?\n) 382 ((string-match "^/\\*" expr-string expr-start)
377 (or 383 (setq expr-start (match-end 0))
378 (string-match hif-end-of-comment 384 (aset expr-string (1- expr-start) ?\n)
379 expr-string expr-start) ; eat comment 385 (or
380 (string-match "$" expr-string expr-start)) ; multi-line comment 386 (string-match hif-end-of-comment
381 (setq expr-start (match-end 0)) 387 expr-string expr-start) ; eat comment
382 (aset expr-string (1- expr-start) ?\n) 388 (string-match "$" expr-string expr-start)) ; multi-line comment
383 ) 389 (setq expr-start (match-end 0))
384 390 (aset expr-string (1- expr-start) ?\n))
385 ((string-match hif-token-regexp expr-string expr-start) 391
386 (let ((token (substring expr-string expr-start (match-end 0)))) 392 ((string-match "^//" expr-string expr-start)
387 (setq expr-start (match-end 0)) 393 (string-match "$" expr-string expr-start)
388 (aset expr-string (1- expr-start) ?\n) 394 (setq expr-start (match-end 0)))
389 ; (message "token: %s" token) (sit-for 1) 395
390 (setq token-list 396 ((string-match hif-token-regexp expr-string expr-start)
391 (cons 397 (let ((token (substring expr-string expr-start (match-end 0))))
392 (cond 398 (setq expr-start (match-end 0))
393 ((string-equal token "||") 'or) 399 (aset expr-string (1- expr-start) ?\n)
394 ((string-equal token "&&") 'and) 400 ; (message "token: %s" token) (sit-for 1)
395 ((string-equal token "!") 'not) 401 (setq token-list
396 ((string-equal token "defined") 'hif-defined) 402 (cons
397 ((string-equal token "(") 'lparen) 403 (cond
398 ((string-equal token ")") 'rparen) 404 ((string-equal token "||") 'or)
399 (t (intern token))) 405 ((string-equal token "&&") 'and)
400 token-list)) 406 ((string-equal token "==") 'equal)
401 )) 407 ((string-equal token "!=") 'hif-notequal)
402 (t (error "Bad #if expression: %s" expr-string)) 408 ((string-equal token "!") 'not)
403 )) 409 ((string-equal token "defined") 'hif-defined)
404 (nreverse token-list) 410 ((string-equal token "(") 'lparen)
405 )) 411 ((string-equal token ")") 'rparen)
412 ((string-equal token "+") 'hif-plus)
413 ((string-equal token "-") 'hif-minus)
414 (t (intern token)))
415 token-list))))
416 (t (error "Bad #if expression: %s" expr-string)))))
417 (set-syntax-table current-syntax-table))
418 (nreverse token-list)))
406 419
407 ;;;----------------------------------------------------------------- 420 ;;;-----------------------------------------------------------------
408 ;;; Translate C preprocessor #if expressions using recursive descent. 421 ;;; Translate C preprocessor #if expressions using recursive descent.
409 ;;; This parser is limited to the operators &&, ||, !, and "defined". 422 ;;; This parser is limited to the operators &&, ||, !, and "defined".
423 ;;; Added ==, !=, +, and -. Gary Oberbrunner, garyo@avs.com, 8/9/94
410 424
411 (defun hif-parse-if-exp (token-list) 425 (defun hif-parse-if-exp (token-list)
412 "Parse the TOKEN-LIST. Return translated list in prefix form." 426 "Parse the TOKEN-LIST. Return translated list in prefix form."
413 (hif-nexttoken) 427 (hif-nexttoken)
414 (prog1 428 (prog1
415 (hif-expr) 429 (hif-expr)
416 (if token ; is there still a token? 430 (if token ; is there still a token?
417 (error "Error: unexpected token: %s" token))) 431 (error "Error: unexpected token: %s" token))))
418 )
419 432
420 (defun hif-nexttoken () 433 (defun hif-nexttoken ()
421 "Pop the next token from token-list into the let variable \"token\"." 434 "Pop the next token from token-list into the let variable \"token\"."
422 (setq token (car token-list)) 435 (setq token (car token-list))
423 (setq token-list (cdr token-list)) 436 (setq token-list (cdr token-list))
424 token 437 token)
425 )
426 438
427 (defun hif-expr () 439 (defun hif-expr ()
428 "Parse and expression of the form 440 "Parse an expression as found in #if.
429 expr : term | expr '||' term." 441 expr : term | expr '||' term."
430 (let ((result (hif-term))) 442 (let ((result (hif-term)))
431 (while (eq token 'or) 443 (while (eq token 'or)
432 (hif-nexttoken) 444 (hif-nexttoken)
433 (setq result (list 'or result (hif-term)))) 445 (setq result (list 'or result (hif-term))))
434 result 446 result))
435 ))
436 447
437 (defun hif-term () 448 (defun hif-term ()
438 "Parse a term of the form 449 "Parse a term : eq-expr | term '&&' eq-expr."
439 term : factor | term '&&' factor." 450 (let ((result (hif-eq-expr)))
440 (let ((result (hif-factor)))
441 (while (eq token 'and) 451 (while (eq token 'and)
442 (hif-nexttoken) 452 (hif-nexttoken)
443 (setq result (list 'and result (hif-factor)))) 453 (setq result (list 'and result (hif-eq-expr))))
444 result 454 result))
445 )) 455
456 (defun hif-eq-expr ()
457 "Parse an eq-expr : math | eq-expr '=='|'!=' math."
458 (let ((result (hif-math))
459 (eq-token nil))
460 (while (or (eq token 'equal) (eq token 'hif-notequal))
461 (setq eq-token token)
462 (hif-nexttoken)
463 (setq result (list eq-token result (hif-math))))
464 result))
465
466 (defun hif-math ()
467 "Parse an expression with + or - and simpler things.
468 math : factor | math '+|-' factor."
469 (let ((result (hif-factor))
470 (math-op nil))
471 (while (or (eq token 'hif-plus) (eq token 'hif-minus))
472 (setq math-op token)
473 (hif-nexttoken)
474 (setq result (list math-op result (hif-factor))))
475 result))
446 476
447 (defun hif-factor () 477 (defun hif-factor ()
448 "Parse a factor of the form 478 "Parse a factor: '!' factor | '(' expr ')' | 'defined(' id ')' | id."
449 factor : '!' factor | '(' expr ')' | 'defined(' id ')' | id."
450 (cond 479 (cond
451 ((eq token 'not) 480 ((eq token 'not)
452 (hif-nexttoken) 481 (hif-nexttoken)
453 (list 'not (hif-factor))) 482 (list 'not (hif-factor)))
454 483
480 (if (memq ident '(or and)) 509 (if (memq ident '(or and))
481 (error "Error: missing identifier")) 510 (error "Error: missing identifier"))
482 (hif-nexttoken) 511 (hif-nexttoken)
483 (` (hif-lookup (quote (, ident)))) 512 (` (hif-lookup (quote (, ident))))
484 )) 513 ))
485
486 )) 514 ))
487 515
516 (defun hif-mathify (val)
517 "Treat VAL as a number: if it's t or nil, use 1 or 0."
518 (cond ((eq val t)
519 1)
520 ((null val)
521 0)
522 (t val)))
523
524 (defun hif-plus (a b)
525 "Like ordinary plus but treat t and nil as 1 and 0."
526 (+ (hif-mathify a) (hif-mathify b)))
527 (defun hif-minus (a b)
528 "Like ordinary minus but treat t and nil as 1 and 0."
529 (- (hif-mathify a) (hif-mathify b)))
530 (defun hif-notequal (a b)
531 "Like (not (equal A B)) but as one symbol."
532 (not (equal a b)))
533
488 ;;;----------- end of parser ----------------------- 534 ;;;----------- end of parser -----------------------
489 535
490 536
491 (defun hif-canonicalize () 537 (defun hif-canonicalize ()
492 "When at beginning of #ifX, returns a canonical (evaluatable) 538 "When at beginning of #ifX, returns a Lisp expression for its condition."
493 form for the expression."
494 (save-excursion 539 (save-excursion
495 (let ((negate (looking-at hif-ifndef-regexp))) 540 (let ((negate (looking-at hif-ifndef-regexp)))
496 (re-search-forward hif-ifx-regexp) 541 (re-search-forward hif-ifx-regexp)
497 (let* ((expr-string 542 (let* ((expr-string
498 (buffer-substring (point) 543 (buffer-substring (point)
503 (list 'not expr) 548 (list 'not expr)
504 expr))))) 549 expr)))))
505 550
506 551
507 (defun hif-find-any-ifX () 552 (defun hif-find-any-ifX ()
508 "Position at beginning of next #if, #ifdef, or #ifndef, including one on 553 "Move to next #if..., or #ifndef, at point or after."
509 this line."
510 ; (message "find ifX at %d" (point)) 554 ; (message "find ifX at %d" (point))
511 (prog1 555 (prog1
512 (re-search-forward hif-ifx-regexp (point-max) t) 556 (re-search-forward hif-ifx-regexp (point-max) t)
513 (beginning-of-line))) 557 (beginning-of-line)))
514 558
515 559
516 (defun hif-find-next-relevant () 560 (defun hif-find-next-relevant ()
517 "Position at beginning of next #ifdef, #ifndef, #else, #endif, 561 "Move to next #if..., #else, or #endif, after the current line."
518 NOT including one on this line."
519 ; (message "hif-find-next-relevant at %d" (point)) 562 ; (message "hif-find-next-relevant at %d" (point))
520 (end-of-line) 563 (end-of-line)
521 ; avoid infinite recursion by only going to beginning of line if match found 564 ; avoid infinite recursion by only going to beginning of line if match found
522 (if (re-search-forward hif-ifx-else-endif-regexp (point-max) t) 565 (if (re-search-forward hif-ifx-else-endif-regexp (point-max) t)
523 (beginning-of-line)) 566 (beginning-of-line)))
524 )
525 567
526 (defun hif-find-previous-relevant () 568 (defun hif-find-previous-relevant ()
527 "Position at beginning of previous #ifdef, #ifndef, #else, #endif, 569 "Move to previous #if..., #else, or #endif, before the current line."
528 NOT including one on this line."
529 ; (message "hif-find-previous-relevant at %d" (point)) 570 ; (message "hif-find-previous-relevant at %d" (point))
530 (beginning-of-line) 571 (beginning-of-line)
531 ; avoid infinite recursion by only going to beginning of line if match found 572 ; avoid infinite recursion by only going to beginning of line if match found
532 (if (re-search-backward hif-ifx-else-endif-regexp (point-min) t) 573 (if (re-search-backward hif-ifx-else-endif-regexp (point-min) t)
533 (beginning-of-line) 574 (beginning-of-line)))
534 )
535 )
536 575
537 576
538 (defun hif-looking-at-ifX () ;; Should eventually see #if 577 (defun hif-looking-at-ifX () ;; Should eventually see #if
539 (looking-at hif-ifx-regexp)) 578 (looking-at hif-ifx-regexp))
540 (defun hif-looking-at-endif () 579 (defun hif-looking-at-endif ()
554 ((hif-looking-at-else) 593 ((hif-looking-at-else)
555 (hif-ifdef-to-endif)) ; find endif following else 594 (hif-ifdef-to-endif)) ; find endif following else
556 ((hif-looking-at-endif) 595 ((hif-looking-at-endif)
557 'done) 596 'done)
558 (t 597 (t
559 (error "Missmatched #ifdef #endif pair")) 598 (error "Mismatched #ifdef #endif pair"))))
560 ))
561 599
562 600
563 (defun hif-endif-to-ifdef () 601 (defun hif-endif-to-ifdef ()
564 "If positioned at #endif form, skip backward to corresponding #ifX." 602 "If positioned at #endif form, skip backward to corresponding #ifX."
565 ; (message "hif-endif-to-ifdef at %d" (point)) 603 ; (message "hif-endif-to-ifdef at %d" (point))
566 (let ((start (point))) 604 (let ((start (point)))
567 (hif-find-previous-relevant) 605 (hif-find-previous-relevant)
568 (if (= start (point)) 606 (if (= start (point))
569 (error "Missmatched #ifdef #endif pair"))) 607 (error "Mismatched #ifdef #endif pair")))
570 (cond ((hif-looking-at-endif) 608 (cond ((hif-looking-at-endif)
571 (hif-endif-to-ifdef) ; find beginning of nested if 609 (hif-endif-to-ifdef) ; find beginning of nested if
572 (hif-endif-to-ifdef)) ; find beginning of outer if or else 610 (hif-endif-to-ifdef)) ; find beginning of outer if or else
573 ((hif-looking-at-else) 611 ((hif-looking-at-else)
574 (hif-endif-to-ifdef)) 612 (hif-endif-to-ifdef))
575 ((hif-looking-at-ifX) 613 ((hif-looking-at-ifX)
576 'done) 614 'done)
577 (t ; never gets here 615 (t))) ; never gets here
578 )))
579 616
580 617
581 (defun forward-ifdef (&optional arg) 618 (defun forward-ifdef (&optional arg)
582 "Move point to beginning of line of the next ifdef-endif. 619 "Move point to beginning of line of the next ifdef-endif.
583 With argument, do this that many times." 620 With argument, do this that many times."
584 (interactive "p") 621 (interactive "p")
585 (or arg (setq arg 1)) 622 (or arg (setq arg 1))
586 (if (< arg 0) 623 (if (< arg 0)
587 (backward-ifdef (- arg))) 624 (backward-ifdef (- arg)))
588 (while (< 0 arg) 625 (while (< 0 arg)
597 )))) 634 ))))
598 635
599 636
600 (defun backward-ifdef (&optional arg) 637 (defun backward-ifdef (&optional arg)
601 "Move point to beginning of the previous ifdef-endif. 638 "Move point to beginning of the previous ifdef-endif.
602 With argument, do this that many times." 639 With argument, do this that many times."
603 (interactive "p") 640 (interactive "p")
604 (or arg (setq arg 1)) 641 (or arg (setq arg 1))
605 (if (< arg 0) 642 (if (< arg 0)
606 (forward-ifdef (- arg))) 643 (forward-ifdef (- arg)))
607 (while (< 0 arg) 644 (while (< 0 arg)
611 (if (not (hif-looking-at-endif)) 648 (if (not (hif-looking-at-endif))
612 (hif-find-previous-relevant)) 649 (hif-find-previous-relevant))
613 (if (hif-looking-at-endif) 650 (if (hif-looking-at-endif)
614 (hif-endif-to-ifdef) 651 (hif-endif-to-ifdef)
615 (goto-char start) 652 (goto-char start)
616 (error "No previous #ifdef") 653 (error "No previous #ifdef")))))
617 ))))
618
619 654
620 655
621 (defun down-ifdef () 656 (defun down-ifdef ()
622 "Move point to beginning of nested ifdef or else-part." 657 "Move point to beginning of nested ifdef or else-part."
623 (interactive) 658 (interactive)
624 (let ((start (point))) 659 (let ((start (point)))
625 (hif-find-next-relevant) 660 (hif-find-next-relevant)
626 (if (or (hif-looking-at-ifX) (hif-looking-at-else)) 661 (if (or (hif-looking-at-ifX) (hif-looking-at-else))
627 () 662 ()
628 (goto-char start) 663 (goto-char start)
629 (error "No following #ifdef") 664 (error "No following #ifdef"))))
630 )))
631 665
632 666
633 (defun up-ifdef () 667 (defun up-ifdef ()
634 "Move point to beginning of enclosing ifdef or else-part." 668 "Move point to beginning of enclosing ifdef or else-part."
635 (interactive) 669 (interactive)
638 (if (not (hif-looking-at-endif)) 672 (if (not (hif-looking-at-endif))
639 (hif-find-previous-relevant)) 673 (hif-find-previous-relevant))
640 (if (hif-looking-at-endif) 674 (if (hif-looking-at-endif)
641 (hif-endif-to-ifdef)) 675 (hif-endif-to-ifdef))
642 (if (= start (point)) 676 (if (= start (point))
643 (error "No previous #ifdef") 677 (error "No previous #ifdef"))))
644 )))
645 678
646 (defun next-ifdef (&optional arg) 679 (defun next-ifdef (&optional arg)
647 "Move to the beginning of the next #ifX, #else, or #endif. 680 "Move to the beginning of the next #ifX, #else, or #endif.
648 With argument, do this that many times." 681 With argument, do this that many times."
649 (interactive "p") 682 (interactive "p")
650 (or arg (setq arg 1)) 683 (or arg (setq arg 1))
651 (if (< arg 0) 684 (if (< arg 0)
652 (previous-ifdef (- arg))) 685 (previous-ifdef (- arg)))
653 (while (< 0 arg) 686 (while (< 0 arg)
654 (setq arg (1- arg)) 687 (setq arg (1- arg))
655 (hif-find-next-relevant) 688 (hif-find-next-relevant)
656 (if (eolp) 689 (if (eolp)
657 (progn 690 (progn
658 (beginning-of-line) 691 (beginning-of-line)
659 (error "No following #ifdefs, #elses, or #endifs") 692 (error "No following #ifdefs, #elses, or #endifs")))))
660 ))))
661 693
662 (defun previous-ifdef (&optional arg) 694 (defun previous-ifdef (&optional arg)
663 "Move to the beginning of the previous #ifX, #else, or #endif. 695 "Move to the beginning of the previous #ifX, #else, or #endif.
664 With argument, do this that many times." 696 With argument, do this that many times."
665 (interactive "p") 697 (interactive "p")
666 (or arg (setq arg 1)) 698 (or arg (setq arg 1))
667 (if (< arg 0) 699 (if (< arg 0)
668 (next-ifdef (- arg))) 700 (next-ifdef (- arg)))
669 (while (< 0 arg) 701 (while (< 0 arg)
670 (setq arg (1- arg)) 702 (setq arg (1- arg))
671 (let ((start (point))) 703 (let ((start (point)))
672 (hif-find-previous-relevant) 704 (hif-find-previous-relevant)
673 (if (= start (point)) 705 (if (= start (point))
674 (error "No previous #ifdefs, #elses, or #endifs") 706 (error "No previous #ifdefs, #elses, or #endifs")))))
675 ))))
676 707
677 708
678 ;===%%SF%% parsing (End) === 709 ;===%%SF%% parsing (End) ===
679 710
680 711
744 ;;; NOTE: If there's an #ifdef at the beginning of the file, we can't 775 ;;; NOTE: If there's an #ifdef at the beginning of the file, we can't
745 ;;; hide it. There's no previous newline to replace. If we added 776 ;;; hide it. There's no previous newline to replace. If we added
746 ;;; one, we'd throw off all the counts. Feh. 777 ;;; one, we'd throw off all the counts. Feh.
747 778
748 (defun hif-hide-line (point) 779 (defun hif-hide-line (point)
749 "Hide the line containing point. Does nothing if 780 "Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil."
750 hide-ifdef-lines is nil."
751 (if hide-ifdef-lines 781 (if hide-ifdef-lines
752 (save-excursion 782 (save-excursion
753 (goto-char point) 783 (goto-char point)
754 (let ((modp (buffer-modified-p))) 784 (let ((modp (buffer-modified-p)))
755 (unwind-protect 785 (unwind-protect
784 ;;; 814 ;;;
785 ;;; When hif-possibly-hide returns, point is at the end of the 815 ;;; When hif-possibly-hide returns, point is at the end of the
786 ;;; possibly-hidden range. 816 ;;; possibly-hidden range.
787 817
788 (defun hif-recurse-on (start end) 818 (defun hif-recurse-on (start end)
789 "Call hide-ifdef-guts after narrowing to end of START line and END 819 "Call `hide-ifdef-guts' after narrowing to end of START line and END line."
790 line."
791 (save-excursion 820 (save-excursion
792 (save-restriction 821 (save-restriction
793 (goto-char start) 822 (goto-char start)
794 (end-of-line) 823 (end-of-line)
795 (narrow-to-region (point) end) 824 (narrow-to-region (point) end)
796 (hide-ifdef-guts)))) 825 (hide-ifdef-guts))))
797 826
798 (defun hif-possibly-hide () 827 (defun hif-possibly-hide ()
799 "Called at #ifX expression, this hides those parts that should be 828 "Called at #ifX expression, this hides those parts that should be hidden.
800 hidden, according to judgement of hide-ifdef-evaluator." 829 It uses the judgement of `hide-ifdef-evaluator'."
801 ; (message "hif-possibly-hide") (sit-for 1) 830 ; (message "hif-possibly-hide") (sit-for 1)
802 (let ((test (hif-canonicalize)) 831 (let ((test (hif-canonicalize))
803 (range (hif-find-range))) 832 (range (hif-find-range)))
804 ; (message "test = %s" test) (sit-for 1) 833 ; (message "test = %s" test) (sit-for 1)
805 834
830 )) 859 ))
831 860
832 861
833 862
834 (defun hide-ifdef-guts () 863 (defun hide-ifdef-guts ()
835 "Does the work of hide-ifdefs, except for the work that's pointless 864 "Does most of the work of `hide-ifdefs'.
836 to redo on a recursive entry." 865 It does not do the work that's pointless to redo on a recursive entry."
837 ; (message "hide-ifdef-guts") 866 ; (message "hide-ifdef-guts")
838 (save-excursion 867 (save-excursion
839 (goto-char (point-min)) 868 (goto-char (point-min))
840 (while (hif-find-any-ifX) 869 (while (hif-find-any-ifX)
841 (hif-possibly-hide)))) 870 (hif-possibly-hide))))
843 ;===%%SF%% hide-ifdef-hiding (End) === 872 ;===%%SF%% hide-ifdef-hiding (End) ===
844 873
845 874
846 ;===%%SF%% exports (Start) === 875 ;===%%SF%% exports (Start) ===
847 876
877 ;;;###autoload
848 (defvar hide-ifdef-initially nil 878 (defvar hide-ifdef-initially nil
849 "*Non-nil if hide-ifdefs should be called when hide-ifdef-mode 879 "*Non-nil means call `hide-ifdefs' when Hide-Ifdef mode is first activated.")
850 is first activated.") 880
851 881 ;;;###autoload
852 (defvar hide-ifdef-hiding nil
853 "Non-nil if text might be hidden.")
854
855 (defvar hide-ifdef-read-only nil 882 (defvar hide-ifdef-read-only nil
856 "*Set to non-nil if you want buffer to be read-only while hiding text.") 883 "*Set to non-nil if you want buffer to be read-only while hiding text.")
857 884
858 (defvar hif-outside-read-only nil 885 (defvar hif-outside-read-only nil
859 "Internal variable. Saves the value of buffer-read-only while hiding.") 886 "Internal variable. Saves the value of `buffer-read-only' while hiding.")
860 887
888 ;;;###autoload
861 (defvar hide-ifdef-lines nil 889 (defvar hide-ifdef-lines nil
862 "*Set to t if you don't want to see the #ifX, #else, and #endif lines.") 890 "*Non-nil means hide the #ifX, #else, and #endif lines.")
863 891
864 (defun hide-ifdef-toggle-read-only () 892 (defun hide-ifdef-toggle-read-only ()
865 "Toggle hide-ifdef-read-only." 893 "Toggle hide-ifdef-read-only."
866 (interactive) 894 (interactive)
867 (setq hide-ifdef-read-only (not hide-ifdef-read-only)) 895 (setq hide-ifdef-read-only (not hide-ifdef-read-only))
868 (message "Hide-Read-Only %s" 896 (message "Hide-Read-Only %s"
869 (if hide-ifdef-read-only "ON" "OFF")) 897 (if hide-ifdef-read-only "ON" "OFF"))
870 (if hide-ifdef-hiding 898 (if hide-ifdef-hiding
871 (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only))) 899 (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)))
872 (hif-update-mode-line) 900 ;; XEmacs change
873 ) 901 (redraw-modeline))
874 902
875 (defun hide-ifdef-toggle-outside-read-only () 903 (defun hide-ifdef-toggle-outside-read-only ()
876 "Replacement for toggle-read-only within hide-ifdef-mode." 904 "Replacement for `toggle-read-only' within Hide-Ifdef mode."
877 (interactive) 905 (interactive)
878 (setq hif-outside-read-only (not hif-outside-read-only)) 906 (setq hif-outside-read-only (not hif-outside-read-only))
879 (message "Read only %s" 907 (message "Read only %s"
880 (if hif-outside-read-only "ON" "OFF")) 908 (if hif-outside-read-only "ON" "OFF"))
881 (setq buffer-read-only 909 (setq buffer-read-only
882 (or (and hide-ifdef-hiding hide-ifdef-read-only) 910 (or (and hide-ifdef-hiding hide-ifdef-read-only)
883 hif-outside-read-only) 911 hif-outside-read-only)
884 ) 912 )
885 (hif-update-mode-line) 913 ;; XEmacs change
886 ) 914 (redraw-modeline))
887 915
888 916
889 (defun hide-ifdef-define (var) 917 (defun hide-ifdef-define (var)
890 "Define a VAR so that #ifdef VAR would be included." 918 "Define a VAR so that #ifdef VAR would be included."
891 (interactive "SDefine what? ") 919 (interactive "SDefine what? ")
892 (hif-set-var var t) 920 (hif-set-var var 1)
893 (if hide-ifdef-hiding (hide-ifdefs))) 921 (if hide-ifdef-hiding (hide-ifdefs)))
894 922
895 (defun hide-ifdef-undef (var) 923 (defun hide-ifdef-undef (var)
896 "Undefine a VAR so that #ifdef VAR would not be included." 924 "Undefine a VAR so that #ifdef VAR would not be included."
897 (interactive "SUndefine what? ") 925 (interactive "SUndefine what? ")
898 (hif-set-var var nil) 926 (hif-set-var var nil)
899 (if hide-ifdef-hiding (hide-ifdefs))) 927 (if hide-ifdef-hiding (hide-ifdefs)))
900 928
901 929
902 (defun hide-ifdefs () 930 (defun hide-ifdefs (&optional nomsg)
903 "Hide the contents of some #ifdefs. Assume that defined symbols have 931 "Hide the contents of some #ifdefs.
904 been added to hide-ifdef-env. The text hidden is the text that would not 932 Assume that defined symbols have been added to `hide-ifdef-env'.
905 be included by the C preprocessor if it were given the file with those 933 The text hidden is the text that would not be included by the C
906 symbols defined. 934 preprocessor if it were given the file with those symbols defined.
907 935
908 Turn off hiding by calling show-ifdef." 936 Turn off hiding by calling `show-ifdefs'."
909 937
910 (interactive) 938 (interactive)
911 (message "Hiding...") 939 (message "Hiding...")
940 (setq hif-outside-read-only buffer-read-only)
912 (if (not hide-ifdef-mode) 941 (if (not hide-ifdef-mode)
913 (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode 942 (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode
914 (if hide-ifdef-hiding 943 (if hide-ifdef-hiding
915 (show-ifdefs)) ; Otherwise, deep confusion. 944 (show-ifdefs)) ; Otherwise, deep confusion.
916 (if buffer-read-only (toggle-read-only)) ; make it writable temporarily 945 (let ((inhibit-read-only t))
917 (setq selective-display t) 946 (setq selective-display t)
918 (setq hide-ifdef-hiding t) 947 (setq hide-ifdef-hiding t)
919 (hide-ifdef-guts) 948 (hide-ifdef-guts))
920 (if (or hide-ifdef-read-only hif-outside-read-only) 949 (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only))
921 (toggle-read-only) ; make it read only 950 (or nomsg
922 ) 951 (message "Hiding done")))
923 (message "Hiding done")
924 )
925 952
926 953
927 (defun show-ifdefs () 954 (defun show-ifdefs ()
928 "Cancel the effects of hide-ifdef. The contents of all #ifdefs is shown." 955 "Cancel the effects of `hide-ifdef': show the contents of all #ifdefs."
929 (interactive) 956 (interactive)
930 (if buffer-read-only (toggle-read-only)) ; make it writable temporarily 957 (setq buffer-read-only hif-outside-read-only)
931 (setq selective-display nil) ; defaults 958 (setq selective-display nil) ; defaults
932 (hif-show-all) 959 (let ((inhibit-read-only t))
933 (if hif-outside-read-only 960 (hif-show-all))
934 (toggle-read-only)) ; make it read only 961 (setq hide-ifdef-hiding nil))
935 (setq hide-ifdef-hiding nil)
936 )
937 962
938 963
939 (defun hif-find-ifdef-block () 964 (defun hif-find-ifdef-block ()
940 "Utilitiy for hide and show ifdef-block. Set top and bottom of ifdef block." 965 "Utility for hide and show `ifdef-block'.
966 Set top and bottom of ifdef block."
941 (let (max-bottom) 967 (let (max-bottom)
942 (save-excursion 968 (save-excursion
943 (beginning-of-line) 969 (beginning-of-line)
944 (if (not (or (hif-looking-at-else) (hif-looking-at-ifX))) 970 (if (not (or (hif-looking-at-else) (hif-looking-at-ifX)))
945 (up-ifdef)) 971 (up-ifdef))
946 (setq top (point)) 972 (setq top (point))
947 (hif-ifdef-to-endif) 973 (hif-ifdef-to-endif)
948 (setq max-bottom (1- (point))) 974 (setq max-bottom (1- (point))))
949 )
950 (save-excursion 975 (save-excursion
951 (beginning-of-line) 976 (beginning-of-line)
952 (if (not (hif-looking-at-endif)) 977 (if (not (hif-looking-at-endif))
953 (hif-find-next-relevant)) 978 (hif-find-next-relevant))
954 (while (hif-looking-at-ifX) 979 (while (hif-looking-at-ifX)
955 (hif-ifdef-to-endif) 980 (hif-ifdef-to-endif)
956 (hif-find-next-relevant) 981 (hif-find-next-relevant))
957 ) 982 (setq bottom (min max-bottom (1- (point)))))))
958 (setq bottom (min max-bottom (1- (point))))
959 ))
960 )
961 983
962 984
963 (defun hide-ifdef-block () 985 (defun hide-ifdef-block ()
964 "Hide the ifdef block (true or false part) enclosing or before the cursor." 986 "Hide the ifdef block (true or false part) enclosing or before the cursor."
965 (interactive) 987 (interactive)
966 (if (not hide-ifdef-mode) 988 (if (not hide-ifdef-mode)
967 (hide-ifdef-mode 1)) 989 (hide-ifdef-mode 1))
968 (if buffer-read-only (toggle-read-only))
969 (setq selective-display t) 990 (setq selective-display t)
970 (let (top bottom) 991 (let (top bottom (inhibit-read-only t))
971 (hif-find-ifdef-block) ; set top and bottom - dynamic scoping 992 (hif-find-ifdef-block) ; set top and bottom - dynamic scoping
972 (hide-ifdef-region top bottom) 993 (hide-ifdef-region top bottom)
973 (if hide-ifdef-lines 994 (if hide-ifdef-lines
974 (progn 995 (progn
975 (hif-hide-line top) 996 (hif-hide-line top)
976 (hif-hide-line (1+ bottom)))) 997 (hif-hide-line (1+ bottom))))
977 (setq hide-ifdef-hiding t) 998 (setq hide-ifdef-hiding t))
978 ) 999 (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)))
979 (if (or hide-ifdef-read-only hif-outside-read-only)
980 (toggle-read-only))
981 )
982 1000
983 1001
984 (defun show-ifdef-block () 1002 (defun show-ifdef-block ()
985 "Show the ifdef block (true or false part) enclosing or before the cursor." 1003 "Show the ifdef block (true or false part) enclosing or before the cursor."
986 (interactive) 1004 (interactive)
987 (let ((old-read-only buffer-read-only)) 1005 (let ((inhibit-read-only t))
988 (if old-read-only (toggle-read-only))
989 (if hide-ifdef-lines 1006 (if hide-ifdef-lines
990 (save-excursion 1007 (save-excursion
991 (beginning-of-line) 1008 (beginning-of-line)
992 (hif-show-ifdef-region (1- (point)) (progn (end-of-line) (point)))) 1009 (hif-show-ifdef-region (1- (point)) (progn (end-of-line) (point))))
993 1010
994 (let (top bottom) 1011 (let (top bottom)
995 (hif-find-ifdef-block) 1012 (hif-find-ifdef-block)
996 (hif-show-ifdef-region (1- top) bottom)) 1013 (hif-show-ifdef-region (1- top) bottom)))))
997 ) 1014
998 1015
999 ; restore read only status since we dont know if all is shown. 1016 ;;; definition alist support
1000 (if old-read-only (toggle-read-only))
1001 ))
1002
1003
1004
1005 ;;; defininition alist support
1006 1017
1007 (defvar hide-ifdef-define-alist nil 1018 (defvar hide-ifdef-define-alist nil
1008 "A global assoc list of pre-defined symbol lists") 1019 "A global assoc list of pre-defined symbol lists")
1009 1020
1010 (defun hif-compress-define-list (env) 1021 (defun hif-compress-define-list (env)
1015 (new-defs nil)) 1026 (new-defs nil))
1016 (while defs 1027 (while defs
1017 (if (car defs) 1028 (if (car defs)
1018 (setq new-defs (cons (car defs) new-defs))) 1029 (setq new-defs (cons (car defs) new-defs)))
1019 (setq defs (cdr defs))) 1030 (setq defs (cdr defs)))
1020 new-defs 1031 new-defs))
1021 ))
1022 1032
1023 (defun hide-ifdef-set-define-alist (name) 1033 (defun hide-ifdef-set-define-alist (name)
1024 "Set the association for NAME to hide-ifdef-env." 1034 "Set the association for NAME to `hide-ifdef-env'."
1025 (interactive "SSet define list: ") 1035 (interactive "SSet define list: ")
1026 (setq hide-ifdef-define-alist 1036 (setq hide-ifdef-define-alist
1027 (cons (cons name (hif-compress-define-list hide-ifdef-env)) 1037 (cons (cons name (hif-compress-define-list hide-ifdef-env))
1028 hide-ifdef-define-alist)) 1038 hide-ifdef-define-alist)))
1029 )
1030 1039
1031 (defun hide-ifdef-use-define-alist (name) 1040 (defun hide-ifdef-use-define-alist (name)
1032 "Set hide-ifdef-env to the define list specified by NAME." 1041 "Set `hide-ifdef-env' to the define list specified by NAME."
1033 (interactive "SUse define list: ") 1042 (interactive "SUse define list: ")
1034 (let ((define-list (assoc name hide-ifdef-define-alist))) 1043 (let ((define-list (assoc name hide-ifdef-define-alist)))
1035 (if define-list 1044 (if define-list
1036 (setq hide-ifdef-env 1045 (setq hide-ifdef-env
1037 (mapcar '(lambda (arg) (cons arg t)) 1046 (mapcar '(lambda (arg) (cons arg t))
1038 (cdr define-list))) 1047 (cdr define-list)))
1039 (error "No define list for %s" name)) 1048 (error "No define list for %s" name))
1040 (if hide-ifdef-hiding (hide-ifdefs)) 1049 (if hide-ifdef-hiding (hide-ifdefs))))
1041 ) 1050
1042 ) 1051 (provide 'hideif)
1043 1052
1044 ;===%%SF%% exports (End) === 1053 ;;; hideif.el ends here