aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-06-07 18:58:35 -0400
committerStefan Monnier2013-06-07 18:58:35 -0400
commit544badc372a8babf42ac84d6a2e95dda2e75adef (patch)
tree3cfc754801053e0a4a8008555b4ce86c13b0c06e
parent04362df8bb3100c4b480b8b61630f810846bf321 (diff)
downloademacs-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/ChangeLog8
-rw-r--r--lisp/emacs-lisp/smie.el138
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 @@
12013-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
12013-06-07 Leo Liu <sdl.web@gmail.com> 92013-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.
1031OPENER 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