📄 hideif.el
字号:
;;; hide-ifdef-mode.el Hides selected code within ifdef.;;;;;; Copyright (C) 1988 Brian Marick and Daniel LaLiberte;;; Written by Brian Marick, at Gould, Computer Systems Division, Urbana IL.;;; Extensively modified by Daniel LaLiberte (while at Gould).;;;;;; You may freely modify and distribute this, but keep a record;;; of modifications and send comments to:;;; liberte@a.cs.uiuc.edu or ihnp4!uiucdcs!liberte;;; I will continue to upgrade hide-ifdef-mode;;; with your contributions and will eventually offer it to FSF.;;;;;; $Header: hide-ifdef-mode.el,v 1.7 88/02/16 03:12:58 liberte Exp $;;;;;; $Log: hide-ifdef-mode.el,v $;;; Revision 1.7 88/02/16 03:12:58 liberte;;; Fixed comments and doc strings.;;; Added optional prefix arg for ifdef motion commands.;;; ;;; Revision 1.6 88/02/05 00:36:18 liberte;;; Bug fixes.;;; 1. A multi-line comment that starts on an #ifdef line;;; now ends on that line.;;; 2. Fix bad function name: hide-hif-ifdef-toggle-read-only;;; 3. Make ifdef-block hiding work outside of ifdefs.;;; ;;; Revision 1.5 88/01/31 23:19:31 liberte;;; Major clean up.;;; Prefix internal names with "hif-".;;; ;;; Revision 1.4 88/01/30 14:09:38 liberte;;; Add hide-ifdef-hiding and hide-ifdef-mode to minor-mode-alist.;;; ;;; Revision 1.3 88/01/29 00:38:19 liberte;;; Fix three bugs.;;; 1. Function "defined" is just like lookup.;;; 2. Skip to newline or cr in case text is hidden.;;; 3. Use car of token list if just one symbol.;;;;;; Revision 1.2 88/01/28 23:32:46 liberte;;; Use hide-ifdef-mode-prefix-key.;;; Copy current-local-map so other buffers do not get;;; hide-ifdef-mode bindings.;;;;;;--------------------------------------------------------------;;; To initialize, toggle the hide-ifdef minor mode with;;;;;; M-x hide-ifdef-mode;;;;;; This will set up key bindings and call hide-ifdef-mode-hook if it;;; has a value. To explicitly hide ifdefs using a buffer-local;;; define list (default empty), type;;;;;; M-x hide-ifdefs or C-c h;;;;;; Hide-ifdef suppresses the display of code that the preprocessor wouldn't;;; pass through. The support of constant expressions in #if lines is ;;; limited to identifiers, parens, and the operators: &&, ||, !, and;;; "defined". Please extend this.;;;;;; The hidden code is marked by ellipses (...). Be;;; cautious when editing near ellipses, since the hidden text is;;; still in the buffer, and you can move the point into it and modify;;; text unawares. If you don't want to see the ellipses, set ;;; selective-display-ellipses to nil. But this can be dangerous.;;; You can make your buffer read-only while hide-ifdef-hiding by setting;;; hide-ifdef-read-only to a non-nil value. You can toggle this ;;; variable with hide-ifdef-toggle-read-only (C-c C-q).;;;;;; You can undo the effect of hide-ifdefs by typing;;;;;; M-x show-ifdefs or C-c s;;;;;; Use M-x hide-ifdef-define (C-c d) to define a symbol.;;; Use M-x hide-ifdef-undef (C-c u) to undefine a symbol.;;;;;; If you define or undefine a symbol while hide-ifdef-mode is in effect,;;; the display will be updated. Only the define list for the current;;; buffer will be affected. You can save changes to the local define;;; list with hide-ifdef-set-define-alist. This adds entries ;;; to hide-ifdef-define-alist.;;;;;; If you have defined a hide-ifdef-mode-hook, you can set;;; up a list of symbols that may be used by hide-ifdefs as in the;;; following example:;;;;;; (setq hide-ifdef-mode-hook;;; '(lambda ();;; (if (not hide-ifdef-define-alist);;; (setq hide-ifdef-define-alist;;; '((list1 ONE TWO);;; (list2 TWO THREE);;; )));;; (hide-ifdef-use-define-alist 'list2) ; use list2 by default;;; ));;;;;; You can call hide-ifdef-use-define-alist (C-c u) at any time to specify;;; another list to use.;;;;;; To cause ifdefs to be hidden as soon as hide-ifdef-mode is called,;;; set hide-ifdef-initially to non-nil.;;;;;; If you set hide-ifdef-lines to t, hide-ifdefs hides all the #ifdef lines.;;; In the absence of highlighting, that might be a bad idea. If you set;;; hide-ifdef-lines to nil (the default), the surrounding preprocessor;;; lines will be displayed. That can be confusing in its own;;; right. Other variations on display are possible, but not much;;; better.;;;;;; You can explicitly hide or show individual ifdef blocks irrespective;;; of the define list by using hide-ifdef-block and show-ifdef-block.;;;;;; You can move the point between ifdefs with forward-ifdef, backward-ifdef,;;; up-ifdef, down-ifdef, next-ifdef, and previous-ifdef.;;;;;; If you have minor-mode-alist in your mode line (the default) two labels;;; may appear. "Ifdef" will appear when hide-ifdef-mode is active. "Hiding";;; will appear when text may be hidden ("hide-ifdef-hiding" is non-nil).(defvar hide-ifdef-mode-map nil "Keymap used with hide-ifdef mode")(defconst hide-ifdef-mode-prefix-key "\C-c" "Prefix key for all hide-ifdef-mode commands.")(defvar hide-ifdef-mode-map-before nil "Buffer-local variable to store a copy of the local keymap before hide-ifdef-mode modifies it.")(defun define-hide-ifdef-mode-map () (if hide-ifdef-mode-map () ; dont redefine it. (setq hide-ifdef-mode-map (make-sparse-keymap)) (define-key hide-ifdef-mode-map "d" 'hide-ifdef-define) (define-key hide-ifdef-mode-map "u" 'hide-ifdef-undef) (define-key hide-ifdef-mode-map "D" 'hide-ifdef-set-define-alist) (define-key hide-ifdef-mode-map "U" 'hide-ifdef-use-define-alist) (define-key hide-ifdef-mode-map "h" 'hide-ifdefs) (define-key hide-ifdef-mode-map "s" 'show-ifdefs) (define-key hide-ifdef-mode-map "\C-h" 'hide-ifdef-block) (define-key hide-ifdef-mode-map "\C-s" 'show-ifdef-block) (define-key hide-ifdef-mode-map "\C-f" 'forward-ifdef) (define-key hide-ifdef-mode-map "\C-b" 'backward-ifdef) (define-key hide-ifdef-mode-map "\C-d" 'down-ifdef) (define-key hide-ifdef-mode-map "\C-u" 'up-ifdef) (define-key hide-ifdef-mode-map "\C-n" 'next-ifdef) (define-key hide-ifdef-mode-map "\C-p" 'previous-ifdef) (define-key hide-ifdef-mode-map "\C-q" 'hide-ifdef-toggle-read-only) (define-key hide-ifdef-mode-map (where-is-internal 'toggle-read-only nil t) 'hide-ifdef-toggle-outside-read-only) ) (fset 'hide-ifdef-mode-map hide-ifdef-mode-map) ; the function is the map )(defun hif-update-mode-line () "Update mode-line by setting buffer-modified to itself." (set-buffer-modified-p (buffer-modified-p)))(defvar hide-ifdef-mode nil "non-nil when hide-ifdef-mode is activated.")(defvar hide-ifdef-hiding nil "non-nil when text may be hidden.")(or (assq 'hide-ifdef-hiding minor-mode-alist) (setq minor-mode-alist (cons '(hide-ifdef-hiding " Hiding") minor-mode-alist)))(or (assq 'hide-ifdef-mode minor-mode-alist) (setq minor-mode-alist (cons '(hide-ifdef-mode " Ifdef") minor-mode-alist)))(defun hide-ifdef-mode (arg) "Toggle hide-ifdef-mode. Thus this is a minor mode, albeit a large one.With arg, turn hide-ifdef-mode on iff arg is positive.In hide-ifdef-mode, code within #ifdef constructs that the C preprocessorwould eliminate may be hidden from view. Several variables affecthow the hiding is done:hide-ifdef-env An association list of defined and undefined symbols for the current buffer. Initially, the global value of hide-ifdef-env is used.hide-ifdef-define-alist An association list of defined symbol lists. Use hide-ifdef-set-define-alist to save the current hide-ifdef-env and hide-ifdef-use-define-alist to set the current hide-ifdef-env from one of the lists in hide-ifdef-define-alist.hide-ifdef-lines Set to non-nil to not show #if, #ifdef, #ifndef, #else, and #endif lines when hiding.hide-ifdef-initially Indicates whether hide-ifdefs should be called when hide-ifdef-mode is activated.hide-ifdef-read-only Set to non-nil if you want to make buffers read only while hiding. After show-ifdefs, read-only status is restored to previous value.\\{hide-ifdef-mode-map}" (interactive "P") (make-local-variable 'hide-ifdef-mode) (setq hide-ifdef-mode (if (null arg) (not hide-ifdef-mode) (> (prefix-numeric-value arg) 0))) (hif-update-mode-line) (if hide-ifdef-mode (progn ; fix c-mode syntax table so we can recognize whole symbols. (modify-syntax-entry ?_ "w") (modify-syntax-entry ?& ".") (modify-syntax-entry ?\| ".") ; inherit global values (make-local-variable 'hide-ifdef-env) (setq hide-ifdef-env (default-value 'hide-ifdef-env)) (make-local-variable 'hide-ifdef-hiding) (setq hide-ifdef-hiding (default-value 'hide-ifdef-hiding)) (make-local-variable 'hif-outside-read-only) (setq hif-outside-read-only buffer-read-only) (make-local-variable 'ide-ifdef-mode-map-before) (setq hide-ifdef-mode-map-before (current-local-map)) (use-local-map (copy-keymap (current-local-map))) (local-unset-key hide-ifdef-mode-prefix-key) (local-set-key hide-ifdef-mode-prefix-key 'hide-ifdef-mode-map) (define-hide-ifdef-mode-map) (run-hooks 'hide-ifdef-mode-hook) (if hide-ifdef-initially (hide-ifdefs) (show-ifdefs)) (message "Enter hide-ifdef-mode.") ) ; else end hide-ifdef-mode (if hide-ifdef-hiding (show-ifdefs)) (use-local-map hide-ifdef-mode-map-before) (message "Exit hide-ifdef-mode.") )) ;; from outline.el with docstring fixed.(defun hif-outline-flag-region (from to flag) "Hides or shows lines from FROM to TO, according to FLAG. If FLAGis \\n (newline character) then text is shown, while if FLAG is \\^M\(control-M) the text is hidden." (let ((modp (buffer-modified-p))) (unwind-protect (progn (subst-char-in-region from to (if (= flag ?\n) ?\^M ?\n) flag t) ) (set-buffer-modified-p modp)) ))(defun hif-show-all () "Show all of the text in the current buffer." (interactive) (hif-outline-flag-region (point-min) (point-max) ?\n))(defun hide-ifdef-region (start end) "START is the start of a #if or #else form. END is the ending part.Everything including these lines is made invisible." (hif-outline-flag-region start end ?\^M) )(defun hif-show-ifdef-region (start end) "Everything between START and END is made visible." (hif-outline-flag-region start end ?\n) );===%%SF%% evaluation (Start) ===(defvar hide-ifdef-evaluator 'eval "The evaluator is given a canonical form and returns T if text underthat form should be displayed.")(defvar hif-undefined-symbol nil "...is by default considered to be false.")(defvar hide-ifdef-env nil "An alist of defined symbols and their values.")(defun hif-set-var (var value) "Prepend (var value) pair to hide-ifdef-env." (setq hide-ifdef-env (cons (cons var value) hide-ifdef-env)))(defun hif-lookup (var); (message "hif-lookup %s" var) (let ((val (assoc var hide-ifdef-env))) (if val (cdr val) hif-undefined-symbol)))(defun hif-defined (var) (hif-lookup var) ; when #if expressions are fully supported, defined result should be 1 ; (if (assoc var hide-ifdef-env) ; 1 ; nil));===%%SF%% evaluation (End) ===;===%%SF%% parsing (Start) ===;;; The code that understands what ifs and ifdef in files look like.(defconst hif-cpp-prefix "\\(^\\|\r\\)[ \t]*#[ \t]*")(defconst hif-ifndef-regexp (concat hif-cpp-prefix "ifndef"))(defconst hif-ifx-regexp (concat hif-cpp-prefix "if\\(n?def\\)?[ \t]+"))(defconst hif-else-regexp (concat hif-cpp-prefix "else"))(defconst hif-endif-regexp (concat hif-cpp-prefix "endif"))(defconst hif-ifx-else-endif-regexp (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp))(defun hif-infix-to-prefix (token-list) "Convert list of tokens in infix into prefix list"; (message "hif-infix-to-prefix: %s" token-list) (if (= 1 (length token-list)) (` (hif-lookup (quote (, (car token-list))))) (hif-parse-if-exp token-list)) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -