diff options
| author | Stefan Monnier | 2013-06-07 18:58:35 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-06-07 18:58:35 -0400 |
| commit | 544badc372a8babf42ac84d6a2e95dda2e75adef (patch) | |
| tree | 3cfc754801053e0a4a8008555b4ce86c13b0c06e | |
| parent | 04362df8bb3100c4b480b8b61630f810846bf321 (diff) | |
| download | emacs-544badc372a8babf42ac84d6a2e95dda2e75adef.tar.gz emacs-544badc372a8babf42ac84d6a2e95dda2e75adef.zip | |
* lisp/emacs-lisp/smie.el: Improve show-paren-mode behavior.
(smie--opener/closer-at-point): New function.
(smie--matching-block-data): Use it. Don't match from right after an
opener or right before a closer. Obey smie-blink-matching-inners.
Don't signal a mismatch for repeated inners like "switch..case..case".
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/emacs-lisp/smie.el | 138 |
2 files changed, 92 insertions, 54 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4ff6a28ae9c..863bcf0d2bc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-06-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/smie.el: Improve show-paren-mode behavior. | ||
| 4 | (smie--opener/closer-at-point): New function. | ||
| 5 | (smie--matching-block-data): Use it. Don't match from right after an | ||
| 6 | opener or right before a closer. Obey smie-blink-matching-inners. | ||
| 7 | Don't signal a mismatch for repeated inners like "switch..case..case". | ||
| 8 | |||
| 1 | 2013-06-07 Leo Liu <sdl.web@gmail.com> | 9 | 2013-06-07 Leo Liu <sdl.web@gmail.com> |
| 2 | 10 | ||
| 3 | * progmodes/octave.el (octave-mode): Set comment-use-global-state | 11 | * progmodes/octave.el (octave-mode): Set comment-use-global-state |
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index e97e9d066fd..f9d0fd9366b 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el | |||
| @@ -957,7 +957,7 @@ If non-nil, it will blink not only for \"begin..end\" but also for \"if...else\" | |||
| 957 | (let ((ender (funcall smie-backward-token-function))) | 957 | (let ((ender (funcall smie-backward-token-function))) |
| 958 | (cond | 958 | (cond |
| 959 | ((not (and ender (rassoc ender smie-closer-alist))) | 959 | ((not (and ender (rassoc ender smie-closer-alist))) |
| 960 | ;; This not is one of the begin..end we know how to check. | 960 | ;; This is not one of the begin..end we know how to check. |
| 961 | (blink-matching-check-mismatch start end)) | 961 | (blink-matching-check-mismatch start end)) |
| 962 | ((not start) t) | 962 | ((not start) t) |
| 963 | ((eq t (car (rassoc ender smie-closer-alist))) nil) | 963 | ((eq t (car (rassoc ender smie-closer-alist))) nil) |
| @@ -1012,6 +1012,9 @@ This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'. | |||
| 1012 | (or (eq (char-before) last-command-event) | 1012 | (or (eq (char-before) last-command-event) |
| 1013 | (not (memq (char-before) | 1013 | (not (memq (char-before) |
| 1014 | smie-blink-matching-triggers))) | 1014 | smie-blink-matching-triggers))) |
| 1015 | ;; FIXME: For octave's "switch ... case ... case" we flash | ||
| 1016 | ;; `switch' at the end of the first `case' and we burp | ||
| 1017 | ;; "mismatch" at the end of the second `case'. | ||
| 1015 | (or smie-blink-matching-inners | 1018 | (or smie-blink-matching-inners |
| 1016 | (not (numberp (nth 2 (assoc token smie-grammar)))))) | 1019 | (not (numberp (nth 2 (assoc token smie-grammar)))))) |
| 1017 | ;; The major mode might set blink-matching-check-function | 1020 | ;; The major mode might set blink-matching-check-function |
| @@ -1023,61 +1026,88 @@ This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'. | |||
| 1023 | 1026 | ||
| 1024 | (defvar-local smie--matching-block-data-cache nil) | 1027 | (defvar-local smie--matching-block-data-cache nil) |
| 1025 | 1028 | ||
| 1029 | (defun smie--opener/closer-at-point () | ||
| 1030 | "Return (OPENER TOKEN START END) or nil. | ||
| 1031 | OPENER is non-nil if TOKEN is an opener and nil if it's a closer." | ||
| 1032 | (let* ((start (point)) | ||
| 1033 | ;; Move to a previous position outside of a token. | ||
| 1034 | (_ (funcall smie-backward-token-function)) | ||
| 1035 | ;; Move to the end of the token before point. | ||
| 1036 | (btok (funcall smie-forward-token-function)) | ||
| 1037 | (bend (point))) | ||
| 1038 | (cond | ||
| 1039 | ;; Token before point is a closer? | ||
| 1040 | ((and (>= bend start) (rassoc btok smie-closer-alist)) | ||
| 1041 | (funcall smie-backward-token-function) | ||
| 1042 | (when (< (point) start) | ||
| 1043 | (prog1 (list nil btok (point) bend) | ||
| 1044 | (goto-char bend)))) | ||
| 1045 | ;; Token around point is an opener? | ||
| 1046 | ((and (> bend start) (assoc btok smie-closer-alist)) | ||
| 1047 | (funcall smie-backward-token-function) | ||
| 1048 | (when (<= (point) start) (list t btok (point) bend))) | ||
| 1049 | ((<= bend start) | ||
| 1050 | (let ((atok (funcall smie-forward-token-function)) | ||
| 1051 | (aend (point))) | ||
| 1052 | (cond | ||
| 1053 | ((< aend start) nil) ;Hopefully shouldn't happen. | ||
| 1054 | ;; Token after point is a closer? | ||
| 1055 | ((assoc atok smie-closer-alist) | ||
| 1056 | (funcall smie-backward-token-function) | ||
| 1057 | (when (<= (point) start) | ||
| 1058 | (list t atok (point) aend))))))))) | ||
| 1059 | |||
| 1026 | (defun smie--matching-block-data (orig &rest args) | 1060 | (defun smie--matching-block-data (orig &rest args) |
| 1027 | "A function suitable for `show-paren-data-function' (which see)." | 1061 | "A function suitable for `show-paren-data-function' (which see)." |
| 1028 | (when smie-closer-alist | 1062 | (if (or (null smie-closer-alist) |
| 1029 | (if (eq (point) (car smie--matching-block-data-cache)) | 1063 | (eq (point) (car smie--matching-block-data-cache))) |
| 1030 | (or (cdr smie--matching-block-data-cache) | 1064 | (or (cdr smie--matching-block-data-cache) |
| 1031 | (apply orig args)) | 1065 | (apply orig args)) |
| 1032 | (setq smie--matching-block-data-cache (list (point))) | 1066 | (setq smie--matching-block-data-cache (list (point))) |
| 1033 | (let* ((beg-of-tok | 1067 | (unless (nth 8 (syntax-ppss)) |
| 1034 | (lambda (&optional start) | 1068 | (condition-case nil |
| 1035 | "Move to the beginning of current token at START." | 1069 | (let ((here (smie--opener/closer-at-point))) |
| 1036 | (let* ((token) | 1070 | (when (and here |
| 1037 | (start (or start (point))) | 1071 | (or smie-blink-matching-inners |
| 1038 | (beg (progn | 1072 | (not (numberp |
| 1039 | (funcall smie-backward-token-function) | 1073 | (nth (if (nth 0 here) 1 2) |
| 1040 | (forward-comment (point-max)) | 1074 | (assoc (nth 1 here) smie-grammar)))))) |
| 1041 | (point))) | 1075 | (let ((there |
| 1042 | (end (progn | 1076 | (cond |
| 1043 | (setq token (funcall smie-forward-token-function)) | 1077 | ((car here) ; Opener. |
| 1044 | (forward-comment (- (point))) | 1078 | (let ((data (smie-forward-sexp 'halfsexp)) |
| 1045 | (point)))) | 1079 | (tend (point))) |
| 1046 | (if (and (<= beg start) (<= start end) | 1080 | (unless (car data) |
| 1047 | (or (assoc token smie-closer-alist) | 1081 | (funcall smie-backward-token-function) |
| 1048 | (rassoc token smie-closer-alist))) | 1082 | (list (member (cons (nth 1 here) (nth 2 data)) |
| 1049 | (progn (goto-char beg) (list token beg end)) | 1083 | smie-closer-alist) |
| 1050 | (goto-char start) | 1084 | (point) tend)))) |
| 1051 | nil)))) | 1085 | (t ;Closer. |
| 1052 | (tok-at-pt | 1086 | (let ((data (smie-backward-sexp 'halfsexp)) |
| 1053 | (lambda () | 1087 | (htok (nth 1 here))) |
| 1054 | (or (funcall beg-of-tok) | 1088 | (if (car data) |
| 1055 | (funcall beg-of-tok | 1089 | (let* ((hprec (nth 2 (assoc htok smie-grammar))) |
| 1056 | (prog1 (point) | 1090 | (ttok (nth 2 data)) |
| 1057 | (funcall smie-forward-token-function))))))) | 1091 | (tprec (nth 1 (assoc ttok smie-grammar)))) |
| 1058 | (unless (nth 8 (syntax-ppss)) | 1092 | (when (and (numberp hprec) ;Here is an inner. |
| 1059 | (condition-case nil | 1093 | (eq hprec tprec)) |
| 1060 | (let ((here (funcall tok-at-pt)) | 1094 | (goto-char (nth 1 data)) |
| 1061 | there pair) | 1095 | (let ((tbeg (point))) |
| 1062 | (when here | 1096 | (funcall smie-forward-token-function) |
| 1063 | (cond | 1097 | (list t tbeg (point))))) |
| 1064 | ((assoc (car here) smie-closer-alist) ; opener | 1098 | (let ((tbeg (point))) |
| 1065 | (forward-sexp 1) | 1099 | (funcall smie-forward-token-function) |
| 1066 | (setq there (funcall tok-at-pt)) | 1100 | (list (member (cons (nth 2 data) htok) |
| 1067 | (setq pair (cons (car here) (car there)))) | 1101 | smie-closer-alist) |
| 1068 | ((rassoc (car here) smie-closer-alist) ; closer | 1102 | tbeg (point))))))))) |
| 1069 | (funcall smie-forward-token-function) | 1103 | ;; Update the cache. |
| 1070 | (forward-sexp -1) | 1104 | (setcdr smie--matching-block-data-cache |
| 1071 | (setq there (funcall tok-at-pt)) | 1105 | (list (nth 2 here) (nth 3 here) |
| 1072 | (setq pair (cons (car there) (car here))))) | 1106 | (nth 1 there) (nth 2 there) |
| 1073 | ;; Update the cache | 1107 | (not (nth 0 there))))))) |
| 1074 | (setcdr smie--matching-block-data-cache | 1108 | (scan-error nil)) |
| 1075 | (list (nth 1 here) (nth 2 here) | 1109 | (goto-char (car smie--matching-block-data-cache))) |
| 1076 | (nth 1 there) (nth 2 there) | 1110 | (apply #'smie--matching-block-data orig args))) |
| 1077 | (not (member pair smie-closer-alist)))))) | ||
| 1078 | (scan-error)) | ||
| 1079 | (goto-char (car smie--matching-block-data-cache)))) | ||
| 1080 | (apply #'smie--matching-block-data orig args)))) | ||
| 1081 | 1111 | ||
| 1082 | ;;; The indentation engine. | 1112 | ;;; The indentation engine. |
| 1083 | 1113 | ||