diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2001-11-28 20:53:28 +0000 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2001-11-28 20:53:28 +0000 |
commit | 722fa77ffa6904adc811d120a239fdb8246adf73 (patch) | |
tree | ade438edd7c06394c76d1e455407daf28a3e8aa1 /lisp/progmodes/hideif.el | |
parent | 3055c5a456cb7a551d4132a55cf5711e7e218869 (diff) | |
download | emacs-722fa77ffa6904adc811d120a239fdb8246adf73.tar.gz |
(hif-end-of-line): New function.
(hide-ifdef-mode): Set line-move-ignore-invisible.
(hide-ifdef-region-internal): New function.
(hide-ifdef-region): Use it.
(hif-defined): Return an integer.
(hif-infix-to-prefix): Remove.
(hif-tokenize): Parse from the buffer rather than from a string.
Correctly tokenize integers. Use forward-comment.
(hif-expr): Use hif-or.
(hif-term): Use hif-and.
(hif-factor): Use hif-not. Handle numbers properly.
Don't require parenthesis around `defined's argument.
(hif-and, hif-or, hif-not): New funs.
(hif-canonicalize): Pass a region to hif-tokenize. Use hif-not.
(hif-hide-line): Don't hide the \n before the line.
(hif-possibly-hide): Correctly handle numeric evaluation results.
Diffstat (limited to 'lisp/progmodes/hideif.el')
-rw-r--r-- | lisp/progmodes/hideif.el | 192 |
1 files changed, 88 insertions, 104 deletions
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index 2e21af69340..dbcfd593ff4 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -206,6 +206,8 @@ how the hiding is done: (set (make-local-variable 'hide-ifdef-hiding) (default-value 'hide-ifdef-hiding)) (set (make-local-variable 'hif-outside-read-only) buffer-read-only) + (set (make-local-variable 'line-move-ignore-invisible) t) + (add-hook 'change-major-mode-hook (lambda () (hide-ifdef-mode -1))) (add-to-invisibility-spec '(hide-ifdef . t)) @@ -213,6 +215,7 @@ how the hiding is done: (hide-ifdefs) (show-ifdefs))) ;; else end hide-ifdef-mode + (kill-local-variable 'line-move-ignore-invisible) (if hide-ifdef-hiding (show-ifdefs)))) @@ -230,15 +233,23 @@ how the hiding is done: (hide-ifdefs t))) (add-hook 'after-revert-hook 'hif-after-revert-function) +(defun hif-end-of-line () + (end-of-line) + (while (= (logand 1 (skip-chars-backward "\\\\")) 1) + (end-of-line 2))) + +(defun hide-ifdef-region-internal (start end) + (remove-overlays start end 'invisible 'hide-ifdef) + (let ((o (make-overlay start end))) + (overlay-put o 'invisible 'hide-ifdef))) + (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." (save-excursion - (goto-char start) (end-of-line) (setq start (point)) - (goto-char end) (end-of-line) (setq end (point)) - (remove-overlays start end 'invisible 'hide-ifdef) - (let ((o (make-overlay start end))) - (overlay-put o 'invisible 'hide-ifdef)))) + (goto-char start) (hif-end-of-line) (setq start (point)) + (goto-char end) (hif-end-of-line) (setq end (point)) + (hide-ifdef-region-internal start end))) (defun hif-show-ifdef-region (start end) "Everything between START and END is made visible." @@ -271,13 +282,7 @@ that form should be displayed.") 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) - ) - + (if (assoc var hide-ifdef-env) 1 0)) ;;===%%SF%% evaluation (End) === @@ -299,71 +304,47 @@ that form should be displayed.") (defvar hif-token) (defvar hif-token-list) -(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))) - ;; pattern to match initial identifier, !, &&, ||, (, or ). ;; Added ==, + and -: garyo@avs.com 8/9/94 -(defconst hif-token-regexp "^\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)") -(defconst hif-end-of-comment "\\*/") - +(defconst hif-token-regexp + "\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)") -(defun hif-tokenize (expr-string) - "Separate string into a list of tokens." - (let ((token-list nil) - (expr-start 0) - (expr-length (length expr-string))) +(defun hif-tokenize (start end) + "Separate string between START and END into a list of tokens." + (let ((token-list nil)) (with-syntax-table hide-ifdef-syntax-table - (while (< expr-start expr-length) - ;; (message "expr-start = %d" expr-start) (sit-for 1) - (cond - ((string-match "^[ \t]+" expr-string expr-start) - ;; skip whitespace - (setq expr-start (match-end 0)) - ;; stick newline in string so ^ matches on the next string-match - (aset expr-string (1- expr-start) ?\n)) - - ((string-match "^/\\*" expr-string expr-start) - (setq expr-start (match-end 0)) - (aset expr-string (1- expr-start) ?\n) - (or - (string-match hif-end-of-comment - expr-string expr-start) ; eat comment - (string-match "$" expr-string expr-start)) ; multi-line comment - (setq expr-start (match-end 0)) - (aset expr-string (1- expr-start) ?\n)) - - ((string-match "^//" expr-string expr-start) - (string-match "$" expr-string expr-start) - (setq expr-start (match-end 0))) - - ((string-match hif-token-regexp expr-string expr-start) - (let ((token (substring expr-string expr-start (match-end 0)))) - (setq expr-start (match-end 0)) - (aset expr-string (1- expr-start) ?\n) - ;; (message "token: %s" token) (sit-for 1) - (push (cond - ((string-equal token "||") 'or) - ((string-equal token "&&") 'and) - ((string-equal token "==") 'equal) - ((string-equal token "!=") 'hif-notequal) - ((string-equal token "!") 'not) - ((string-equal token "defined") 'hif-defined) - ((string-equal token "(") 'lparen) - ((string-equal token ")") 'rparen) - ((string-equal token ">") 'hif-greater) - ((string-equal token "<") 'hif-less) - ((string-equal token ">=") 'hif-greater-equal) - ((string-equal token "<=") 'hif-less-equal) - ((string-equal token "+") 'hif-plus) - ((string-equal token "-") 'hif-minus) - (t (intern token))) - token-list))) - (t (error "Bad #if expression: %s" expr-string))))) + (save-excursion + (goto-char start) + (while (progn (forward-comment (point-max)) (< (point) end)) + ;; (message "expr-start = %d" expr-start) (sit-for 1) + (cond + ((looking-at "\\\\\n") + (forward-char 2)) + + ((looking-at hif-token-regexp) + (let ((token (buffer-substring (point) (match-end 0)))) + (goto-char (match-end 0)) + ;; (message "token: %s" token) (sit-for 1) + (push (cond + ((string-equal token "||") 'or) + ((string-equal token "&&") 'and) + ((string-equal token "==") 'equal) + ((string-equal token "!=") 'hif-notequal) + ((string-equal token "!") 'not) + ((string-equal token "defined") 'hif-defined) + ((string-equal token "(") 'lparen) + ((string-equal token ")") 'rparen) + ((string-equal token ">") 'hif-greater) + ((string-equal token "<") 'hif-less) + ((string-equal token ">=") 'hif-greater-equal) + ((string-equal token "<=") 'hif-less-equal) + ((string-equal token "+") 'hif-plus) + ((string-equal token "-") 'hif-minus) + ((string-match "\\`[0-9]*\\'" token) + (string-to-number token)) + (t (intern token))) + token-list))) + (t (error "Bad #if expression: %s" (buffer-string))))))) (nreverse token-list))) ;;;----------------------------------------------------------------- @@ -379,11 +360,9 @@ that form should be displayed.") (if hif-token ; is there still a token? (error "Error: unexpected token: %s" hif-token)))) -(defun hif-nexttoken () +(defsubst hif-nexttoken () "Pop the next token from token-list into the let variable \"hif-token\"." - (setq hif-token (car hif-token-list)) - (setq hif-token-list (cdr hif-token-list)) - hif-token) + (setq hif-token (pop hif-token-list))) (defun hif-expr () "Parse an expression as found in #if. @@ -391,7 +370,7 @@ that form should be displayed.") (let ((result (hif-term))) (while (eq hif-token 'or) (hif-nexttoken) - (setq result (list 'or result (hif-term)))) + (setq result (list 'hif-or result (hif-term)))) result)) (defun hif-term () @@ -399,7 +378,7 @@ that form should be displayed.") (let ((result (hif-eq-expr))) (while (eq hif-token 'and) (hif-nexttoken) - (setq result (list 'and result (hif-eq-expr)))) + (setq result (list 'hif-and result (hif-eq-expr)))) result)) (defun hif-eq-expr () @@ -418,7 +397,7 @@ that form should be displayed.") math : factor | math '+|-' factor." (let ((result (hif-factor)) (math-op nil)) - (while (or (eq hif-token 'hif-plus) (eq hif-token 'hif-minus)) + (while (memq hif-token '(hif-plus hif-minus)) (setq math-op hif-token) (hif-nexttoken) (setq result (list math-op result (hif-factor)))) @@ -429,7 +408,7 @@ that form should be displayed.") (cond ((eq hif-token 'not) (hif-nexttoken) - (list 'not (hif-factor))) + (list 'hif-not (hif-factor))) ((eq hif-token 'lparen) (hif-nexttoken) @@ -441,18 +420,20 @@ that form should be displayed.") ((eq hif-token 'hif-defined) (hif-nexttoken) - (if (not (eq hif-token 'lparen)) - (error "Error: expected \"(\" after \"defined\"")) - (hif-nexttoken) - (let ((ident hif-token)) + (let ((paren (when (eq hif-token 'lparen) (hif-nexttoken) t)) + (ident hif-token)) (if (memq hif-token '(or and not hif-defined lparen rparen)) (error "Error: unexpected token: %s" hif-token)) - (hif-nexttoken) - (unless (eq hif-token 'rparen) - (error "Error: expected \")\" after identifier")) + (when paren + (hif-nexttoken) + (unless (eq hif-token 'rparen) + (error "Error: expected \")\" after identifier"))) (hif-nexttoken) `(hif-defined (quote ,ident)))) + ((numberp hif-token) + (prog1 hif-token (hif-nexttoken))) + (t ; identifier (let ((ident hif-token)) (if (memq ident '(or and)) @@ -466,6 +447,12 @@ that form should be displayed.") ((null val) 0) (t val))) +(defun hif-and (a b) + (and (not (zerop (hif-mathify a))) (not (zerop (hif-mathify b))))) +(defun hif-or (a b) + (or (not (zerop (hif-mathify a))) (not (zerop (hif-mathify b))))) +(defun hif-not (a) + (zerop (hif-mathify a))) (defun hif-plus (a b) "Like ordinary plus but treat t and nil as 1 and 0." (+ (hif-mathify a) (hif-mathify b))) @@ -495,13 +482,12 @@ that form should be displayed.") (save-excursion (let ((negate (looking-at hif-ifndef-regexp))) (re-search-forward hif-ifx-regexp) - (let* ((expr-string - (buffer-substring (point) - (progn (skip-chars-forward "^\n\r") (point)))) - (expr (hif-infix-to-prefix (hif-tokenize expr-string)))) + (let* ((tokens (hif-tokenize (point) + (progn (hif-end-of-line) (point)))) + (expr (hif-parse-if-exp tokens))) ;; (message "hif-canonicalized: %s" expr) (if negate - (list 'not expr) + (list 'hif-not expr) expr))))) @@ -669,12 +655,12 @@ With argument, do this that many times." ;;; Only valid if ELSE-P is true. ;;; END The end of the range. (beginning of line) -(defun hif-make-range (start end &optional else) +(defsubst hif-make-range (start end &optional else) (list start else end)) -(defun hif-range-start (range) (elt range 0)) -(defun hif-range-else (range) (elt range 1)) -(defun hif-range-end (range) (elt range 2)) +(defsubst hif-range-start (range) (elt range 0)) +(defsubst hif-range-else (range) (elt range 1)) +(defsubst hif-range-end (range) (elt range 2)) @@ -716,16 +702,14 @@ Point is left unchanged." ;;; A bit slimy. -;;; NOTE: If there's an #ifdef at the beginning of the file, we can't -;;; hide it. There's no previous newline to replace. If we added -;;; one, we'd throw off all the counts. Feh. (defun hif-hide-line (point) "Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil." (if hide-ifdef-lines (save-excursion (goto-char point) - (hide-ifdef-region (line-end-position 0) (line-end-position))))) + (hide-ifdef-region-internal (line-beginning-position) + (progn (hif-end-of-line) (point)))))) ;;; Hif-Possibly-Hide @@ -769,10 +753,10 @@ It uses the judgement of `hide-ifdef-evaluator'." ;; (message "test = %s" test) (sit-for 1) (hif-hide-line (hif-range-end range)) - (if (funcall hide-ifdef-evaluator test) - (cond ((hif-range-else range) ; case 1 + (if (not (hif-not (funcall hide-ifdef-evaluator test))) + (cond ((hif-range-else range) ; case 1 (hif-hide-line (hif-range-else range)) - (hide-ifdef-region (hif-range-else range) + (hide-ifdef-region (hif-range-else range) (1- (hif-range-end range))) (hif-recurse-on (hif-range-start range) (hif-range-else range))) |