From 7bea8c7a92e1fb3eaf1a4e9f2becdaf0074f64ad Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 11 Nov 2010 00:08:25 -0500 Subject: * lisp/emacs-lisp/smie.el (smie-rule-parent, smie-indent--rule): Use smie-indent-virtual when indenting relative to an opener. (smie-rule-separator): Use smie-rule-parent. (smie-indent-keyword): Consult rules, even for openers at bol. (smie-indent-comment-close): Try to align closer's content. --- lisp/emacs-lisp/smie.el | 67 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 16 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index 03c03126d2f..e944902f6e3 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -63,6 +63,17 @@ ;; Since then, some of that code has been beaten into submission, but the ;; smie-indent-keyword is still pretty obscure. +;; Conflict resolution: +;; +;; - One source of conflicts is when you have: +;; (exp ("IF" exp "ELSE" exp "END") ("CASE" cases "END")) +;; (cases (cases "ELSE" insts) ...) +;; The IF-rule implies ELSE=END and the CASE-rule implies ELSE>END. +;; FIXME: we could try to resolve such conflicts automatically by changing +;; the way BNF rules such as the IF-rule is handled. I.e. rather than +;; IF=ELSE and ELSE=END, we could turn them into IFEND +;; and IF=END, + ;;; Code: ;; FIXME: I think the behavior on empty lines is wrong. It shouldn't @@ -155,6 +166,11 @@ one of those elements share the same precedence level and associativity." (put 'smie-bnf->prec2 'pure t) (defun smie-bnf->prec2 (bnf &rest precs) + ;; FIXME: Add repetition operator like (repeat ). + ;; Maybe also add (or ...) for things like + ;; (exp (exp (or "+" "*" "=" ..) exp)). + ;; Basically, make it EBNF (except for the specification of a separator in + ;; the repetition). (let ((nts (mapcar 'car bnf)) ;Non-terminals (first-ops-table ()) (last-ops-table ()) @@ -613,7 +629,7 @@ Possible return values: ;; It is the last element, let's stop here. (throw 'return (list nil (point) token))) ;; If the new operator is not the last in the BNF rule, - ;; ans is not associative, it's one of the inner operators + ;; and is not associative, it's one of the inner operators ;; (like the "in" in "let .. in .. end"), so keep looking. ((not (smie--associative-p toklevels)) (push toklevels levels)) @@ -969,8 +985,14 @@ Only meaningful when called from within `smie-rules-function'." (goto-char (cadr (smie-indent--parent))) (cons 'column (+ (or offset 0) - (if (smie-indent--hanging-p) - (smie-indent-virtual) (current-column)))))) + ;; Use smie-indent-virtual when indenting relative to an opener: + ;; this will also by default use current-column unless + ;; that opener is hanging, but will additionally consult + ;; rules-function, so it gives it a chance to tweak + ;; indentation (e.g. by forcing indentation relative to + ;; its own parent, as in fn a => fn b => fn c =>). + (if (or (null (car smie--parent)) (smie-indent--hanging-p)) + (smie-indent-virtual) (current-column)))))) (defvar smie-rule-separator-outdent 2) @@ -1030,11 +1052,7 @@ Only meaningful when called from within `smie-rules-function'." ;; FIXME: Rather than consult the number of spaces, we could *set* the ;; number of spaces so as to align the separator with the close-paren ;; while aligning the content with the rest. - (let ((parent-col - (save-excursion - (goto-char (cadr smie--parent)) - (if (smie-indent--hanging-p) - (smie-indent-virtual) (current-column)))) + (let ((parent-col (cdr (smie-rule-parent))) (parent-pos-col ;FIXME: we knew this when computing smie--parent. (save-excursion (goto-char (cadr smie--parent)) @@ -1083,7 +1101,16 @@ BASE-POS is the position relative to which offsets should be applied." (+ offset (if (null base-pos) 0 (goto-char base-pos) - (if (smie-indent--hanging-p) + ;; Use smie-indent-virtual when indenting relative to an opener: + ;; this will also by default use current-column unless + ;; that opener is hanging, but will additionally consult + ;; rules-function, so it gives it a chance to tweak indentation + ;; (e.g. by forcing indentation relative to its own parent, as in + ;; fn a => fn b => fn c =>). + ;; When parent==nil it doesn't matter because the only case + ;; where it's really used is when the base-pos is hanging anyway. + (if (or (and parent (null (car parent))) + (smie-indent--hanging-p)) (smie-indent-virtual) (current-column))))) (t (error "Unknown indentation offset %s" offset)))))) @@ -1171,12 +1198,11 @@ in order to figure out the indentation of some other (further down) point." ;; - middle-of-line: "trust current position". (cond ((null (cdr toklevels)) nil) ;Not a keyword. - ((smie-indent--bolp) + ((smie-indent--rule :before token)) + ((smie-indent--bolp) ;I.e. non-virtual indent. ;; For an open-paren-like thingy at BOL, always indent only ;; based on other rules (typically smie-indent-after-keyword). nil) - ;; We're only ever here for virtual-indent. - ((smie-indent--rule :before token)) (t ;; By default use point unless we're hanging. (unless (smie-indent--hanging-p) (current-column))))) @@ -1298,10 +1324,19 @@ in order to figure out the indentation of some other (further down) point." comment-end-skip (not (looking-at " \t*$")) ;Not just a \n comment-closer. (looking-at comment-end-skip) - (nth 4 (syntax-ppss)) - (save-excursion - (goto-char (nth 8 (syntax-ppss))) - (current-column)))) + (let ((end (match-string 0))) + (and (nth 4 (syntax-ppss)) + (save-excursion + (goto-char (nth 8 (syntax-ppss))) + (and (looking-at comment-start-skip) + (let ((start (match-string 0))) + ;; Align the common substring between starter + ;; and ender, if possible. + (if (string-match "\\(.+\\).*\n\\(.*?\\)\\1" + (concat start "\n" end)) + (+ (current-column) (match-beginning 0) + (- (match-beginning 2) (match-end 2))) + (current-column))))))))) (defun smie-indent-comment-inside () (and (nth 4 (syntax-ppss)) -- cgit v1.2.3 From acef0722fc954a88eea588486b478f49b1afdc6a Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 11 Nov 2010 17:19:01 -0500 Subject: * lisp/files.el (safe-local-variable-p): Gracefully handle errors. * lisp/emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the safety predicate. --- lisp/ChangeLog | 5 +++++ lisp/emacs-lisp/bytecomp.el | 17 ++++------------- lisp/files.el | 5 ++++- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 88dc22a011d..fef5fec5ce9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,10 @@ 2010-11-11 Stefan Monnier + * emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the + safety predicate. + + * files.el (safe-local-variable-p): Gracefully handle errors. + * emacs-lisp/smie.el (smie-rule-parent, smie-indent--rule): Use smie-indent-virtual when indenting relative to an opener. (smie-rule-separator): Use smie-rule-parent. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 394169be99d..cdfac80ca78 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -294,21 +294,12 @@ suppress. For example, (not mapcar) will suppress warnings about mapcar." (set :menu-tag "Some" ,@(mapcar (lambda (x) `(const ,x)) byte-compile-warning-types)))) -;;;###autoload(put 'byte-compile-warnings 'safe-local-variable 'byte-compile-warnings-safe-p) ;;;###autoload -(defun byte-compile-warnings-safe-p (x) - "Return non-nil if X is valid as a value of `byte-compile-warnings'." - (or (booleanp x) - (and (listp x) - (if (eq (car x) 'not) (setq x (cdr x)) - t) - (equal (mapcar - (lambda (e) - (when (memq e byte-compile-warning-types) - e)) - x) - x)))) +(put 'byte-compile-warnings 'safe-local-variable + (lambda (v) + (or (symbolp v) + (null (delq nil (mapcar (lambda (x) (not (symbolp x))) v)))))) (defun byte-compile-warning-enabled-p (warning) "Return non-nil if WARNING is enabled, according to `byte-compile-warnings'." diff --git a/lisp/files.el b/lisp/files.el index 0664bfd3844..4901c3872cd 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -3134,7 +3134,10 @@ It is safe if any of these conditions are met: evaluates to a non-nil value with VAL as an argument." (or (member (cons sym val) safe-local-variable-values) (let ((safep (get sym 'safe-local-variable))) - (and (functionp safep) (funcall safep val))))) + (and (functionp safep) + ;; If the function signals an error, that means it + ;; can't assure us that the value is safe. + (with-demoted-errors (funcall safep val)))))) (defun risky-local-variable-p (sym &optional ignored) "Non-nil if SYM could be dangerous as a file-local variable. -- cgit v1.2.3 From 10b40d2ef6eb3480f36a39168440dd59efca0e97 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 11 Nov 2010 20:33:28 -0500 Subject: * lisp/emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints when filling the remaining "unconstrained" values. --- lisp/ChangeLog | 5 +++++ lisp/emacs-lisp/smie.el | 45 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 5 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index fef5fec5ce9..a20f4d57aed 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2010-11-12 Stefan Monnier + + * emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints + when filling the remaining "unconstrained" values. + 2010-11-11 Stefan Monnier * emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index e944902f6e3..09095521b49 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -74,10 +74,20 @@ ;; IF=ELSE and ELSE=END, we could turn them into IFEND ;; and IF=END, -;;; Code: +;; TODO & BUGS: +;; +;; - FIXME: I think the behavior on empty lines is wrong. It shouldn't +;; look at the next token on subsequent lines. +;; - Using the structural information SMIE gives us, it should be possible to +;; implement a `smie-align' command that would automatically figure out what +;; there is to align and how to do it (something like: align the token of +;; lowest precedence that appears the same number of times on all lines, +;; and then do the same on each side of that token). +;; - Maybe accept two juxtaposed non-terminals in the BNF under the condition +;; that the first always ends with a terminal, or that the second always +;; starts with a terminal. -;; FIXME: I think the behavior on empty lines is wrong. It shouldn't -;; look at the next token on subsequent lines. +;;; Code: (eval-when-compile (require 'cl)) @@ -401,6 +411,18 @@ CSTS is a list of pairs representing arcs in a graph." (append names (list (car names))) " < "))) +;; (defun smie-check-grammar (grammar prec2 &optional dummy) +;; (maphash (lambda (k v) +;; (when (consp k) +;; (let ((left (nth 2 (assoc (car k) grammar))) +;; (right (nth 1 (assoc (cdr k) grammar)))) +;; (when (and left right) +;; (cond +;; ((< left right) (assert (eq v '<))) +;; ((> left right) (assert (eq v '>))) +;; (t (assert (eq v '=)))))))) +;; prec2)) + (put 'smie-prec2->grammar 'pure t) (defun smie-prec2->grammar (prec2) "Take a 2D precedence table and turn it into an alist of precedence levels. @@ -469,6 +491,7 @@ PREC2 is a table as returned by `smie-precs->prec2' or ;; left = right). (unless (caar cst) (setcar (car cst) i) + ;; (smie-check-grammar table prec2 'step1) (incf i)) (setq csts (delq cst csts)))) (unless progress @@ -478,8 +501,19 @@ PREC2 is a table as returned by `smie-precs->prec2' or (incf i 10)) ;; Propagate equalities back to their source. (dolist (eq (nreverse eqs)) - (assert (or (null (caar eq)) (eq (car eq) (cdr eq)))) - (setcar (car eq) (cadr eq))) + (when (null (cadr eq)) + ;; There's an equality constraint, but we still haven't given + ;; it a value: that means it binds tighter than anything else, + ;; and it can't be an opener/closer (those don't have equality + ;; constraints). + ;; So set it here rather than below since doing it below + ;; makes it more difficult to obey the equality constraints. + (setcar (cdr eq) i) + (incf i)) + (assert (or (null (caar eq)) (eq (caar eq) (cadr eq)))) + (setcar (car eq) (cadr eq)) + ;; (smie-check-grammar table prec2 'step2) + ) ;; Finally, fill in the remaining vars (which only appeared on the ;; right side of the < constraints). (let ((classification-table (gethash :smie-open/close-alist prec2))) @@ -500,6 +534,7 @@ PREC2 is a table as returned by `smie-precs->prec2' or (incf i))))) ;See other (incf i) above. (let ((ca (gethash :smie-closer-alist prec2))) (when ca (push (cons :smie-closer-alist ca) table))) + ;; (smie-check-grammar table prec2 'step3) table)) ;;; Parsing using a precedence level table. -- cgit v1.2.3 From 4c0eb0d3db97c4f13612a6952bf1e7a88d63cb86 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 16 Nov 2010 19:47:16 -0800 Subject: autoload.el fix for bug#7414. * lisp/emacs-lisp/autoload.el (autoload-find-destination): The function coding-system-eol-type may return non-numeric values. --- lisp/ChangeLog | 5 +++++ lisp/emacs-lisp/autoload.el | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 53c6db7eb0d..d0607f72f7e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2010-11-17 Glenn Morris + + * emacs-lisp/autoload.el (autoload-find-destination): The function + coding-system-eol-type may return non-numeric values. (Bug#7414) + 2010-11-16 Ulrich Mueller * server.el (server-force-stop): Ensure the server is stopped (Bug#7409). diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index c985aae07b6..5ae984ffdb0 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -1,7 +1,8 @@ ;; autoload.el --- maintain autoloads in loaddefs.el -;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2001, 2002, 2003, -;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2001, 2002, +;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. ;; Author: Roland McGrath ;; Keywords: maint @@ -525,8 +526,8 @@ removes any prior now out-of-date autoload entries." (autoload-ensure-default-file (autoload-generated-file))) ;; This is to make generated-autoload-file have Unix EOLs, so ;; that it is portable to all platforms. - (unless (zerop (coding-system-eol-type buffer-file-coding-system)) - (set-buffer-file-coding-system 'unix)) + (or (eq 0 (coding-system-eol-type buffer-file-coding-system)) + (set-buffer-file-coding-system 'unix)) (or (> (buffer-size) 0) (error "Autoloads file %s does not exist" buffer-file-name)) (or (file-writable-p buffer-file-name) @@ -735,5 +736,4 @@ Calls `update-directory-autoloads' on the command line arguments." (provide 'autoload) -;; arch-tag: 00244766-98f4-4767-bf42-8a22103441c6 ;;; autoload.el ends here -- cgit v1.2.3 From e2f454c4bed74e7699e71da161db37a4dd1317de Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 17 Nov 2010 14:59:16 -0500 Subject: * emacs-lisp/smie.el (smie-bnf-classify): Signal errors for tokens that are both openers (resp. closers) and something else. (smie-grammar): Loosen definition of valid values. (smie-next-sexp, smie-down-list, smie-blink-matching-open) (smie-indent--parent, smie-rule-parent, smie-indent-keyword) (smie-indent-after-keyword): Adjust users. (smie-indent-keyword): Don't indent empty lines. --- lisp/ChangeLog | 8 +++++ lisp/emacs-lisp/smie.el | 96 ++++++++++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 41 deletions(-) (limited to 'lisp/emacs-lisp') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c1e446c3138..0ba7c673857 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,13 @@ 2010-11-17 Stefan Monnier + * emacs-lisp/smie.el (smie-bnf-classify): Signal errors for tokens + that are both openers (resp. closers) and something else. + (smie-grammar): Loosen definition of valid values. + (smie-next-sexp, smie-down-list, smie-blink-matching-open) + (smie-indent--parent, smie-rule-parent, smie-indent-keyword) + (smie-indent-after-keyword): Adjust users. + (smie-indent-keyword): Don't indent empty lines. + * vc-hg.el (vc-hg-program): New var. Suggested by Norman Gray . (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\"). "Return a table classifying terminals. Each terminal can either be an `opener', a `closer', or neither." (let ((table (make-hash-table :test #'equal)) + (nts (mapcar #'car bnf)) (alist '())) (dolist (category bnf) (puthash (car category) 'neither table) ;Remove non-terminals. @@ -362,14 +363,22 @@ Each terminal can either be an `opener', a `closer', or neither." (let ((first (pop rhs))) (puthash first (if (memq (gethash first table) '(nil opener)) - 'opener 'neither) + 'opener + (unless (member first nts) + (error "SMIE: token %s is both opener and non-opener" + first)) + 'neither) table)) (while (cdr rhs) (puthash (pop rhs) 'neither table)) ;Remove internals. (let ((last (pop rhs))) (puthash last (if (memq (gethash last table) '(nil closer)) - 'closer 'neither) + 'closer + (unless (member last nts) + (error "SMIE: token %s is both closer and non-closer" + last)) + 'neither) table))))) (maphash (lambda (tok v) (when (memq v '(closer opener)) @@ -544,9 +553,9 @@ PREC2 is a table as returned by `smie-precs->prec2' or This list is normally built by `smie-prec2->grammar'. Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). Parsing is done using an operator precedence parser. -LEFT-LEVEL and RIGHT-LEVEL can be either numbers or nil, where nil +LEFT-LEVEL and RIGHT-LEVEL can be either numbers or a list, where a list means that this operator does not bind on the corresponding side, -i.e. a LEFT-LEVEL of nil means this is a token that behaves somewhat like +e.g. a LEFT-LEVEL of nil means this is a token that behaves somewhat like an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something like a close-paren.") @@ -630,9 +639,10 @@ Possible return values: (if (eq pos (point)) ;; We did not move, so let's abort the loop. (throw 'return (list t (point)))))) - ((null (funcall op-back toklevels)) + ((not (numberp (funcall op-back toklevels))) ;; A token like a paren-close. - (assert (funcall op-forw toklevels)) ;Otherwise, why mention it? + (assert (numberp ; Otherwise, why mention it in smie-grammar. + (funcall op-forw toklevels))) (push toklevels levels)) (t (while (and levels (< (funcall op-back toklevels) @@ -640,7 +650,7 @@ Possible return values: (setq levels (cdr levels))) (cond ((null levels) - (if (and halfsexp (funcall op-forw toklevels)) + (if (and halfsexp (numberp (funcall op-forw toklevels))) (push toklevels levels) (throw 'return (prog1 (list (or (car toklevels) t) (point) token) @@ -656,11 +666,11 @@ Possible return values: ;; Keep looking as long as we haven't matched the ;; topmost operator. (levels - (if (funcall op-forw toklevels) + (if (numberp (funcall op-forw toklevels)) (push toklevels levels))) ;; We matched the topmost operator. If the new operator ;; is the last in the corresponding BNF rule, we're done. - ((null (funcall op-forw toklevels)) + ((not (numberp (funcall op-forw toklevels))) ;; It is the last element, let's stop here. (throw 'return (list nil (point) token))) ;; If the new operator is not the last in the BNF rule, @@ -765,7 +775,7 @@ Possible return values: ;; intervention, e.g. for Octave's use of `until' ;; as a pseudo-closer of `do'. (closer) - ((or (equal levels '(nil)) (nth 1 (car levels))) + ((or (equal levels '(nil)) (numberp (nth 1 (car levels)))) (error "Doesn't look like a block")) (t ;; Now that smie-setup automatically sets smie-closer-alist @@ -776,7 +786,7 @@ Possible return values: (when (and (eq (nth 2 level) (nth 1 other)) (not (memq other seen))) (push other seen) - (if (nth 2 other) + (if (numberp (nth 2 other)) (push other levels) (push (car other) found)))))) (cond @@ -817,8 +827,8 @@ This command assumes point is not in a string or comment." (progn (goto-char start) (down-list inc) nil) (forward-sexp inc) (/= (point) pos))) - ((and levels (null (nth (+ 1 offset) levels))) nil) - ((and levels (null (nth (- 2 offset) levels))) + ((and levels (not (numberp (nth (+ 1 offset) levels)))) nil) + ((and levels (not (numberp (nth (- 2 offset) levels)))) (let ((end (point))) (goto-char start) (signal 'scan-error @@ -903,7 +913,7 @@ This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'. (not (memq (char-before) smie-blink-matching-triggers))) (or smie-blink-matching-inners - (null (nth 2 (assoc token smie-grammar))))) + (not (numberp (nth 2 (assoc token smie-grammar)))))) ;; The major mode might set blink-matching-check-function ;; buffer-locally so that interactive calls to ;; blink-matching-open work right, but let's not presume @@ -979,7 +989,7 @@ the beginning of a line." (save-excursion (let* ((pos (point)) (tok (funcall smie-forward-token-function))) - (unless (cadr (assoc tok smie-grammar)) + (unless (numberp (cadr (assoc tok smie-grammar))) (goto-char pos)) (setq smie--parent (smie-backward-sexp 'halfsexp)))))) @@ -1026,7 +1036,7 @@ Only meaningful when called from within `smie-rules-function'." ;; rules-function, so it gives it a chance to tweak ;; indentation (e.g. by forcing indentation relative to ;; its own parent, as in fn a => fn b => fn c =>). - (if (or (null (car smie--parent)) (smie-indent--hanging-p)) + (if (or (listp (car smie--parent)) (smie-indent--hanging-p)) (smie-indent-virtual) (current-column)))))) (defvar smie-rule-separator-outdent 2) @@ -1222,26 +1232,30 @@ in order to figure out the indentation of some other (further down) point." (let* ((pos (point)) (toklevels (smie-indent-forward-token)) (token (pop toklevels))) - (if (null (car toklevels)) - (save-excursion - (goto-char pos) - ;; Different cases: - ;; - smie-indent--bolp: "indent according to others". - ;; - common hanging: "indent according to others". - ;; - SML-let hanging: "indent like parent". - ;; - if-after-else: "indent-like parent". - ;; - middle-of-line: "trust current position". - (cond - ((null (cdr toklevels)) nil) ;Not a keyword. - ((smie-indent--rule :before token)) - ((smie-indent--bolp) ;I.e. non-virtual indent. - ;; For an open-paren-like thingy at BOL, always indent only - ;; based on other rules (typically smie-indent-after-keyword). - nil) - (t - ;; By default use point unless we're hanging. - (unless (smie-indent--hanging-p) (current-column))))) - + (cond + ((< pos (line-beginning-position)) + ;; The token we just read is actually not on the line where we started. + nil) + ((not (numberp (car toklevels))) + (save-excursion + (goto-char pos) + ;; Different cases: + ;; - smie-indent--bolp: "indent according to others". + ;; - common hanging: "indent according to others". + ;; - SML-let hanging: "indent like parent". + ;; - if-after-else: "indent-like parent". + ;; - middle-of-line: "trust current position". + (cond + ((null (cdr toklevels)) nil) ;Not a keyword. + ((smie-indent--rule :before token)) + ((smie-indent--bolp) ;I.e. non-virtual indent. + ;; For an open-paren-like thingy at BOL, always indent only + ;; based on other rules (typically smie-indent-after-keyword). + nil) + (t + ;; By default use point unless we're hanging. + (unless (smie-indent--hanging-p) (current-column)))))) + (t ;; FIXME: This still looks too much like black magic!! (let* ((parent (smie-backward-sexp 'halfsexp))) ;; Different behaviors: @@ -1321,7 +1335,7 @@ in order to figure out the indentation of some other (further down) point." ;; So we use a heuristic here, which is that we only use virtual ;; if the parent is tightly linked to the child token (they're ;; part of the same BNF rule). - (if (car parent) (current-column) (smie-indent-virtual)))))))))) + (if (car parent) (current-column) (smie-indent-virtual))))))))))) (defun smie-indent-comment () "Compute indentation of a comment." @@ -1389,11 +1403,11 @@ in order to figure out the indentation of some other (further down) point." ;; The default indentation after a keyword/operator is ;; 0 for infix, t for prefix, and use another rule ;; for postfix. - ((null (nth 2 toklevel)) nil) ;A closer. - ((or (null (nth 1 toklevel)) ;An opener. - (rassoc tok smie-closer-alist)) ;An inner. + ((not (numberp (nth 2 toklevel))) nil) ;A closer. + ((or (not (numberp (nth 1 toklevel))) ;An opener. + (rassoc tok smie-closer-alist)) ;An inner. (+ (smie-indent-virtual) (smie-indent--offset 'basic))) ; - (t (smie-indent-virtual)))))) ;An infix. + (t (smie-indent-virtual)))))) ;An infix. (defun smie-indent-exps () ;; Indentation of sequences of simple expressions without -- cgit v1.2.3