📄 hideif.el
字号:
; pattern to match initial identifier, !, &&, ||, (, or ).(defconst hif-token-regexp "^\\(!\\|&&\\|||\\|[()]\\|\\w+\\)")(defconst hif-end-of-comment "\\*/")(defun hif-tokenize (expr-string) "Separate string into a list of tokens" (let ((token-list nil) (expr-start 0) (expr-length (length expr-string))) (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 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) (setq token-list (cons (cond ((string-equal token "||") 'or) ((string-equal token "&&") 'and) ((string-equal token "!") 'not) ((string-equal token "defined") 'hif-defined) ((string-equal token "(") 'lparen) ((string-equal token ")") 'rparen) (t (intern token))) token-list)) )) (t (error "Bad #if expression: %s" expr-string)) )) (nreverse token-list) ));;;-----------------------------------------------------------------;;; Translate C preprocessor #if expressions using recursive descent.;;; This parser is limited to the operators &&, ||, !, and "defined".(defun hif-parse-if-exp (token-list) "Parse the TOKEN-LIST. Return translated list in prefix form." (hif-nexttoken) (prog1 (hif-expr) (if token ; is there still a token? (error "Error: unexpected token: %s" token))) )(defun hif-nexttoken () "Pop the next token from token-list into the let variable \"token\"." (setq token (car token-list)) (setq token-list (cdr token-list)) token )(defun hif-expr () "Parse and expression of the form expr : term | expr '||' term." (let ((result (hif-term))) (while (eq token 'or) (hif-nexttoken) (setq result (list 'or result (hif-term)))) result ))(defun hif-term () "Parse a term of the form term : factor | term '&&' factor." (let ((result (hif-factor))) (while (eq token 'and) (hif-nexttoken) (setq result (list 'and result (hif-factor)))) result ))(defun hif-factor () "Parse a factor of the form factor : '!' factor | '(' expr ')' | 'defined(' id ')' | id." (cond ((eq token 'not) (hif-nexttoken) (list 'not (hif-factor))) ((eq token 'lparen) (hif-nexttoken) (let ((result (hif-expr))) (if (not (eq token 'rparen)) (error "Bad token in parenthesized expression: %s" token) (hif-nexttoken) result))) ((eq token 'hif-defined) (hif-nexttoken) (if (not (eq token 'lparen)) (error "Error: expected \"(\" after \"define\"")) (hif-nexttoken) (let ((ident token)) (if (memq token '(or and not hif-defined lparen rparen)) (error "Error: unexpected token: %s" token)) (hif-nexttoken) (if (not (eq token 'rparen)) (error "Error: expected \")\" after identifier")) (hif-nexttoken) (` (hif-defined (quote (, ident)))) )) (t ; identifier (let ((ident token)) (if (memq ident '(or and)) (error "Error: missing identifier")) (hif-nexttoken) (` (hif-lookup (quote (, ident)))) )) ));;;----------- end of parser -----------------------(defun hif-canonicalize () "When at beginning of #ifX, returns a canonical (evaluatable) form for the expression." (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)))); (message "hif-canonicalized: %s" expr) (if negate (list 'not expr) expr)))))(defun hif-find-any-ifX () "Position at beginning of next #if, #ifdef, or #ifndef, including one onthis line."; (message "find ifX at %d" (point)) (prog1 (re-search-forward hif-ifx-regexp (point-max) t) (beginning-of-line)))(defun hif-find-next-relevant () "Position at beginning of next #ifdef, #ifndef, #else, #endif,NOT including one on this line."; (message "hif-find-next-relevant at %d" (point)) (end-of-line) ; avoid infinite recursion by only going to beginning of line if match found (if (re-search-forward hif-ifx-else-endif-regexp (point-max) t) (beginning-of-line)) )(defun hif-find-previous-relevant () "Position at beginning of previous #ifdef, #ifndef, #else, #endif,NOT including one on this line."; (message "hif-find-previous-relevant at %d" (point)) (beginning-of-line) ; avoid infinite recursion by only going to beginning of line if match found (if (re-search-backward hif-ifx-else-endif-regexp (point-min) t) (beginning-of-line) ) )(defun hif-looking-at-ifX () ;; Should eventually see #if (looking-at hif-ifx-regexp))(defun hif-looking-at-endif () (looking-at hif-endif-regexp))(defun hif-looking-at-else () (looking-at hif-else-regexp))(defun hif-ifdef-to-endif () "If positioned at #ifX or #else form, skip to corresponding #endif."; (message "hif-ifdef-to-endif at %d" (point)) (sit-for 1) (hif-find-next-relevant) (cond ((hif-looking-at-ifX) (hif-ifdef-to-endif) ; find endif of nested if (hif-ifdef-to-endif)) ; find outer endif or else ((hif-looking-at-else) (hif-ifdef-to-endif)) ; find endif following else ((hif-looking-at-endif) 'done) (t (error "Missmatched #ifdef #endif pair")) ))(defun hif-endif-to-ifdef () "If positioned at #endif form, skip backward to corresponding #ifX."; (message "hif-endif-to-ifdef at %d" (point)) (let ((start (point))) (hif-find-previous-relevant) (if (= start (point)) (error "Missmatched #ifdef #endif pair"))) (cond ((hif-looking-at-endif) (hif-endif-to-ifdef) ; find beginning of nested if (hif-endif-to-ifdef)) ; find beginning of outer if or else ((hif-looking-at-else) (hif-endif-to-ifdef)) ((hif-looking-at-ifX) 'done) (t ; never gets here )))(defun forward-ifdef (&optional arg) "Move point to beginning of line of the next ifdef-endif. With argument, do this that many times." (interactive "p") (or arg (setq arg 1)) (if (< arg 0) (backward-ifdef (- arg))) (while (< 0 arg) (setq arg (- arg)) (let ((start (point))) (if (not (hif-looking-at-ifX)) (hif-find-next-relevant)) (if (hif-looking-at-ifX) (hif-ifdef-to-endif) (goto-char start) (error "No following #ifdef") ))))(defun backward-ifdef (&optional arg) "Move point to beginning of the previous ifdef-endif. With argument, do this that many times." (interactive "p") (or arg (setq arg 1)) (if (< arg 0) (forward-ifdef (- arg))) (while (< 0 arg) (setq arg (1- arg)) (beginning-of-line) (let ((start (point))) (if (not (hif-looking-at-endif)) (hif-find-previous-relevant)) (if (hif-looking-at-endif) (hif-endif-to-ifdef) (goto-char start) (error "No previous #ifdef") ))))(defun down-ifdef () "Move point to beginning of nested ifdef or else-part." (interactive) (let ((start (point))) (hif-find-next-relevant) (if (or (hif-looking-at-ifX) (hif-looking-at-else)) () (goto-char start) (error "No following #ifdef") )))(defun up-ifdef () "Move point to beginning of enclosing ifdef or else-part." (interactive) (beginning-of-line) (let ((start (point))) (if (not (hif-looking-at-endif)) (hif-find-previous-relevant)) (if (hif-looking-at-endif) (hif-endif-to-ifdef)) (if (= start (point)) (error "No previous #ifdef") )))(defun next-ifdef (&optional arg) "Move to the beginning of the next #ifX, #else, or #endif. With argument, do this that many times." (interactive "p") (or arg (setq arg 1)) (if (< arg 0) (previous-ifdef (- arg))) (while (< 0 arg) (setq arg (1- arg)) (hif-find-next-relevant) (if (eolp) (progn (beginning-of-line) (error "No following #ifdefs, #elses, or #endifs") ))))(defun previous-ifdef (&optional arg) "Move to the beginning of the previous #ifX, #else, or #endif. With argument, do this that many times." (interactive "p") (or arg (setq arg 1)) (if (< arg 0) (next-ifdef (- arg))) (while (< 0 arg) (setq arg (1- arg)) (let ((start (point))) (hif-find-previous-relevant) (if (= start (point)) (error "No previous #ifdefs, #elses, or #endifs") ))));===%%SF%% parsing (End) ===;===%%SF%% hide-ifdef-hiding (Start) ===;;; A range is a structure with four components:;;; ELSE-P True if there was an else clause for the ifdef.;;; START The start of the range. (beginning of line);;; ELSE The else marker (beginning of line);;; Only valid if ELSE-P is true.;;; END The end of the range. (beginning of line)(defun hif-make-range (else-p start end &optional else) (list else-p start else end))(defun hif-range-else-p (range) (elt range 0))(defun hif-range-start (range) (elt range 1))(defun hif-range-else (range) (elt range 2))(defun hif-range-end (range) (elt range 3))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -