diff options
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/emacs-lisp/smie.el | 96 |
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 @@ | |||
| 1 | 2010-11-17 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2010-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. |
| 354 | Each terminal can either be an `opener', a `closer', or neither." | 354 | Each 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 | |||
| 544 | This list is normally built by `smie-prec2->grammar'. | 553 | This list is normally built by `smie-prec2->grammar'. |
| 545 | Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). | 554 | Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). |
| 546 | Parsing is done using an operator precedence parser. | 555 | Parsing is done using an operator precedence parser. |
| 547 | LEFT-LEVEL and RIGHT-LEVEL can be either numbers or nil, where nil | 556 | LEFT-LEVEL and RIGHT-LEVEL can be either numbers or a list, where a list |
| 548 | means that this operator does not bind on the corresponding side, | 557 | means that this operator does not bind on the corresponding side, |
| 549 | i.e. a LEFT-LEVEL of nil means this is a token that behaves somewhat like | 558 | e.g. a LEFT-LEVEL of nil means this is a token that behaves somewhat like |
| 550 | an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something | 559 | an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something |
| 551 | like a close-paren.") | 560 | like 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 |