diff options
| author | Stefan Monnier | 2010-09-18 02:35:00 +0200 |
|---|---|---|
| committer | Stefan Monnier | 2010-09-18 02:35:00 +0200 |
| commit | b879a6e2974d913d0c6dc1e290b2c246d7888b4f (patch) | |
| tree | f8d6bc12c185cf77892012bc4052efeb1f95fdc3 | |
| parent | 269c197ee9d1c3c0b8c03c278d76a570740dd624 (diff) | |
| download | emacs-b879a6e2974d913d0c6dc1e290b2c246d7888b4f.tar.gz emacs-b879a6e2974d913d0c6dc1e290b2c246d7888b4f.zip | |
Fix and improve last syntax-propertize patch
* lisp/emacs-lisp/syntax.el (syntax-propertize-precompile-rules): New macro.
(syntax-propertize-rules): Add var-ref case. Fix offset computation
when adding surrounding \(..\).
* lisp/progmodes/fortran.el (fortran--font-lock-syntactic-keywords): Remove.
(fortran-make-syntax-propertize-function): New function; replaces
fortran-font-lock-syntactic-keywords.
(fortran-mode): Use it.
(fortran-line-length): Use it. Improve interactive spec.
* lisp/progmodes/js.el (js-mode): Fix last change (bug#7054).
* lisp/textmodes/tex-mode.el (tex-syntax-propertize-rules)
(latex-syntax-propertize-rules): New consts; replace
tex-font-lock-syntactic-keywords.
(tex-env-mark, latex-env-before-change): New functions.
(latex-electric-env-pair-mode): New minor mode.
(tex-font-lock-verb): Change arguments; do move point.
(tex-font-lock-syntactic-face-function): Adjust to new verbatim
representation as a form of comment.
(tex-font-lock-keywords-1): Remove workaround, now unneeded.
(doctex-syntax-propertize-rules): New const; replaces
doctex-font-lock-syntactic-keywords.
(tex-common-initialization, doctex-mode): Use syntax-propertize-rules.
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | lisp/ChangeLog | 27 | ||||
| -rw-r--r-- | lisp/emacs-lisp/syntax.el | 48 | ||||
| -rw-r--r-- | lisp/progmodes/fortran.el | 69 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 2 | ||||
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 169 |
6 files changed, 220 insertions, 97 deletions
| @@ -236,6 +236,8 @@ kill ring). | |||
| 236 | 236 | ||
| 237 | * Changes in Specialized Modes and Packages in Emacs 24.1 | 237 | * Changes in Specialized Modes and Packages in Emacs 24.1 |
| 238 | 238 | ||
| 239 | ** latex-electric-env-pair-mode keeps \begin..\end matched on the fly. | ||
| 240 | |||
| 239 | ** FIXME: xdg-open for browse-url and reportbug, 2010/08. (Close bug#4546?) | 241 | ** FIXME: xdg-open for browse-url and reportbug, 2010/08. (Close bug#4546?) |
| 240 | 242 | ||
| 241 | ** Archive Mode has basic support to browse 7z archives. | 243 | ** Archive Mode has basic support to browse 7z archives. |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index df2a2315504..653822a86fd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | 2010-09-18 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * textmodes/tex-mode.el (tex-syntax-propertize-rules) | ||
| 4 | (latex-syntax-propertize-rules): New consts; replace | ||
| 5 | tex-font-lock-syntactic-keywords. | ||
| 6 | (tex-env-mark, latex-env-before-change): New functions. | ||
| 7 | (latex-electric-env-pair-mode): New minor mode. | ||
| 8 | (tex-font-lock-verb): Change arguments; do move point. | ||
| 9 | (tex-font-lock-syntactic-face-function): Adjust to new verbatim | ||
| 10 | representation as a form of comment. | ||
| 11 | (tex-font-lock-keywords-1): Remove workaround, now unneeded. | ||
| 12 | (doctex-syntax-propertize-rules): New const; replaces | ||
| 13 | doctex-font-lock-syntactic-keywords. | ||
| 14 | (tex-common-initialization, doctex-mode): Use syntax-propertize-rules. | ||
| 15 | |||
| 16 | * progmodes/fortran.el (fortran--font-lock-syntactic-keywords): Remove. | ||
| 17 | (fortran-make-syntax-propertize-function): New function; replaces | ||
| 18 | fortran-font-lock-syntactic-keywords. | ||
| 19 | (fortran-mode): Use it. | ||
| 20 | (fortran-line-length): Use it. Improve interactive spec. | ||
| 21 | |||
| 22 | * emacs-lisp/syntax.el (syntax-propertize-precompile-rules): New macro. | ||
| 23 | (syntax-propertize-rules): Add var-ref case. Fix offset computation | ||
| 24 | when adding surrounding \(..\). | ||
| 25 | |||
| 26 | * progmodes/js.el (js-mode): Fix last change (bug#7054). | ||
| 27 | |||
| 1 | 2010-09-17 Stefan Monnier <monnier@iro.umontreal.ca> | 28 | 2010-09-17 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 29 | ||
| 3 | * obsolete/old-whitespace.el (whitespace-rescan-files-in-buffers): | 30 | * obsolete/old-whitespace.el (whitespace-rescan-files-in-buffers): |
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index ad0166e7af0..b85399263d0 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el | |||
| @@ -57,7 +57,11 @@ | |||
| 57 | ;; syntax-ppss-flush-cache since that would not only flush the cache but also | 57 | ;; syntax-ppss-flush-cache since that would not only flush the cache but also |
| 58 | ;; reset syntax-propertize--done which should not be done in this case). | 58 | ;; reset syntax-propertize--done which should not be done in this case). |
| 59 | "Mode-specific function to apply the syntax-table properties. | 59 | "Mode-specific function to apply the syntax-table properties. |
| 60 | Called with 2 arguments: START and END.") | 60 | Called with 2 arguments: START and END. |
| 61 | This function can call `syntax-ppss' on any position before END, but it | ||
| 62 | should not call `syntax-ppss-flush-cache', which means that it should not | ||
| 63 | call `syntax-ppss' on some position and later modify the buffer on some | ||
| 64 | earlier position.") | ||
| 61 | 65 | ||
| 62 | (defvar syntax-propertize-chunk-size 500) | 66 | (defvar syntax-propertize-chunk-size 500) |
| 63 | 67 | ||
| @@ -109,15 +113,35 @@ Put first the functions more likely to cause a change and cheaper to compute.") | |||
| 109 | t t s 1)) | 113 | t t s 1)) |
| 110 | re t t)) | 114 | re t t)) |
| 111 | 115 | ||
| 116 | (defmacro syntax-propertize-precompile-rules (&rest rules) | ||
| 117 | "Return a precompiled form of RULES to pass to `syntax-propertize-rules'. | ||
| 118 | The arg RULES can be of the same form as in `syntax-propertize-rules'. | ||
| 119 | The return value is an object that can be passed as a rule to | ||
| 120 | `syntax-propertize-rules'. | ||
| 121 | I.e. this is useful only when you want to share rules among several | ||
| 122 | syntax-propertize-functions." | ||
| 123 | (declare (debug syntax-propertize-rules)) | ||
| 124 | ;; Precompile? Yeah, right! | ||
| 125 | ;; Seriously, tho, this is a macro for 2 reasons: | ||
| 126 | ;; - we could indeed do some pre-compilation at some point in the future, | ||
| 127 | ;; e.g. fi/when we switch to a DFA-based implementation of | ||
| 128 | ;; syntax-propertize-rules. | ||
| 129 | ;; - this lets Edebug properly annotate the expressions inside RULES. | ||
| 130 | `',rules) | ||
| 131 | |||
| 112 | (defmacro syntax-propertize-rules (&rest rules) | 132 | (defmacro syntax-propertize-rules (&rest rules) |
| 113 | "Make a function that applies RULES for use in `syntax-propertize-function'. | 133 | "Make a function that applies RULES for use in `syntax-propertize-function'. |
| 114 | The function will scan the buffer, applying the rules where they match. | 134 | The function will scan the buffer, applying the rules where they match. |
| 115 | The buffer is scanned a single time, like \"lex\" would, rather than once | 135 | The buffer is scanned a single time, like \"lex\" would, rather than once |
| 116 | per rule. | 136 | per rule. |
| 117 | 137 | ||
| 118 | Each rule has the form (REGEXP HIGHLIGHT1 ... HIGHLIGHTn), where REGEXP | 138 | Each RULE can be a symbol, in which case that symbol's value should be, |
| 119 | is an expression (evaluated at time of macro-expansion) that returns a regexp, | 139 | at macro-expansion time, a precompiled set of rules, as returned |
| 120 | and where HIGHLIGHTs have the form (NUMBER SYNTAX) which means to | 140 | by `syntax-propertize-precompile-rules'. |
| 141 | |||
| 142 | Otherwise, RULE should have the form (REGEXP HIGHLIGHT1 ... HIGHLIGHTn), where | ||
| 143 | REGEXP is an expression (evaluated at time of macro-expansion) that returns | ||
| 144 | a regexp, and where HIGHLIGHTs have the form (NUMBER SYNTAX) which means to | ||
| 121 | apply the property SYNTAX to the chars matched by the subgroup NUMBER | 145 | apply the property SYNTAX to the chars matched by the subgroup NUMBER |
| 122 | of the regular expression, if NUMBER did match. | 146 | of the regular expression, if NUMBER did match. |
| 123 | SYNTAX is an expression that returns a value to apply as `syntax-table' | 147 | SYNTAX is an expression that returns a value to apply as `syntax-table' |
| @@ -132,11 +156,18 @@ Also SYNTAX is free to move point, in which case RULES may not be applied to | |||
| 132 | some parts of the text or may be applied several times to other parts. | 156 | some parts of the text or may be applied several times to other parts. |
| 133 | 157 | ||
| 134 | Note: back-references in REGEXPs do not work." | 158 | Note: back-references in REGEXPs do not work." |
| 135 | (declare (debug (&rest (form &rest | 159 | (declare (debug (&rest &or symbolp ;FIXME: edebug this eval step. |
| 160 | (form &rest | ||
| 136 | (numberp | 161 | (numberp |
| 137 | [&or stringp | 162 | [&or stringp ;FIXME: Use &wrap |
| 138 | ("prog1" [&or stringp def-form] def-body) | 163 | ("prog1" [&or stringp def-form] def-body) |
| 139 | def-form]))))) | 164 | def-form]))))) |
| 165 | (let ((newrules nil)) | ||
| 166 | (while rules | ||
| 167 | (if (symbolp (car rules)) | ||
| 168 | (setq rules (append (symbol-value (pop rules)) rules)) | ||
| 169 | (push (pop rules) newrules))) | ||
| 170 | (setq rules (nreverse newrules))) | ||
| 140 | (let* ((offset 0) | 171 | (let* ((offset 0) |
| 141 | (branches '()) | 172 | (branches '()) |
| 142 | ;; We'd like to use a real DFA-based lexer, usually, but since Emacs | 173 | ;; We'd like to use a real DFA-based lexer, usually, but since Emacs |
| @@ -145,7 +176,8 @@ Note: back-references in REGEXPs do not work." | |||
| 145 | (re | 176 | (re |
| 146 | (mapconcat | 177 | (mapconcat |
| 147 | (lambda (rule) | 178 | (lambda (rule) |
| 148 | (let ((re (eval (car rule)))) | 179 | (let* ((orig-re (eval (car rule))) |
| 180 | (re orig-re)) | ||
| 149 | (when (and (assq 0 rule) (cdr rules)) | 181 | (when (and (assq 0 rule) (cdr rules)) |
| 150 | ;; If there's more than 1 rule, and the rule want to apply | 182 | ;; If there's more than 1 rule, and the rule want to apply |
| 151 | ;; highlight to match 0, create an extra group to be able to | 183 | ;; highlight to match 0, create an extra group to be able to |
| @@ -229,7 +261,7 @@ Note: back-references in REGEXPs do not work." | |||
| 229 | code)))) | 261 | code)))) |
| 230 | (push (cons condition (nreverse code)) | 262 | (push (cons condition (nreverse code)) |
| 231 | branches)) | 263 | branches)) |
| 232 | (incf offset (regexp-opt-depth re)) | 264 | (incf offset (regexp-opt-depth orig-re)) |
| 233 | re)) | 265 | re)) |
| 234 | rules | 266 | rules |
| 235 | "\\|"))) | 267 | "\\|"))) |
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index daa0fd07364..91cfb646b66 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el | |||
| @@ -483,19 +483,27 @@ The only difference is, it returns t in a case when the default returns nil." | |||
| 483 | "Maximum highlighting for Fortran mode. | 483 | "Maximum highlighting for Fortran mode. |
| 484 | Consists of level 3 plus all other intrinsics not already highlighted.") | 484 | Consists of level 3 plus all other intrinsics not already highlighted.") |
| 485 | 485 | ||
| 486 | (defvar fortran--font-lock-syntactic-keywords) | ||
| 487 | ;; Comments are real pain in Fortran because there is no way to | 486 | ;; Comments are real pain in Fortran because there is no way to |
| 488 | ;; represent the standard comment syntax in an Emacs syntax table. | 487 | ;; represent the standard comment syntax in an Emacs syntax table. |
| 489 | ;; (We can do so for F90-style). Therefore an unmatched quote in a | 488 | ;; (We can do so for F90-style). Therefore an unmatched quote in a |
| 490 | ;; standard comment will throw fontification off on the wrong track. | 489 | ;; standard comment will throw fontification off on the wrong track. |
| 491 | ;; So we do syntactic fontification with regexps. | 490 | ;; So we do syntactic fontification with regexps. |
| 492 | (defun fortran-font-lock-syntactic-keywords () | 491 | (defun fortran-make-syntax-propertize-function (line-length) |
| 493 | "Return a value for `font-lock-syntactic-keywords' in Fortran mode. | 492 | "Return a value for `syntax-propertize-function' in Fortran mode. |
| 494 | This varies according to the value of `fortran-line-length'. | 493 | This varies according to the value of LINE-LENGTH. |
| 495 | This is used to fontify fixed-format Fortran comments." | 494 | This is used to fontify fixed-format Fortran comments." |
| 496 | `(("^[cd\\*]" 0 (11)) | 495 | ;; This results in a non-byte-compiled function. We could pass it through |
| 497 | (,(format "^[^cd\\*\t\n].\\{%d\\}\\([^\n]+\\)" (1- fortran-line-length)) | 496 | ;; `byte-compile', but simple benchmarks indicate that it's probably not |
| 498 | 1 (11)))) | 497 | ;; worth the trouble (about ½% of slow down). |
| 498 | (eval ;I hate `eval', but it's hard to avoid it here. | ||
| 499 | `(syntax-propertize-rules | ||
| 500 | ("^[cd\\*]" (0 "<")) | ||
| 501 | ;; We mark all chars after line-length as "comment-start", rather than | ||
| 502 | ;; just the first one. This is so that a closing ' that's past the | ||
| 503 | ;; line-length will indeed be ignored (and will result in a string that | ||
| 504 | ;; leaks into subsequent lines). | ||
| 505 | ((format "^[^cd\\*\t\n].\\{%d\\}\\(.+\\)" (1- line-length)) | ||
| 506 | (1 "<"))))) | ||
| 499 | 507 | ||
| 500 | (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 | 508 | (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 |
| 501 | "Default expressions to highlight in Fortran mode.") | 509 | "Default expressions to highlight in Fortran mode.") |
| @@ -889,10 +897,8 @@ with no args, if that value is non-nil." | |||
| 889 | fortran-font-lock-keywords-4) | 897 | fortran-font-lock-keywords-4) |
| 890 | nil t ((?/ . "$/") ("_$" . "w")) | 898 | nil t ((?/ . "$/") ("_$" . "w")) |
| 891 | fortran-beginning-of-subprogram)) | 899 | fortran-beginning-of-subprogram)) |
| 892 | (set (make-local-variable 'fortran--font-lock-syntactic-keywords) | ||
| 893 | (fortran-make-syntax-propertize-function)) | ||
| 894 | (set (make-local-variable 'syntax-propertize-function) | 900 | (set (make-local-variable 'syntax-propertize-function) |
| 895 | (syntax-propertize-via-font-lock fortran--font-lock-syntactic-keywords)) | 901 | (fortran-make-syntax-propertize-function fortran-line-length)) |
| 896 | (set (make-local-variable 'imenu-case-fold-search) t) | 902 | (set (make-local-variable 'imenu-case-fold-search) t) |
| 897 | (set (make-local-variable 'imenu-generic-expression) | 903 | (set (make-local-variable 'imenu-generic-expression) |
| 898 | fortran-imenu-generic-expression) | 904 | fortran-imenu-generic-expression) |
| @@ -912,27 +918,30 @@ with no args, if that value is non-nil." | |||
| 912 | "Set the length of fixed-form Fortran lines to NCHARS. | 918 | "Set the length of fixed-form Fortran lines to NCHARS. |
| 913 | This normally only affects the current buffer, which must be in | 919 | This normally only affects the current buffer, which must be in |
| 914 | Fortran mode. If the optional argument GLOBAL is non-nil, it | 920 | Fortran mode. If the optional argument GLOBAL is non-nil, it |
| 915 | affects all Fortran buffers, and also the default." | 921 | affects all Fortran buffers, and also the default. |
| 916 | (interactive "p") | 922 | If a numeric prefix argument is specified, it will be used as NCHARS, |
| 917 | (let (new) | 923 | otherwise is a non-numeric prefix arg is specified, the length will be |
| 918 | (mapc (lambda (buff) | 924 | provided via the minibuffer, and otherwise the current column is used." |
| 919 | (with-current-buffer buff | 925 | (interactive |
| 920 | (when (eq major-mode 'fortran-mode) | 926 | (list (cond |
| 921 | (setq fortran-line-length nchars | 927 | ((numberp current-prefix-arg) current-prefix-arg) |
| 922 | fill-column fortran-line-length | 928 | (current-prefix-arg |
| 923 | new (fortran-make-syntax-propertize-function)) | 929 | (read-number "Line length: " (default-value 'fortran-line-length))) |
| 924 | ;; Refontify only if necessary. | 930 | (t (current-column))))) |
| 925 | (unless (equal new fortran--font-lock-syntactic-keywords) | 931 | (dolist (buff (if global |
| 926 | (setq fortran--font-lock-syntactic-keywords new) | 932 | (buffer-list) |
| 927 | (setq syntax-propertize-function | 933 | (list (current-buffer)))) |
| 928 | (syntax-propertize-via-font-lock new)) | 934 | (with-current-buffer buff |
| 929 | (syntax-ppss-flush-cache (point-min)) | 935 | (when (derived-mode-p 'fortran-mode) |
| 930 | (if font-lock-mode (font-lock-mode 1)))))) | 936 | (unless (eq fortran-line-length nchars) |
| 937 | (setq fortran-line-length nchars | ||
| 938 | fill-column fortran-line-length | ||
| 939 | syntax-propertize-function | ||
| 940 | (fortran-make-syntax-propertize-function nchars)) | ||
| 941 | (syntax-ppss-flush-cache (point-min)) | ||
| 942 | (if font-lock-mode (font-lock-mode 1)))))) | ||
| 931 | (if global | 943 | (if global |
| 932 | (buffer-list) | 944 | (setq-default fortran-line-length nchars))) |
| 933 | (list (current-buffer)))) | ||
| 934 | (if global | ||
| 935 | (setq-default fortran-line-length nchars)))) | ||
| 936 | 945 | ||
| 937 | (defun fortran-hack-local-variables () | 946 | (defun fortran-hack-local-variables () |
| 938 | "Fortran mode adds this to `hack-local-variables-hook'." | 947 | "Fortran mode adds this to `hack-local-variables-hook'." |
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index ba70bb8ecce..aeb2e91b6af 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -3304,7 +3304,7 @@ Key bindings: | |||
| 3304 | 3304 | ||
| 3305 | (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) | 3305 | (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) |
| 3306 | (set (make-local-variable 'font-lock-defaults) | 3306 | (set (make-local-variable 'font-lock-defaults) |
| 3307 | '(js--font-lock-keywords)) | 3307 | (list js--font-lock-keywords)) |
| 3308 | (set (make-local-variable 'syntax-propertize-function) | 3308 | (set (make-local-variable 'syntax-propertize-function) |
| 3309 | js-syntax-propertize-function) | 3309 | js-syntax-propertize-function) |
| 3310 | 3310 | ||
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 81a3816c1e8..c2d02dd9a4f 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el | |||
| @@ -488,10 +488,6 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 488 | ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) | 488 | ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) |
| 489 | (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) | 489 | (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
| 490 | (list | 490 | (list |
| 491 | ;; tex-font-lock-syntactic-keywords causes the \ of \end{verbatim} to be | ||
| 492 | ;; highlighted as tex-verbatim face. Let's undo that. | ||
| 493 | ;; This is ugly and brittle :-( --Stef | ||
| 494 | '("^\\(\\\\\\)end" (1 (get-text-property (match-end 1) 'face) t)) | ||
| 495 | ;; display $$ math $$ | 491 | ;; display $$ math $$ |
| 496 | ;; We only mark the match between $$ and $$ because the $$ delimiters | 492 | ;; We only mark the match between $$ and $$ because the $$ delimiters |
| 497 | ;; themselves have already been marked (along with $..$) by syntactic | 493 | ;; themselves have already been marked (along with $..$) by syntactic |
| @@ -642,29 +638,90 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 642 | (put 'tex-verbatim-environments 'safe-local-variable | 638 | (put 'tex-verbatim-environments 'safe-local-variable |
| 643 | (lambda (x) (null (delq t (mapcar 'stringp x))))) | 639 | (lambda (x) (null (delq t (mapcar 'stringp x))))) |
| 644 | 640 | ||
| 645 | (defvar tex-font-lock-syntactic-keywords | 641 | (eval-when-compile |
| 646 | '((eval . `(,(concat "^\\\\begin *{" | 642 | (defconst tex-syntax-propertize-rules |
| 647 | (regexp-opt tex-verbatim-environments t) | 643 | (syntax-propertize-precompile-rules |
| 648 | "}.*\\(\n\\)") 2 "|")) | ||
| 649 | ;; Technically, we'd like to put the "|" property on the \n preceding | ||
| 650 | ;; the \end, but this would have 2 disadvantages: | ||
| 651 | ;; 1 - it's wrong if the verbatim env is empty (the same \n is used to | ||
| 652 | ;; start and end the fenced-string). | ||
| 653 | ;; 2 - font-lock considers the preceding \n as being part of the | ||
| 654 | ;; preceding line, so things gets screwed every time the previous | ||
| 655 | ;; line is re-font-locked on its own. | ||
| 656 | ;; There's a hack in tex-font-lock-keywords-1 to remove the verbatim | ||
| 657 | ;; face from the \ but C-M-f still jumps to the wrong spot :-( --Stef | ||
| 658 | ;; FIXME: See gud.el for an example of a solution to a similar problem. | ||
| 659 | (eval . `(,(concat "^\\(\\\\\\)end *{" | ||
| 660 | (regexp-opt tex-verbatim-environments t) | ||
| 661 | "}\\(.?\\)") (1 "|") (3 "<"))) | ||
| 662 | ;; ("^\\(\\\\\\)begin *{comment}" 1 "< b") | ||
| 663 | ;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b") | ||
| 664 | ("\\\\verb\\**\\([^a-z@*]\\)" | 644 | ("\\\\verb\\**\\([^a-z@*]\\)" |
| 665 | ;; Do it last, because it uses syntax-ppss which needs the | 645 | (1 (prog1 "\"" |
| 666 | ;; syntax-table properties of previous entries. | 646 | (tex-font-lock-verb |
| 667 | 1 (tex-font-lock-verb (match-end 1))))) | 647 | (match-beginning 0) (char-after (match-beginning 1)))))))) |
| 648 | |||
| 649 | (defconst latex-syntax-propertize-rules | ||
| 650 | (syntax-propertize-precompile-rules | ||
| 651 | tex-syntax-propertize-rules | ||
| 652 | ("\\\\\\(?:end\\|begin\\) *\\({[^\n{}]*}\\)" | ||
| 653 | (1 (ignore | ||
| 654 | (tex-env-mark (match-beginning 0) | ||
| 655 | (match-beginning 1) (match-end 1)))))))) | ||
| 656 | |||
| 657 | (defun tex-env-mark (cmd start end) | ||
| 658 | (when (= cmd (line-beginning-position)) | ||
| 659 | (let ((arg (buffer-substring-no-properties (1+ start) (1- end)))) | ||
| 660 | (when (member arg tex-verbatim-environments) | ||
| 661 | (if (eq ?b (char-after (1+ cmd))) | ||
| 662 | ;; \begin | ||
| 663 | (put-text-property (line-end-position) | ||
| 664 | (line-beginning-position 2) | ||
| 665 | 'syntax-table (string-to-syntax "< c")) | ||
| 666 | ;; In the case of an empty verbatim env, the \n after the \begin is | ||
| 667 | ;; the same as the \n before the \end. Lucky for us, the "> c" | ||
| 668 | ;; property associated to the \end will be placed afterwards, so it | ||
| 669 | ;; will override the "< c". | ||
| 670 | (put-text-property (1- cmd) cmd | ||
| 671 | 'syntax-table (string-to-syntax "> c")) | ||
| 672 | ;; The text between \end{verbatim} and \n is ignored, so we'll treat | ||
| 673 | ;; it as a comment. | ||
| 674 | (put-text-property end (min (1+ end) (line-end-position)) | ||
| 675 | 'syntax-table (string-to-syntax "<")))))) | ||
| 676 | ;; Mark env args for possible electric pairing. | ||
| 677 | (unless (get-char-property (1+ start) 'text-clones) ;Already paired-up. | ||
| 678 | (put-text-property start end 'latex-env-pair t))) | ||
| 679 | |||
| 680 | (define-minor-mode latex-electric-env-pair-mode | ||
| 681 | "Automatically update the \\end arg when editing the \\begin one. | ||
| 682 | And vice-versa." | ||
| 683 | :lighter "/e" | ||
| 684 | (if latex-electric-env-pair-mode | ||
| 685 | (add-hook 'before-change-functions | ||
| 686 | #'latex-env-before-change nil 'local) | ||
| 687 | (remove-hook 'before-change-functions | ||
| 688 | #'latex-env-before-change 'local))) | ||
| 689 | |||
| 690 | (defun latex-env-before-change (start end) | ||
| 691 | (when (get-text-property start 'latex-env-pair) | ||
| 692 | (condition-case err | ||
| 693 | (with-silent-modifications | ||
| 694 | ;; Remove properties even if don't find a pair. | ||
| 695 | (remove-text-properties | ||
| 696 | (previous-single-property-change (1+ start) 'latex-env-pair) | ||
| 697 | (next-single-property-change start 'latex-env-pair) | ||
| 698 | '(latex-env-pair)) | ||
| 699 | (unless (or (get-char-property start 'text-clones) | ||
| 700 | (get-char-property (1+ start) 'text-clones) | ||
| 701 | (save-excursion | ||
| 702 | (goto-char start) | ||
| 703 | (not (re-search-backward | ||
| 704 | "\\\\\\(?:end\\|begi\\(n\\)\\) *{" | ||
| 705 | (line-beginning-position) t)))) | ||
| 706 | (let ((cmd-start (match-beginning 0)) | ||
| 707 | (type (match-end 1)) ;nil for \end, else \begin. | ||
| 708 | (arg-start (1- (match-end 0)))) | ||
| 709 | (save-excursion | ||
| 710 | (goto-char (match-end 0)) | ||
| 711 | (when (and (looking-at "[^\n{}]*}") | ||
| 712 | (> (match-end 0) end)) | ||
| 713 | (let ((arg-end (match-end 0))) | ||
| 714 | (if (null type) ;\end | ||
| 715 | (progn (goto-char arg-end) | ||
| 716 | (latex-forward-sexp -1) (forward-word 1)) | ||
| 717 | (goto-char cmd-start) | ||
| 718 | (latex-forward-sexp 1) | ||
| 719 | (let (forward-sexp-function) (backward-sexp))) | ||
| 720 | (when (looking-at | ||
| 721 | (regexp-quote (buffer-substring arg-start arg-end))) | ||
| 722 | (text-clone-create arg-start arg-end)))))))) | ||
| 723 | (scan-error nil) | ||
| 724 | (error (message "Error in latex-env-before-change: %s" err))))) | ||
| 668 | 725 | ||
| 669 | (defun tex-font-lock-unfontify-region (beg end) | 726 | (defun tex-font-lock-unfontify-region (beg end) |
| 670 | (font-lock-default-unfontify-region beg end) | 727 | (font-lock-default-unfontify-region beg end) |
| @@ -731,37 +788,32 @@ Not smaller than the value set by `tex-suscript-height-minimum'." | |||
| 731 | (define-obsolete-face-alias 'tex-verbatim-face 'tex-verbatim "22.1") | 788 | (define-obsolete-face-alias 'tex-verbatim-face 'tex-verbatim "22.1") |
| 732 | (defvar tex-verbatim-face 'tex-verbatim) | 789 | (defvar tex-verbatim-face 'tex-verbatim) |
| 733 | 790 | ||
| 734 | (defun tex-font-lock-verb (end) | 791 | (defun tex-font-lock-verb (start delim) |
| 735 | "Place syntax-table properties on the \verb construct. | 792 | "Place syntax table properties on the \verb construct. |
| 736 | END is the position of the first delimiter after \verb." | 793 | START is the position of the \\ and DELIM is the delimiter char." |
| 737 | (unless (nth 8 (syntax-ppss end)) | ||
| 738 | ;; Do nothing if the \verb construct is itself inside a comment or | 794 | ;; Do nothing if the \verb construct is itself inside a comment or |
| 739 | ;; verbatim env. | 795 | ;; verbatim env. |
| 740 | (save-excursion | 796 | (unless (nth 8 (save-excursion (syntax-ppss start))) |
| 741 | ;; Let's find the end and mark it. | 797 | ;; Let's find the end and mark it. |
| 742 | ;; We used to do it inside tex-font-lock-syntactic-face-function, but | 798 | ;; This may span more than a single line, but we don't bother |
| 743 | ;; this leads to funny effects when jumping to the end of the buffer, | 799 | ;; placing a syntax-multiline property since such multiline verbs aren't |
| 744 | ;; because font-lock applies font-lock-syntactic-keywords to the whole | 800 | ;; valid anyway. |
| 745 | ;; preceding text but font-lock-syntactic-face-function only to the | 801 | (skip-chars-forward (string ?^ delim)) |
| 746 | ;; actually displayed text. | ||
| 747 | (goto-char end) | ||
| 748 | (let ((char (char-before))) | ||
| 749 | (skip-chars-forward (string ?^ char)) ;; Use `end' ? | ||
| 750 | (when (eq (char-syntax (preceding-char)) ?/) | ||
| 751 | (put-text-property (1- (point)) (point) 'syntax-table '(1))) | ||
| 752 | (unless (eobp) | 802 | (unless (eobp) |
| 753 | (put-text-property (point) (1+ (point)) 'syntax-table '(7)) | 803 | (when (eq (char-syntax (preceding-char)) ?/) |
| 754 | ;; Cause the rest of the buffer to be re-fontified. | 804 | (put-text-property (1- (point)) (point) |
| 755 | ;; (remove-text-properties (1+ (point)) (point-max) '(fontified)) | 805 | 'syntax-table (string-to-syntax "."))) |
| 756 | ))) | 806 | (put-text-property (point) (1+ (point)) |
| 757 | "\"")) | 807 | 'syntax-table (string-to-syntax "\""))))) |
| 758 | 808 | ||
| 759 | ;; Use string syntax but math face for $...$. | 809 | ;; Use string syntax but math face for $...$. |
| 760 | (defun tex-font-lock-syntactic-face-function (state) | 810 | (defun tex-font-lock-syntactic-face-function (state) |
| 761 | (let ((char (nth 3 state))) | 811 | (let ((char (nth 3 state))) |
| 762 | (cond | 812 | (cond |
| 763 | ((not char) font-lock-comment-face) | 813 | ((not char) |
| 814 | (if (eq 2 (nth 7 state)) tex-verbatim-face font-lock-comment-face)) | ||
| 764 | ((eq char ?$) tex-math-face) | 815 | ((eq char ?$) tex-math-face) |
| 816 | ;; A \verb element. | ||
| 765 | (t tex-verbatim-face)))) | 817 | (t tex-verbatim-face)))) |
| 766 | 818 | ||
| 767 | 819 | ||
| @@ -1166,7 +1218,7 @@ Entering SliTeX mode runs the hook `text-mode-hook', then the hook | |||
| 1166 | (font-lock-unfontify-region-function | 1218 | (font-lock-unfontify-region-function |
| 1167 | . tex-font-lock-unfontify-region))) | 1219 | . tex-font-lock-unfontify-region))) |
| 1168 | (set (make-local-variable 'syntax-propertize-function) | 1220 | (set (make-local-variable 'syntax-propertize-function) |
| 1169 | (syntax-propertize-via-font-lock tex-font-lock-syntactic-keywords)) | 1221 | (syntax-propertize-rules latex-syntax-propertize-rules)) |
| 1170 | ;; TABs in verbatim environments don't do what you think. | 1222 | ;; TABs in verbatim environments don't do what you think. |
| 1171 | (set (make-local-variable 'indent-tabs-mode) nil) | 1223 | (set (make-local-variable 'indent-tabs-mode) nil) |
| 1172 | ;; Other vars that should be buffer-local. | 1224 | ;; Other vars that should be buffer-local. |
| @@ -2812,15 +2864,15 @@ There might be text before point." | |||
| 2812 | ;; syntax-table can't deal with. We could turn it | 2864 | ;; syntax-table can't deal with. We could turn it |
| 2813 | ;; into a non-comment, or use `\n%' or `%^' as the comment. | 2865 | ;; into a non-comment, or use `\n%' or `%^' as the comment. |
| 2814 | ;; Instead, we include it in the ^^A comment. | 2866 | ;; Instead, we include it in the ^^A comment. |
| 2815 | (eval-when-compile (string-to-syntax "< b")) | 2867 | (string-to-syntax "< b") |
| 2816 | (eval-when-compile (string-to-syntax ">")))) | 2868 | (string-to-syntax ">"))) |
| 2817 | (let ((end (line-end-position))) | 2869 | (let ((end (line-end-position))) |
| 2818 | (if (< end (point-max)) | 2870 | (if (< end (point-max)) |
| 2819 | (put-text-property | 2871 | (put-text-property |
| 2820 | end (1+ end) | 2872 | end (1+ end) |
| 2821 | 'syntax-table | 2873 | 'syntax-table |
| 2822 | (eval-when-compile (string-to-syntax "> b"))))) | 2874 | (string-to-syntax "> b")))) |
| 2823 | (eval-when-compile (string-to-syntax "< b"))))) | 2875 | (string-to-syntax "< b")))) |
| 2824 | 2876 | ||
| 2825 | (defun doctex-font-lock-syntactic-face-function (state) | 2877 | (defun doctex-font-lock-syntactic-face-function (state) |
| 2826 | ;; Mark DocTeX documentation, which is parsed as a style A comment | 2878 | ;; Mark DocTeX documentation, which is parsed as a style A comment |
| @@ -2832,11 +2884,12 @@ There might be text before point." | |||
| 2832 | (tex-font-lock-syntactic-face-function state) | 2884 | (tex-font-lock-syntactic-face-function state) |
| 2833 | font-lock-doc-face)) | 2885 | font-lock-doc-face)) |
| 2834 | 2886 | ||
| 2835 | (defvar doctex-font-lock-syntactic-keywords | 2887 | (eval-when-compile |
| 2836 | (append | 2888 | (defconst doctex-syntax-propertize-rules |
| 2837 | tex-font-lock-syntactic-keywords | 2889 | (syntax-propertize-precompile-rules |
| 2838 | ;; For DocTeX comment-in-doc. | 2890 | latex-syntax-propertize-rules |
| 2839 | `(("\\(\\^\\)\\^A" (1 (doctex-font-lock-^^A)))))) | 2891 | ;; For DocTeX comment-in-doc. |
| 2892 | ("\\(\\^\\)\\^A" (1 (doctex-font-lock-^^A)))))) | ||
| 2840 | 2893 | ||
| 2841 | (defvar doctex-font-lock-keywords | 2894 | (defvar doctex-font-lock-keywords |
| 2842 | (append tex-font-lock-keywords | 2895 | (append tex-font-lock-keywords |
| @@ -2855,7 +2908,7 @@ There might be text before point." | |||
| 2855 | (t x))) | 2908 | (t x))) |
| 2856 | (cdr font-lock-defaults)))) | 2909 | (cdr font-lock-defaults)))) |
| 2857 | (set (make-local-variable 'syntax-propertize-function) | 2910 | (set (make-local-variable 'syntax-propertize-function) |
| 2858 | (syntax-propertize-via-font-lock doctex-font-lock-syntactic-keywords))) | 2911 | (syntax-propertize-rules doctex-syntax-propertize-rules))) |
| 2859 | 2912 | ||
| 2860 | (run-hooks 'tex-mode-load-hook) | 2913 | (run-hooks 'tex-mode-load-hook) |
| 2861 | 2914 | ||