aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/emacs-lisp/smie.el96
2 files changed, 63 insertions, 41 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c1e446c3138..0ba7c673857 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,13 @@
12010-11-17 Stefan Monnier <monnier@iro.umontreal.ca> 12010-11-17 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/smie.el (smie-bnf-classify): Signal errors for tokens
4 that are both openers (resp. closers) and something else.
5 (smie-grammar): Loosen definition of valid values.
6 (smie-next-sexp, smie-down-list, smie-blink-matching-open)
7 (smie-indent--parent, smie-rule-parent, smie-indent-keyword)
8 (smie-indent-after-keyword): Adjust users.
9 (smie-indent-keyword): Don't indent empty lines.
10
3 * vc-hg.el (vc-hg-program): New var. 11 * vc-hg.el (vc-hg-program): New var.
4 Suggested by Norman Gray <norman@astro.gla.ac.uk>. 12 Suggested by Norman Gray <norman@astro.gla.ac.uk>.
5 (vc-hg-state, vc-hg-working-revision, vc-hg-command): Use it. 13 (vc-hg-state, vc-hg-working-revision, vc-hg-command): Use it.
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index 09095521b49..179e0a9f094 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -353,6 +353,7 @@ from the table, e.g. the table will not include things like (\"if\" . \"else\").
353 "Return a table classifying terminals. 353 "Return a table classifying terminals.
354Each terminal can either be an `opener', a `closer', or neither." 354Each terminal can either be an `opener', a `closer', or neither."
355 (let ((table (make-hash-table :test #'equal)) 355 (let ((table (make-hash-table :test #'equal))
356 (nts (mapcar #'car bnf))
356 (alist '())) 357 (alist '()))
357 (dolist (category bnf) 358 (dolist (category bnf)
358 (puthash (car category) 'neither table) ;Remove non-terminals. 359 (puthash (car category) 'neither table) ;Remove non-terminals.
@@ -362,14 +363,22 @@ Each terminal can either be an `opener', a `closer', or neither."
362 (let ((first (pop rhs))) 363 (let ((first (pop rhs)))
363 (puthash first 364 (puthash first
364 (if (memq (gethash first table) '(nil opener)) 365 (if (memq (gethash first table) '(nil opener))
365 'opener 'neither) 366 'opener
367 (unless (member first nts)
368 (error "SMIE: token %s is both opener and non-opener"
369 first))
370 'neither)
366 table)) 371 table))
367 (while (cdr rhs) 372 (while (cdr rhs)
368 (puthash (pop rhs) 'neither table)) ;Remove internals. 373 (puthash (pop rhs) 'neither table)) ;Remove internals.
369 (let ((last (pop rhs))) 374 (let ((last (pop rhs)))
370 (puthash last 375 (puthash last
371 (if (memq (gethash last table) '(nil closer)) 376 (if (memq (gethash last table) '(nil closer))
372 'closer 'neither) 377 'closer
378 (unless (member last nts)
379 (error "SMIE: token %s is both closer and non-closer"
380 last))
381 'neither)
373 table))))) 382 table)))))
374 (maphash (lambda (tok v) 383 (maphash (lambda (tok v)
375 (when (memq v '(closer opener)) 384 (when (memq v '(closer opener))
@@ -544,9 +553,9 @@ PREC2 is a table as returned by `smie-precs->prec2' or
544This list is normally built by `smie-prec2->grammar'. 553This list is normally built by `smie-prec2->grammar'.
545Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). 554Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL).
546Parsing is done using an operator precedence parser. 555Parsing is done using an operator precedence parser.
547LEFT-LEVEL and RIGHT-LEVEL can be either numbers or nil, where nil 556LEFT-LEVEL and RIGHT-LEVEL can be either numbers or a list, where a list
548means that this operator does not bind on the corresponding side, 557means that this operator does not bind on the corresponding side,
549i.e. a LEFT-LEVEL of nil means this is a token that behaves somewhat like 558e.g. a LEFT-LEVEL of nil means this is a token that behaves somewhat like
550an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something 559an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something
551like a close-paren.") 560like a close-paren.")
552 561
@@ -630,9 +639,10 @@ Possible return values:
630 (if (eq pos (point)) 639 (if (eq pos (point))
631 ;; We did not move, so let's abort the loop. 640 ;; We did not move, so let's abort the loop.
632 (throw 'return (list t (point)))))) 641 (throw 'return (list t (point))))))
633 ((null (funcall op-back toklevels)) 642 ((not (numberp (funcall op-back toklevels)))
634 ;; A token like a paren-close. 643 ;; A token like a paren-close.
635 (assert (funcall op-forw toklevels)) ;Otherwise, why mention it? 644 (assert (numberp ; Otherwise, why mention it in smie-grammar.
645 (funcall op-forw toklevels)))
636 (push toklevels levels)) 646 (push toklevels levels))
637 (t 647 (t
638 (while (and levels (< (funcall op-back toklevels) 648 (while (and levels (< (funcall op-back toklevels)
@@ -640,7 +650,7 @@ Possible return values:
640 (setq levels (cdr levels))) 650 (setq levels (cdr levels)))
641 (cond 651 (cond
642 ((null levels) 652 ((null levels)
643 (if (and halfsexp (funcall op-forw toklevels)) 653 (if (and halfsexp (numberp (funcall op-forw toklevels)))
644 (push toklevels levels) 654 (push toklevels levels)
645 (throw 'return 655 (throw 'return
646 (prog1 (list (or (car toklevels) t) (point) token) 656 (prog1 (list (or (car toklevels) t) (point) token)
@@ -656,11 +666,11 @@ Possible return values:
656 ;; Keep looking as long as we haven't matched the 666 ;; Keep looking as long as we haven't matched the
657 ;; topmost operator. 667 ;; topmost operator.
658 (levels 668 (levels
659 (if (funcall op-forw toklevels) 669 (if (numberp (funcall op-forw toklevels))
660 (push toklevels levels))) 670 (push toklevels levels)))
661 ;; We matched the topmost operator. If the new operator 671 ;; We matched the topmost operator. If the new operator
662 ;; is the last in the corresponding BNF rule, we're done. 672 ;; is the last in the corresponding BNF rule, we're done.
663 ((null (funcall op-forw toklevels)) 673 ((not (numberp (funcall op-forw toklevels)))
664 ;; It is the last element, let's stop here. 674 ;; It is the last element, let's stop here.
665 (throw 'return (list nil (point) token))) 675 (throw 'return (list nil (point) token)))
666 ;; If the new operator is not the last in the BNF rule, 676 ;; If the new operator is not the last in the BNF rule,
@@ -765,7 +775,7 @@ Possible return values:
765 ;; intervention, e.g. for Octave's use of `until' 775 ;; intervention, e.g. for Octave's use of `until'
766 ;; as a pseudo-closer of `do'. 776 ;; as a pseudo-closer of `do'.
767 (closer) 777 (closer)
768 ((or (equal levels '(nil)) (nth 1 (car levels))) 778 ((or (equal levels '(nil)) (numberp (nth 1 (car levels))))
769 (error "Doesn't look like a block")) 779 (error "Doesn't look like a block"))
770 (t 780 (t
771 ;; Now that smie-setup automatically sets smie-closer-alist 781 ;; Now that smie-setup automatically sets smie-closer-alist
@@ -776,7 +786,7 @@ Possible return values:
776 (when (and (eq (nth 2 level) (nth 1 other)) 786 (when (and (eq (nth 2 level) (nth 1 other))
777 (not (memq other seen))) 787 (not (memq other seen)))
778 (push other seen) 788 (push other seen)
779 (if (nth 2 other) 789 (if (numberp (nth 2 other))
780 (push other levels) 790 (push other levels)
781 (push (car other) found)))))) 791 (push (car other) found))))))
782 (cond 792 (cond
@@ -817,8 +827,8 @@ This command assumes point is not in a string or comment."
817 (progn (goto-char start) (down-list inc) nil) 827 (progn (goto-char start) (down-list inc) nil)
818 (forward-sexp inc) 828 (forward-sexp inc)
819 (/= (point) pos))) 829 (/= (point) pos)))
820 ((and levels (null (nth (+ 1 offset) levels))) nil) 830 ((and levels (not (numberp (nth (+ 1 offset) levels)))) nil)
821 ((and levels (null (nth (- 2 offset) levels))) 831 ((and levels (not (numberp (nth (- 2 offset) levels))))
822 (let ((end (point))) 832 (let ((end (point)))
823 (goto-char start) 833 (goto-char start)
824 (signal 'scan-error 834 (signal 'scan-error
@@ -903,7 +913,7 @@ This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'.
903 (not (memq (char-before) 913 (not (memq (char-before)
904 smie-blink-matching-triggers))) 914 smie-blink-matching-triggers)))
905 (or smie-blink-matching-inners 915 (or smie-blink-matching-inners
906 (null (nth 2 (assoc token smie-grammar))))) 916 (not (numberp (nth 2 (assoc token smie-grammar))))))
907 ;; The major mode might set blink-matching-check-function 917 ;; The major mode might set blink-matching-check-function
908 ;; buffer-locally so that interactive calls to 918 ;; buffer-locally so that interactive calls to
909 ;; blink-matching-open work right, but let's not presume 919 ;; blink-matching-open work right, but let's not presume
@@ -979,7 +989,7 @@ the beginning of a line."
979 (save-excursion 989 (save-excursion
980 (let* ((pos (point)) 990 (let* ((pos (point))
981 (tok (funcall smie-forward-token-function))) 991 (tok (funcall smie-forward-token-function)))
982 (unless (cadr (assoc tok smie-grammar)) 992 (unless (numberp (cadr (assoc tok smie-grammar)))
983 (goto-char pos)) 993 (goto-char pos))
984 (setq smie--parent 994 (setq smie--parent
985 (smie-backward-sexp 'halfsexp)))))) 995 (smie-backward-sexp 'halfsexp))))))
@@ -1026,7 +1036,7 @@ Only meaningful when called from within `smie-rules-function'."
1026 ;; rules-function, so it gives it a chance to tweak 1036 ;; rules-function, so it gives it a chance to tweak
1027 ;; indentation (e.g. by forcing indentation relative to 1037 ;; indentation (e.g. by forcing indentation relative to
1028 ;; its own parent, as in fn a => fn b => fn c =>). 1038 ;; its own parent, as in fn a => fn b => fn c =>).
1029 (if (or (null (car smie--parent)) (smie-indent--hanging-p)) 1039 (if (or (listp (car smie--parent)) (smie-indent--hanging-p))
1030 (smie-indent-virtual) (current-column)))))) 1040 (smie-indent-virtual) (current-column))))))
1031 1041
1032(defvar smie-rule-separator-outdent 2) 1042(defvar smie-rule-separator-outdent 2)
@@ -1222,26 +1232,30 @@ in order to figure out the indentation of some other (further down) point."
1222 (let* ((pos (point)) 1232 (let* ((pos (point))
1223 (toklevels (smie-indent-forward-token)) 1233 (toklevels (smie-indent-forward-token))
1224 (token (pop toklevels))) 1234 (token (pop toklevels)))
1225 (if (null (car toklevels)) 1235 (cond
1226 (save-excursion 1236 ((< pos (line-beginning-position))
1227 (goto-char pos) 1237 ;; The token we just read is actually not on the line where we started.
1228 ;; Different cases: 1238 nil)
1229 ;; - smie-indent--bolp: "indent according to others". 1239 ((not (numberp (car toklevels)))
1230 ;; - common hanging: "indent according to others". 1240 (save-excursion
1231 ;; - SML-let hanging: "indent like parent". 1241 (goto-char pos)
1232 ;; - if-after-else: "indent-like parent". 1242 ;; Different cases:
1233 ;; - middle-of-line: "trust current position". 1243 ;; - smie-indent--bolp: "indent according to others".
1234 (cond 1244 ;; - common hanging: "indent according to others".
1235 ((null (cdr toklevels)) nil) ;Not a keyword. 1245 ;; - SML-let hanging: "indent like parent".
1236 ((smie-indent--rule :before token)) 1246 ;; - if-after-else: "indent-like parent".
1237 ((smie-indent--bolp) ;I.e. non-virtual indent. 1247 ;; - middle-of-line: "trust current position".
1238 ;; For an open-paren-like thingy at BOL, always indent only 1248 (cond
1239 ;; based on other rules (typically smie-indent-after-keyword). 1249 ((null (cdr toklevels)) nil) ;Not a keyword.
1240 nil) 1250 ((smie-indent--rule :before token))
1241 (t 1251 ((smie-indent--bolp) ;I.e. non-virtual indent.
1242 ;; By default use point unless we're hanging. 1252 ;; For an open-paren-like thingy at BOL, always indent only
1243 (unless (smie-indent--hanging-p) (current-column))))) 1253 ;; based on other rules (typically smie-indent-after-keyword).
1244 1254 nil)
1255 (t
1256 ;; By default use point unless we're hanging.
1257 (unless (smie-indent--hanging-p) (current-column))))))
1258 (t
1245 ;; FIXME: This still looks too much like black magic!! 1259 ;; FIXME: This still looks too much like black magic!!
1246 (let* ((parent (smie-backward-sexp 'halfsexp))) 1260 (let* ((parent (smie-backward-sexp 'halfsexp)))
1247 ;; Different behaviors: 1261 ;; Different behaviors:
@@ -1321,7 +1335,7 @@ in order to figure out the indentation of some other (further down) point."
1321 ;; So we use a heuristic here, which is that we only use virtual 1335 ;; So we use a heuristic here, which is that we only use virtual
1322 ;; if the parent is tightly linked to the child token (they're 1336 ;; if the parent is tightly linked to the child token (they're
1323 ;; part of the same BNF rule). 1337 ;; part of the same BNF rule).
1324 (if (car parent) (current-column) (smie-indent-virtual)))))))))) 1338 (if (car parent) (current-column) (smie-indent-virtual)))))))))))
1325 1339
1326(defun smie-indent-comment () 1340(defun smie-indent-comment ()
1327 "Compute indentation of a comment." 1341 "Compute indentation of a comment."
@@ -1389,11 +1403,11 @@ in order to figure out the indentation of some other (further down) point."
1389 ;; The default indentation after a keyword/operator is 1403 ;; The default indentation after a keyword/operator is
1390 ;; 0 for infix, t for prefix, and use another rule 1404 ;; 0 for infix, t for prefix, and use another rule
1391 ;; for postfix. 1405 ;; for postfix.
1392 ((null (nth 2 toklevel)) nil) ;A closer. 1406 ((not (numberp (nth 2 toklevel))) nil) ;A closer.
1393 ((or (null (nth 1 toklevel)) ;An opener. 1407 ((or (not (numberp (nth 1 toklevel))) ;An opener.
1394 (rassoc tok smie-closer-alist)) ;An inner. 1408 (rassoc tok smie-closer-alist)) ;An inner.
1395 (+ (smie-indent-virtual) (smie-indent--offset 'basic))) ; 1409 (+ (smie-indent-virtual) (smie-indent--offset 'basic))) ;
1396 (t (smie-indent-virtual)))))) ;An infix. 1410 (t (smie-indent-virtual)))))) ;An infix.
1397 1411
1398(defun smie-indent-exps () 1412(defun smie-indent-exps ()
1399 ;; Indentation of sequences of simple expressions without 1413 ;; Indentation of sequences of simple expressions without