annotate lisp/emacs-lisp/smie.el @ 110036:af3f1edc363f

* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take a list of parents. (smie-indent-column): Allow indirection through variables.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 30 Aug 2010 17:21:14 +0200
parents 3a11454ef7ca
children 5cab4c4229ff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1 ;;; smie.el --- Simple Minded Indentation Engine
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
2
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
3 ;; Copyright (C) 2010 Free Software Foundation, Inc.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
4
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
6 ;; Keywords: languages, lisp, internal, parsing, indentation
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
7
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
8 ;; This file is part of GNU Emacs.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
9
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
11 ;; it under the terms of the GNU General Public License as published by
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
12 ;; the Free Software Foundation, either version 3 of the License, or
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
13 ;; (at your option) any later version.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
14
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
15 ;; GNU Emacs is distributed in the hope that it will be useful,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
18 ;; GNU General Public License for more details.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
19
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
21 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
22
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
23 ;;; Commentary:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
24
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
25 ;; While working on the SML indentation code, the idea grew that maybe
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
26 ;; I could write something generic to do the same thing, and at the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
27 ;; end of working on the SML code, I had a pretty good idea of what it
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
28 ;; could look like. That idea grew stronger after working on
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
29 ;; LaTeX indentation.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
30 ;;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
31 ;; So at some point I decided to try it out, by writing a new
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
32 ;; indentation code for Coq while trying to keep most of the code
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
33 ;; "table driven", where only the tables are Coq-specific. The result
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
34 ;; (which was used for Beluga-mode as well) turned out to be based on
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
35 ;; something pretty close to an operator precedence parser.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
36
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
37 ;; So here is another rewrite, this time following the actual principles of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
38 ;; operator precedence grammars. Why OPG? Even though they're among the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
39 ;; weakest kinds of parsers, these parsers have some very desirable properties
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
40 ;; for Emacs:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
41 ;; - most importantly for indentation, they work equally well in either
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
42 ;; direction, so you can use them to parse backward from the indentation
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
43 ;; point to learn the syntactic context;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
44 ;; - they work locally, so there's no need to keep a cache of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
45 ;; the parser's state;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
46 ;; - because of that locality, indentation also works just fine when earlier
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
47 ;; parts of the buffer are syntactically incorrect since the indentation
108912
c7e85ff4bca6 * lisp/emacs-lisp/smie.el (smie-indent-keyword): Remove special case that
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108897
diff changeset
48 ;; looks at "as little as possible" of the buffer to make an indentation
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
49 ;; decision.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
50 ;; - they typically have no error handling and can't even detect a parsing
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
51 ;; error, so we don't have to worry about what to do in case of a syntax
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
52 ;; error because the parser just automatically does something. Better yet,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
53 ;; we can afford to use a sloppy grammar.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
54
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
55 ;; The development (especially the parts building the 2D precedence
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
56 ;; tables and then computing the precedence levels from it) is largely
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
57 ;; inspired from page 187-194 of "Parsing techniques" by Dick Grune
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
58 ;; and Ceriel Jacobs (BookBody.pdf available at
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
59 ;; http://www.cs.vu.nl/~dick/PTAPG.html).
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
60 ;;
108912
c7e85ff4bca6 * lisp/emacs-lisp/smie.el (smie-indent-keyword): Remove special case that
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108897
diff changeset
61 ;; OTOH we had to kill many chickens, read many coffee grounds, and practice
c7e85ff4bca6 * lisp/emacs-lisp/smie.el (smie-indent-keyword): Remove special case that
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108897
diff changeset
62 ;; untold numbers of black magic spells, to come up with the indentation code.
c7e85ff4bca6 * lisp/emacs-lisp/smie.el (smie-indent-keyword): Remove special case that
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108897
diff changeset
63 ;; Since then, some of that code has been beaten into submission, but the
c7e85ff4bca6 * lisp/emacs-lisp/smie.el (smie-indent-keyword): Remove special case that
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108897
diff changeset
64 ;; smie-indent-keyword is still pretty obscure.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
65
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
66 ;;; Code:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
67
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
68 ;; FIXME: I think the behavior on empty lines is wrong. It shouldn't
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
69 ;; look at the next token on subsequent lines.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
70
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
71 (eval-when-compile (require 'cl))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
72
108878
c3cbf94d10f1 * emacs-lisp/smie.el (comment-continue): Declare for byte-compiler.
Juanma Barranquero <lekktu@gmail.com>
parents: 108865
diff changeset
73 (defvar comment-continue)
108923
5173ad363d4b * emacs-lisp/smie.el (comment-string-strip): Declare function.
Juanma Barranquero <lekktu@gmail.com>
parents: 108912
diff changeset
74 (declare-function comment-string-strip "newcomment" (str beforep afterp))
108878
c3cbf94d10f1 * emacs-lisp/smie.el (comment-continue): Declare for byte-compiler.
Juanma Barranquero <lekktu@gmail.com>
parents: 108865
diff changeset
75
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
76 ;;; Building precedence level tables from BNF specs.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
77
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
78 (defun smie-set-prec2tab (table x y val &optional override)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
79 (assert (and x y))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
80 (let* ((key (cons x y))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
81 (old (gethash key table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
82 (if (and old (not (eq old val)))
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
83 (if (and override (gethash key override))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
84 ;; FIXME: The override is meant to resolve ambiguities,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
85 ;; but it also hides real conflicts. It would be great to
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
86 ;; be able to distinguish the two cases so that overrides
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
87 ;; don't hide real conflicts.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
88 (puthash key (gethash key override) table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
89 (display-warning 'smie (format "Conflict: %s %s/%s %s" x old val y)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
90 (puthash key val table))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
91
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
92 (defun smie-precs-precedence-table (precs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
93 "Compute a 2D precedence table from a list of precedences.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
94 PRECS should be a list, sorted by precedence (e.g. \"+\" will
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
95 come before \"*\"), of elements of the form \(left OP ...)
108923
5173ad363d4b * emacs-lisp/smie.el (comment-string-strip): Declare function.
Juanma Barranquero <lekktu@gmail.com>
parents: 108912
diff changeset
96 or (right OP ...) or (nonassoc OP ...) or (assoc OP ...). All operators in
108642
66f3c521df14 * emacs-lisp/smie.el: Fix typos in docstrings.
Juanma Barranquero <lekktu@gmail.com>
parents: 108632
diff changeset
97 one of those elements share the same precedence level and associativity."
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
98 (let ((prec2-table (make-hash-table :test 'equal)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
99 (dolist (prec precs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
100 (dolist (op (cdr prec))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
101 (let ((selfrule (cdr (assq (car prec)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
102 '((left . >) (right . <) (assoc . =))))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
103 (when selfrule
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
104 (dolist (other-op (cdr prec))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
105 (smie-set-prec2tab prec2-table op other-op selfrule))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
106 (let ((op1 '<) (op2 '>))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
107 (dolist (other-prec precs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
108 (if (eq prec other-prec)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
109 (setq op1 '> op2 '<)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
110 (dolist (other-op (cdr other-prec))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
111 (smie-set-prec2tab prec2-table op other-op op2)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
112 (smie-set-prec2tab prec2-table other-op op op1)))))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
113 prec2-table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
114
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
115 (defun smie-merge-prec2s (&rest tables)
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
116 (if (null (cdr tables))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
117 (car tables)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
118 (let ((prec2 (make-hash-table :test 'equal)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
119 (dolist (table tables)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
120 (maphash (lambda (k v)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
121 (smie-set-prec2tab prec2 (car k) (cdr k) v))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
122 table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
123 prec2)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
124
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
125 (defun smie-bnf-precedence-table (bnf &rest precs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
126 (let ((nts (mapcar 'car bnf)) ;Non-terminals
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
127 (first-ops-table ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
128 (last-ops-table ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
129 (first-nts-table ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
130 (last-nts-table ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
131 (prec2 (make-hash-table :test 'equal))
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
132 (override (apply 'smie-merge-prec2s
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
133 (mapcar 'smie-precs-precedence-table precs)))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
134 again)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
135 (dolist (rules bnf)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
136 (let ((nt (car rules))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
137 (last-ops ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
138 (first-ops ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
139 (last-nts ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
140 (first-nts ()))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
141 (dolist (rhs (cdr rules))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
142 (assert (consp rhs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
143 (if (not (member (car rhs) nts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
144 (pushnew (car rhs) first-ops)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
145 (pushnew (car rhs) first-nts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
146 (when (consp (cdr rhs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
147 ;; If the first is not an OP we add the second (which
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
148 ;; should be an OP if BNF is an "operator grammar").
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
149 ;; Strictly speaking, this should only be done if the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
150 ;; first is a non-terminal which can expand to a phrase
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
151 ;; without any OP in it, but checking doesn't seem worth
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
152 ;; the trouble, and it lets the writer of the BNF
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
153 ;; be a bit more sloppy by skipping uninteresting base
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
154 ;; cases which are terminals but not OPs.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
155 (assert (not (member (cadr rhs) nts)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
156 (pushnew (cadr rhs) first-ops)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
157 (let ((shr (reverse rhs)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
158 (if (not (member (car shr) nts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
159 (pushnew (car shr) last-ops)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
160 (pushnew (car shr) last-nts)
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
161 (when (consp (cdr shr))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
162 (assert (not (member (cadr shr) nts)))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
163 (pushnew (cadr shr) last-ops)))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
164 (push (cons nt first-ops) first-ops-table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
165 (push (cons nt last-ops) last-ops-table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
166 (push (cons nt first-nts) first-nts-table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
167 (push (cons nt last-nts) last-nts-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
168 ;; Compute all first-ops by propagating the initial ones we have
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
169 ;; now, according to first-nts.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
170 (setq again t)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
171 (while (prog1 again (setq again nil))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
172 (dolist (first-nts first-nts-table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
173 (let* ((nt (pop first-nts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
174 (first-ops (assoc nt first-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
175 (dolist (first-nt first-nts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
176 (dolist (op (cdr (assoc first-nt first-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
177 (unless (member op first-ops)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
178 (setq again t)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
179 (push op (cdr first-ops))))))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
180 ;; Same thing for last-ops.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
181 (setq again t)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
182 (while (prog1 again (setq again nil))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
183 (dolist (last-nts last-nts-table)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
184 (let* ((nt (pop last-nts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
185 (last-ops (assoc nt last-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
186 (dolist (last-nt last-nts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
187 (dolist (op (cdr (assoc last-nt last-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
188 (unless (member op last-ops)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
189 (setq again t)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
190 (push op (cdr last-ops))))))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
191 ;; Now generate the 2D precedence table.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
192 (dolist (rules bnf)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
193 (dolist (rhs (cdr rules))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
194 (while (cdr rhs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
195 (cond
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
196 ((member (car rhs) nts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
197 (dolist (last (cdr (assoc (car rhs) last-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
198 (smie-set-prec2tab prec2 last (cadr rhs) '> override)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
199 ((member (cadr rhs) nts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
200 (dolist (first (cdr (assoc (cadr rhs) first-ops-table)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
201 (smie-set-prec2tab prec2 (car rhs) first '< override))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
202 (if (and (cddr rhs) (not (member (car (cddr rhs)) nts)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
203 (smie-set-prec2tab prec2 (car rhs) (car (cddr rhs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
204 '= override)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
205 (t (smie-set-prec2tab prec2 (car rhs) (cadr rhs) '= override)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
206 (setq rhs (cdr rhs)))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
207 prec2))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
208
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
209 (defun smie-prec2-levels (prec2)
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
210 ;; FIXME: Rather than only return an alist of precedence levels, we should
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
211 ;; also extract other useful data from it:
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
212 ;; - matching sets of block openers&closers (which can otherwise become
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
213 ;; collapsed into a single equivalence class in smie-op-levels) for
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
214 ;; smie-close-block as well as to detect mismatches in smie-next-sexp
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
215 ;; or in blink-paren (as well as to do the blink-paren for inner
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
216 ;; keywords like the "in" of "let..in..end").
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
217 ;; - better default indentation rules (i.e. non-zero indentation after inner
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
218 ;; keywords like the "in" of "let..in..end") for smie-indent-after-keyword.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
219 ;; Of course, maybe those things would be even better handled in the
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
220 ;; bnf->prec function.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
221 "Take a 2D precedence table and turn it into an alist of precedence levels.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
222 PREC2 is a table as returned by `smie-precs-precedence-table' or
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
223 `smie-bnf-precedence-table'."
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
224 ;; For each operator, we create two "variables" (corresponding to
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
225 ;; the left and right precedence level), which are represented by
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
226 ;; cons cells. Those are the vary cons cells that appear in the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
227 ;; final `table'. The value of each "variable" is kept in the `car'.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
228 (let ((table ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
229 (csts ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
230 (eqs ())
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
231 tmp x y)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
232 ;; From `prec2' we construct a list of constraints between
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
233 ;; variables (aka "precedence levels"). These can be either
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
234 ;; equality constraints (in `eqs') or `<' constraints (in `csts').
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
235 (maphash (lambda (k v)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
236 (if (setq tmp (assoc (car k) table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
237 (setq x (cddr tmp))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
238 (setq x (cons nil nil))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
239 (push (cons (car k) (cons nil x)) table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
240 (if (setq tmp (assoc (cdr k) table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
241 (setq y (cdr tmp))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
242 (setq y (cons nil (cons nil nil)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
243 (push (cons (cdr k) y) table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
244 (ecase v
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
245 (= (push (cons x y) eqs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
246 (< (push (cons x y) csts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
247 (> (push (cons y x) csts))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
248 prec2)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
249 ;; First process the equality constraints.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
250 (let ((eqs eqs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
251 (while eqs
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
252 (let ((from (caar eqs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
253 (to (cdar eqs)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
254 (setq eqs (cdr eqs))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
255 (if (eq to from)
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
256 nil ;Nothing to do.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
257 (dolist (other-eq eqs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
258 (if (eq from (cdr other-eq)) (setcdr other-eq to))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
259 (when (eq from (car other-eq))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
260 ;; This can happen because of `assoc' settings in precs
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
261 ;; or because of a rhs like ("op" foo "op").
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
262 (setcar other-eq to)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
263 (dolist (cst csts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
264 (if (eq from (cdr cst)) (setcdr cst to))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
265 (if (eq from (car cst)) (setcar cst to)))))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
266 ;; Then eliminate trivial constraints iteratively.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
267 (let ((i 0))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
268 (while csts
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
269 (let ((rhvs (mapcar 'cdr csts))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
270 (progress nil))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
271 (dolist (cst csts)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
272 (unless (memq (car cst) rhvs)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
273 (setq progress t)
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
274 ;; We could give each var in a given iteration the same value,
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
275 ;; but we can also give them arbitrarily different values.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
276 ;; Basically, these are vars between which there is no
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
277 ;; constraint (neither equality nor inequality), so
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
278 ;; anything will do.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
279 ;; We give them arbitrary values, which means that we
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
280 ;; replace the "no constraint" case with either > or <
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
281 ;; but not =. The reason we do that is so as to try and
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
282 ;; distinguish associative operators (which will have
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
283 ;; left = right).
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
284 (unless (caar cst)
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
285 (setcar (car cst) i)
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
286 (incf i))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
287 (setq csts (delq cst csts))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
288 (unless progress
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
289 (error "Can't resolve the precedence table to precedence levels")))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
290 (incf i 10))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
291 ;; Propagate equalities back to their source.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
292 (dolist (eq (nreverse eqs))
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
293 (assert (or (null (caar eq)) (eq (car eq) (cdr eq))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
294 (setcar (car eq) (cadr eq)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
295 ;; Finally, fill in the remaining vars (which only appeared on the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
296 ;; right side of the < constraints).
108766
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
297 (dolist (x table)
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
298 ;; When both sides are nil, it means this operator binds very
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
299 ;; very tight, but it's still just an operator, so we give it
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
300 ;; the highest precedence.
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
301 ;; OTOH if only one side is nil, it usually means it's like an
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
302 ;; open-paren, which is very important for indentation purposes,
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
303 ;; so we keep it nil, to make it easier to recognize.
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
304 (unless (or (nth 1 x) (nth 2 x))
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
305 (setf (nth 1 x) i)
2f547b05b620 * emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108652
diff changeset
306 (setf (nth 2 x) i))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
307 table))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
308
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
309 ;;; Parsing using a precedence level table.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
310
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
311 (defvar smie-op-levels 'unset
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
312 "List of token parsing info.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
313 Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL).
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
314 Parsing is done using an operator precedence parser.
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
315 LEFT-LEVEL and RIGHT-LEVEL can be either numbers or nil, where nil
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
316 means that this operator does not bind on the corresponding side,
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
317 i.e. a LEFT-LEVEL of nil means this is a token that behaves somewhat like
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
318 an open-paren, whereas a RIGHT-LEVEL of nil would correspond to something
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
319 like a close-paren.")
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
320
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
321 (defvar smie-forward-token-function 'smie-default-forward-token
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
322 "Function to scan forward for the next token.
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
323 Called with no argument should return a token and move to its end.
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
324 If no token is found, return nil or the empty string.
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
325 It can return nil when bumping into a parenthesis, which lets SMIE
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
326 use syntax-tables to handle them in efficient C code.")
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
327
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
328 (defvar smie-backward-token-function 'smie-default-backward-token
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
329 "Function to scan backward the previous token.
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
330 Same calling convention as `smie-forward-token-function' except
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
331 it should move backward to the beginning of the previous token.")
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
332
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
333 (defalias 'smie-op-left 'car)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
334 (defalias 'smie-op-right 'cadr)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
335
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
336 (defun smie-default-backward-token ()
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
337 (forward-comment (- (point)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
338 (buffer-substring-no-properties
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
339 (point)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
340 (progn (if (zerop (skip-syntax-backward "."))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
341 (skip-syntax-backward "w_'"))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
342 (point))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
343
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
344 (defun smie-default-forward-token ()
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
345 (forward-comment (point-max))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
346 (buffer-substring-no-properties
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
347 (point)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
348 (progn (if (zerop (skip-syntax-forward "."))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
349 (skip-syntax-forward "w_'"))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
350 (point))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
351
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
352 (defun smie-associative-p (toklevels)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
353 ;; in "a + b + c" we want to stop at each +, but in
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
354 ;; "if a then b elsif c then d else c" we don't want to stop at each keyword.
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
355 ;; To distinguish the two cases, we made smie-prec2-levels choose
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
356 ;; different levels for each part of "if a then b else c", so that
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
357 ;; by checking if the left-level is equal to the right level, we can
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
358 ;; figure out that it's an associative operator.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
359 ;; This is not 100% foolproof, tho, since the "elsif" will have to have
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
360 ;; equal left and right levels (since it's optional), so smie-next-sexp
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
361 ;; has to be careful to distinguish those different cases.
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
362 (eq (smie-op-left toklevels) (smie-op-right toklevels)))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
363
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
364 (defun smie-next-sexp (next-token next-sexp op-forw op-back halfsexp)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
365 "Skip over one sexp.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
366 NEXT-TOKEN is a function of no argument that moves forward by one
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
367 token (after skipping comments if needed) and returns it.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
368 NEXT-SEXP is a lower-level function to skip one sexp.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
369 OP-FORW is the accessor to the forward level of the level data.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
370 OP-BACK is the accessor to the backward level of the level data.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
371 HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
372 first token we see is an operator, skip over its left-hand-side argument.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
373 Possible return values:
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
374 (FORW-LEVEL POS TOKEN): we couldn't skip TOKEN because its back-level
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
375 is too high. FORW-LEVEL is the forw-level of TOKEN,
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
376 POS is its start position in the buffer.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
377 (t POS TOKEN): same thing when we bump on the wrong side of a paren.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
378 (nil POS TOKEN): we skipped over a paren-like pair.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
379 nil: we skipped over an identifier, matched parentheses, ..."
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
380 (catch 'return
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
381 (let ((levels ()))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
382 (while
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
383 (let* ((pos (point))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
384 (token (funcall next-token))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
385 (toklevels (cdr (assoc token smie-op-levels))))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
386 (cond
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
387 ((null toklevels)
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
388 (when (zerop (length token))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
389 (condition-case err
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
390 (progn (goto-char pos) (funcall next-sexp 1) nil)
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
391 (scan-error (throw 'return
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
392 (list t (caddr err)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
393 (buffer-substring-no-properties
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
394 (caddr err)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
395 (+ (caddr err)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
396 (if (< (point) (caddr err))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
397 -1 1)))))))
108652
79ce86edba9f * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108649
diff changeset
398 (if (eq pos (point))
79ce86edba9f * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108649
diff changeset
399 ;; We did not move, so let's abort the loop.
79ce86edba9f * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108649
diff changeset
400 (throw 'return (list t (point))))))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
401 ((null (funcall op-back toklevels))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
402 ;; A token like a paren-close.
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
403 (assert (funcall op-forw toklevels)) ;Otherwise, why mention it?
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
404 (push toklevels levels))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
405 (t
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
406 (while (and levels (< (funcall op-back toklevels)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
407 (funcall op-forw (car levels))))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
408 (setq levels (cdr levels)))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
409 (cond
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
410 ((null levels)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
411 (if (and halfsexp (funcall op-forw toklevels))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
412 (push toklevels levels)
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
413 (throw 'return
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
414 (prog1 (list (or (car toklevels) t) (point) token)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
415 (goto-char pos)))))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
416 (t
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
417 (let ((lastlevels levels))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
418 (if (and levels (= (funcall op-back toklevels)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
419 (funcall op-forw (car levels))))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
420 (setq levels (cdr levels)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
421 ;; We may have found a match for the previously pending
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
422 ;; operator. Is this the end?
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
423 (cond
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
424 ;; Keep looking as long as we haven't matched the
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
425 ;; topmost operator.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
426 (levels
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
427 (if (funcall op-forw toklevels)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
428 (push toklevels levels)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
429 ;; We matched the topmost operator. If the new operator
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
430 ;; is the last in the corresponding BNF rule, we're done.
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
431 ((null (funcall op-forw toklevels))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
432 ;; It is the last element, let's stop here.
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
433 (throw 'return (list nil (point) token)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
434 ;; If the new operator is not the last in the BNF rule,
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
435 ;; ans is not associative, it's one of the inner operators
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
436 ;; (like the "in" in "let .. in .. end"), so keep looking.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
437 ((not (smie-associative-p toklevels))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
438 (push toklevels levels))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
439 ;; The new operator is associative. Two cases:
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
440 ;; - it's really just an associative operator (like + or ;)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
441 ;; in which case we should have stopped right before.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
442 ((and lastlevels
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
443 (smie-associative-p (car lastlevels)))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
444 (throw 'return
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
445 (prog1 (list (or (car toklevels) t) (point) token)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
446 (goto-char pos))))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
447 ;; - it's an associative operator within a larger construct
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
448 ;; (e.g. an "elsif"), so we should just ignore it and keep
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
449 ;; looking for the closing element.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
450 (t (setq levels lastlevels))))))))
108649
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
451 levels)
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
452 (setq halfsexp nil)))))
c9e786f54683 Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108642
diff changeset
453
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
454 (defun smie-backward-sexp (&optional halfsexp)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
455 "Skip over one sexp.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
456 HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
457 first token we see is an operator, skip over its left-hand-side argument.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
458 Possible return values:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
459 (LEFT-LEVEL POS TOKEN): we couldn't skip TOKEN because its right-level
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
460 is too high. LEFT-LEVEL is the left-level of TOKEN,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
461 POS is its start position in the buffer.
108642
66f3c521df14 * emacs-lisp/smie.el: Fix typos in docstrings.
Juanma Barranquero <lekktu@gmail.com>
parents: 108632
diff changeset
462 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
463 (nil POS TOKEN): we skipped over a paren-like pair.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
464 nil: we skipped over an identifier, matched parentheses, ..."
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
465 (smie-next-sexp
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
466 (indirect-function smie-backward-token-function)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
467 (indirect-function 'backward-sexp)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
468 (indirect-function 'smie-op-left)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
469 (indirect-function 'smie-op-right)
108652
79ce86edba9f * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108649
diff changeset
470 halfsexp))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
471
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
472 (defun smie-forward-sexp (&optional halfsexp)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
473 "Skip over one sexp.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
474 HALFSEXP if non-nil, means skip over a partial sexp if needed. I.e. if the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
475 first token we see is an operator, skip over its left-hand-side argument.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
476 Possible return values:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
477 (RIGHT-LEVEL POS TOKEN): we couldn't skip TOKEN because its left-level
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
478 is too high. RIGHT-LEVEL is the right-level of TOKEN,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
479 POS is its end position in the buffer.
108642
66f3c521df14 * emacs-lisp/smie.el: Fix typos in docstrings.
Juanma Barranquero <lekktu@gmail.com>
parents: 108632
diff changeset
480 (t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
481 (nil POS TOKEN): we skipped over a paren-like pair.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
482 nil: we skipped over an identifier, matched parentheses, ..."
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
483 (smie-next-sexp
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
484 (indirect-function smie-forward-token-function)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
485 (indirect-function 'forward-sexp)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
486 (indirect-function 'smie-op-right)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
487 (indirect-function 'smie-op-left)
108652
79ce86edba9f * emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108649
diff changeset
488 halfsexp))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
489
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
490 ;;; Miscellanous commands using the precedence parser.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
491
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
492 (defun smie-backward-sexp-command (&optional n)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
493 "Move backward through N logical elements."
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
494 (interactive "^p")
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
495 (smie-forward-sexp-command (- n)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
496
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
497 (defun smie-forward-sexp-command (&optional n)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
498 "Move forward through N logical elements."
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
499 (interactive "^p")
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
500 (let ((forw (> n 0))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
501 (forward-sexp-function nil))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
502 (while (/= n 0)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
503 (setq n (- n (if forw 1 -1)))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
504 (let ((pos (point))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
505 (res (if forw
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
506 (smie-forward-sexp 'halfsexp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
507 (smie-backward-sexp 'halfsexp))))
109840
51f5fd9b5515 * smie.el (smie-forward-sexp-command): Fix typo.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109838
diff changeset
508 (if (and (car res) (= pos (point)) (not (if forw (eobp) (bobp))))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
509 (signal 'scan-error
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
510 (list "Containing expression ends prematurely"
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
511 (cadr res) (cadr res)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
512 nil)))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
513
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
514 (defvar smie-closer-alist nil
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
515 "Alist giving the closer corresponding to an opener.")
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
516
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
517 (defun smie-close-block ()
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
518 "Close the closest surrounding block."
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
519 (interactive)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
520 (let ((closer
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
521 (save-excursion
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
522 (backward-up-list 1)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
523 (if (looking-at "\\s(")
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
524 (string (cdr (syntax-after (point))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
525 (let* ((open (funcall smie-forward-token-function))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
526 (closer (cdr (assoc open smie-closer-alist)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
527 (levels (list (assoc open smie-op-levels)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
528 (seen '())
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
529 (found '()))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
530 (cond
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
531 ;; Even if we improve the auto-computation of closers,
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
532 ;; there are still cases where we need manual
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
533 ;; intervention, e.g. for Octave's use of `until'
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
534 ;; as a pseudo-closer of `do'.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
535 (closer)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
536 ((or (equal levels '(nil)) (nth 1 (car levels)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
537 (error "Doesn't look like a block"))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
538 (t
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
539 ;; FIXME: With grammars like Octave's, every closer ("end",
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
540 ;; "endif", "endwhile", ...) has the same level, so we'd need
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
541 ;; to look at the BNF or at least at the 2D prec-table, in
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
542 ;; order to find the right closer for a given opener.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
543 (while levels
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
544 (let ((level (pop levels)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
545 (dolist (other smie-op-levels)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
546 (when (and (eq (nth 2 level) (nth 1 other))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
547 (not (memq other seen)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
548 (push other seen)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
549 (if (nth 2 other)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
550 (push other levels)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
551 (push (car other) found))))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
552 (cond
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
553 ((null found) (error "No known closer for opener %s" open))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
554 ;; FIXME: what should we do if there are various closers?
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
555 (t (car found))))))))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
556 (unless (save-excursion (skip-chars-backward " \t") (bolp))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
557 (newline))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
558 (insert closer)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
559 (if (save-excursion (skip-chars-forward " \t") (eolp))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
560 (indent-according-to-mode)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
561 (reindent-then-newline-and-indent))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
562
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
563 ;;; The indentation engine.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
564
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
565 (defcustom smie-indent-basic 4
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
566 "Basic amount of indentation."
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
567 :type 'integer)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
568
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
569 (defvar smie-indent-rules 'unset
108864
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
570 ;; TODO: For SML, we need more rule formats, so as to handle
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
571 ;; structure Foo =
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
572 ;; Bar (toto)
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
573 ;; and
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
574 ;; structure Foo =
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
575 ;; struct ... end
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
576 ;; I.e. the indentation after "=" depends on the parent ("structure")
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
577 ;; as well as on the following token ("struct").
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
578 "Rules of the following form.
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
579 \((:before . TOK) . OFFSET-RULES) how to indent TOK itself.
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
580 \(TOK . OFFSET-RULES) how to indent right after TOK.
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
581 \(list-intro . TOKENS) declare TOKENS as being followed by what may look like
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
582 a funcall but is just a sequence of expressions.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
583 \(t . OFFSET) basic indentation step.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
584 \(args . OFFSET) indentation of arguments.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
585 \((T1 . T2) OFFSET) like ((:before . T2) (:parent T1 OFFSET)).
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
586
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
587 OFFSET-RULES is a list of elements which can each either be:
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
588
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
589 \(:hanging . OFFSET-RULES) if TOK is hanging, use OFFSET-RULES.
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
590 \(:parent PARENT . OFFSET-RULES) if TOK's parent is PARENT, use OFFSET-RULES.
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
591 \(:next TOKEN . OFFSET-RULES) if TOK is followed by TOKEN, use OFFSET-RULES.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
592 \(:prev TOKEN . OFFSET-RULES) if TOK is preceded by TOKEN, use
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
593 \(:bolp . OFFSET-RULES) If TOK is first on a line, use OFFSET-RULES.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
594 OFFSET the offset to use.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
595
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
596 PARENT can be either the name of the parent or a list of such names.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
597
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
598 OFFSET can be of the form:
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
599 `point' align with the token.
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
600 `parent' align with the parent.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
601 NUMBER offset by NUMBER.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
602 \(+ OFFSETS...) use the sum of OFFSETS.
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
603 VARIABLE use the value of VARIABLE as offset.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
604
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
605 The precise meaning of `point' depends on various details: it can
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
606 either mean the position of the token we're indenting, or the
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
607 position of its parent, or the position right after its parent.
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
608
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
609 A nil offset for indentation after an opening token defaults
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
610 to `smie-indent-basic'.")
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
611
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
612 (defun smie-indent-hanging-p ()
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
613 ;; A hanging keyword is one that's at the end of a line except it's not at
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
614 ;; the beginning of a line.
108797
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
615 (and (save-excursion
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
616 (when (zerop (length (funcall smie-forward-token-function)))
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
617 ;; Could be an open-paren.
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
618 (forward-char 1))
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
619 (skip-chars-forward " \t")
d674108e8753 Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108766
diff changeset
620 (eolp))
108864
f241d9fe71fe * lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108797
diff changeset
621 (not (smie-bolp))))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
622
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
623 (defun smie-bolp ()
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
624 (save-excursion (skip-chars-backward " \t") (bolp)))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
625
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
626 (defun smie-indent-offset (elem)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
627 (or (cdr (assq elem smie-indent-rules))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
628 (cdr (assq t smie-indent-rules))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
629 smie-indent-basic))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
630
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
631 (defvar smie-indent-debug-log)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
632
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
633 (defun smie-indent-offset-rule (tokinfo &optional after parent)
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
634 "Apply the OFFSET-RULES in TOKINFO.
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
635 Point is expected to be right in front of the token corresponding to TOKINFO.
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
636 If computing the indentation after the token, then AFTER is the position
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
637 after the token, otherwise it should be nil.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
638 PARENT if non-nil should be the parent info returned by `smie-backward-sexp'."
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
639 (let ((rules (cdr tokinfo))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
640 next prev
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
641 offset)
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
642 (while (consp rules)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
643 (let ((rule (pop rules)))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
644 (cond
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
645 ((not (consp rule)) (setq offset rule))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
646 ((eq (car rule) '+) (setq offset rule))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
647 ((eq (car rule) :hanging)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
648 (when (smie-indent-hanging-p)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
649 (setq rules (cdr rule))))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
650 ((eq (car rule) :bolp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
651 (when (smie-bolp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
652 (setq rules (cdr rule))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
653 ((eq (car rule) :eolp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
654 (unless after
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
655 (error "Can't use :eolp in :before indentation rules"))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
656 (when (> after (line-end-position))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
657 (setq rules (cdr rule))))
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
658 ((eq (car rule) :prev)
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
659 (unless prev
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
660 (save-excursion
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
661 (setq prev (smie-indent-backward-token))))
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
662 (when (equal (car prev) (cadr rule))
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
663 (setq rules (cddr rule))))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
664 ((eq (car rule) :next)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
665 (unless next
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
666 (unless after
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
667 (error "Can't use :next in :before indentation rules"))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
668 (save-excursion
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
669 (goto-char after)
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
670 (setq next (smie-indent-forward-token))))
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
671 (when (equal (car next) (cadr rule))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
672 (setq rules (cddr rule))))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
673 ((eq (car rule) :parent)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
674 (unless parent
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
675 (save-excursion
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
676 (if after (goto-char after))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
677 (setq parent (smie-backward-sexp 'halfsexp))))
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
678 (when (if (listp (cadr rule))
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
679 (member (nth 2 parent) (cadr rule))
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
680 (equal (nth 2 parent) (cadr rule)))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
681 (setq rules (cddr rule))))
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
682 (t (error "Unknown rule %s for indentation of %s"
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
683 rule (car tokinfo))))))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
684 ;; If `offset' is not set yet, use `rules' to handle the case where
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
685 ;; the tokinfo uses the old-style ((PARENT . TOK). OFFSET).
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
686 (unless offset (setq offset rules))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
687 (when (boundp 'smie-indent-debug-log)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
688 (push (list (point) offset tokinfo) smie-indent-debug-log))
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
689 offset))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
690
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
691 (defun smie-indent-column (offset &optional base parent virtual-point)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
692 "Compute the actual column to use for a given OFFSET.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
693 BASE is the base position to use, and PARENT is the parent info, if any.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
694 If VIRTUAL-POINT is non-nil, then `point' is virtual."
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
695 (cond
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
696 ((eq (car-safe offset) '+)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
697 (apply '+ (mapcar (lambda (offset) (smie-indent-column offset nil parent))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
698 (cdr offset))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
699 ((integerp offset)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
700 (+ offset
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
701 (case base
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
702 ((nil) 0)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
703 (parent (goto-char (cadr parent))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
704 (smie-indent-virtual))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
705 (t
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
706 (goto-char base)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
707 ;; For indentation after "(let" in SML-mode, we end up accumulating
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
708 ;; the offset of "(" and the offset of "let", so we use `min' to try
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
709 ;; and get it right either way.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
710 (min (smie-indent-virtual) (current-column))))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
711 ((eq offset 'point)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
712 ;; In indent-keyword, if we're indenting `then' wrt `if', we want to use
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
713 ;; indent-virtual rather than use just current-column, so that we can
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
714 ;; apply the (:before . "if") rule which does the "else if" dance in SML.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
715 ;; But in other cases, we do not want to use indent-virtual
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
716 ;; (e.g. indentation of "*" w.r.t "+", or ";" wrt "("). We could just
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
717 ;; always use indent-virtual and then have indent-rules say explicitly
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
718 ;; to use `point' after things like "(" or "+" when they're not at EOL,
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
719 ;; but you'd end up with lots of those rules.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
720 ;; So we use a heuristic here, which is that we only use virtual if
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
721 ;; the parent is tightly linked to the child token (they're part of
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
722 ;; the same BNF rule).
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
723 (if (and virtual-point (null (car parent))) ;Black magic :-(
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
724 (smie-indent-virtual) (current-column)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
725 ((eq offset 'parent)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
726 (unless parent
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
727 (setq parent (or (smie-backward-sexp 'halfsexp) :notfound)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
728 (if (consp parent) (goto-char (cadr parent)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
729 (smie-indent-virtual))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
730 ((eq offset nil) nil)
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
731 ((and (symbolp offset) (boundp 'offset))
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
732 (smie-indent-column (symbol-value offset) base parent virtual-point))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
733 (t (error "Unknown indentation offset %s" offset))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
734
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
735 (defun smie-indent-forward-token ()
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
736 "Skip token forward and return it, along with its levels."
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
737 (let ((tok (funcall smie-forward-token-function)))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
738 (cond
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
739 ((< 0 (length tok)) (assoc tok smie-op-levels))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
740 ((looking-at "\\s(")
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
741 (forward-char 1)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
742 (list (buffer-substring (1- (point)) (point)) nil 0)))))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
743
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
744 (defun smie-indent-backward-token ()
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
745 "Skip token backward and return it, along with its levels."
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
746 (let ((tok (funcall smie-backward-token-function)))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
747 (cond
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
748 ((< 0 (length tok)) (assoc tok smie-op-levels))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
749 ;; 4 == Open paren syntax.
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
750 ((eq 4 (syntax-class (syntax-after (1- (point)))))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
751 (forward-char -1)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
752 (list (buffer-substring (point) (1+ (point))) nil 0)))))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
753
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
754 (defun smie-indent-virtual ()
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
755 ;; We used to take an optional arg (with value :not-hanging) to specify that
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
756 ;; we should only use (smie-indent-calculate) if we're looking at a hanging
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
757 ;; keyword. This was a bad idea, because the virtual indent of a position
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
758 ;; should not depend on the caller, since it leads to situations where two
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
759 ;; dependent indentations get indented differently.
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
760 "Compute the virtual indentation to use for point.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
761 This is used when we're not trying to indent point but just
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
762 need to compute the column at which point should be indented
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
763 in order to figure out the indentation of some other (further down) point."
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
764 ;; Trust pre-existing indentation on other lines.
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
765 (if (smie-bolp) (current-column) (smie-indent-calculate)))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
766
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
767 (defun smie-indent-fixindent ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
768 ;; Obey the `fixindent' special comment.
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
769 (and (smie-bolp)
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
770 (save-excursion
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
771 (comment-normalize-vars)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
772 (re-search-forward (concat comment-start-skip
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
773 "fixindent"
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
774 comment-end-skip)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
775 ;; 1+ to account for the \n comment termination.
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
776 (1+ (line-end-position)) t))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
777 (current-column)))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
778
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
779 (defun smie-indent-bob ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
780 ;; Start the file at column 0.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
781 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
782 (forward-comment (- (point)))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
783 (if (bobp) 0)))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
784
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
785 (defun smie-indent-close ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
786 ;; Align close paren with opening paren.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
787 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
788 ;; (forward-comment (point-max))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
789 (when (looking-at "\\s)")
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
790 (while (not (zerop (skip-syntax-forward ")")))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
791 (skip-chars-forward " \t"))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
792 (condition-case nil
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
793 (progn
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
794 (backward-sexp 1)
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
795 (smie-indent-virtual)) ;:not-hanging
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
796 (scan-error nil)))))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
797
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
798 (defun smie-indent-keyword ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
799 ;; Align closing token with the corresponding opening one.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
800 ;; (e.g. "of" with "case", or "in" with "let").
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
801 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
802 (let* ((pos (point))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
803 (toklevels (smie-indent-forward-token))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
804 (token (pop toklevels)))
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
805 (if (null (car toklevels))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
806 (save-excursion
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
807 (goto-char pos)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
808 ;; Different cases:
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
809 ;; - smie-bolp: "indent according to others".
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
810 ;; - common hanging: "indent according to others".
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
811 ;; - SML-let hanging: "indent like parent".
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
812 ;; - if-after-else: "indent-like parent".
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
813 ;; - middle-of-line: "trust current position".
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
814 (cond
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
815 ((null (cdr toklevels)) nil) ;Not a keyword.
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
816 ((smie-bolp)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
817 ;; For an open-paren-like thingy at BOL, always indent only
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
818 ;; based on other rules (typically smie-indent-after-keyword).
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
819 nil)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
820 (t
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
821 ;; We're only ever here for virtual-indent, which is why
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
822 ;; we can use (current-column) as answer for `point'.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
823 (let* ((tokinfo (or (assoc (cons :before token)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
824 smie-indent-rules)
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
825 ;; By default use point unless we're hanging.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
826 `((:before . ,token) (:hanging nil) point)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
827 ;; (after (prog1 (point) (goto-char pos)))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
828 (offset (smie-indent-offset-rule tokinfo)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
829 (smie-indent-column offset)))))
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
830
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
831 ;; FIXME: This still looks too much like black magic!!
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
832 ;; FIXME: Rather than a bunch of rules like (PARENT . TOKEN), we
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
833 ;; want a single rule for TOKEN with different cases for each PARENT.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
834 (let* ((parent (smie-backward-sexp 'halfsexp))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
835 (tokinfo
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
836 (or (assoc (cons (caddr parent) token)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
837 smie-indent-rules)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
838 (assoc (cons :before token) smie-indent-rules)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
839 ;; Default rule.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
840 `((:before . ,token)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
841 ;; (:parent open 0)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
842 point)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
843 (offset (save-excursion
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
844 (goto-char pos)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
845 (smie-indent-offset-rule tokinfo nil parent))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
846 ;; Different behaviors:
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
847 ;; - align with parent.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
848 ;; - parent + offset.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
849 ;; - after parent's column + offset (actually, after or before
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
850 ;; depending on where backward-sexp stopped).
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
851 ;; ? let it drop to some other indentation function (almost never).
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
852 ;; ? parent + offset + parent's own offset.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
853 ;; Different cases:
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
854 ;; - bump into a same-level operator.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
855 ;; - bump into a specific known parent.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
856 ;; - find a matching open-paren thingy.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
857 ;; - bump into some random parent.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
858 ;; ? borderline case (almost never).
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
859 ;; ? bump immediately into a parent.
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
860 (cond
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
861 ((not (or (< (point) pos)
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
862 (and (cadr parent) (< (cadr parent) pos))))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
863 ;; If we didn't move at all, that means we didn't really skip
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
864 ;; what we wanted. Should almost never happen, other than
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
865 ;; maybe when an infix or close-paren is at the beginning
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
866 ;; of a buffer.
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
867 nil)
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
868 ((eq (car parent) (car toklevels))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
869 ;; We bumped into a same-level operator. align with it.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
870 (if (and (smie-bolp) (/= (point) pos)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
871 (save-excursion
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
872 (goto-char (goto-char (cadr parent)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
873 (not (smie-bolp)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
874 ;; Check the offset of `token' rather then its parent
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
875 ;; because its parent may have used a special rule. E.g.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
876 ;; function foo;
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
877 ;; line2;
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
878 ;; line3;
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
879 ;; The ; on the first line had a special rule, but when
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
880 ;; indenting line3, we don't care about it and want to
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
881 ;; align with line2.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
882 (memq offset '(point nil)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
883 ;; If the parent is at EOL and its children are indented like
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
884 ;; itself, then we can just obey the indentation chosen for the
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
885 ;; child.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
886 ;; This is important for operators like ";" which
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
887 ;; are usually at EOL (and have an offset of 0): otherwise we'd
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
888 ;; always go back over all the statements, which is
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
889 ;; a performance problem and would also mean that fixindents
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
890 ;; in the middle of such a sequence would be ignored.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
891 ;;
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
892 ;; This is a delicate point!
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
893 ;; Even if the offset is not 0, we could follow the same logic
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
894 ;; and subtract the offset from the child's indentation.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
895 ;; But that would more often be a bad idea: OT1H we generally
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
896 ;; want to reuse the closest similar indentation point, so that
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
897 ;; the user's choice (or the fixindents) are obeyed. But OTOH
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
898 ;; we don't want this to affect "unrelated" parts of the code.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
899 ;; E.g. a fixindent in the body of a "begin..end" should not
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
900 ;; affect the indentation of the "end".
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
901 (current-column)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
902 (goto-char (cadr parent))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
903 ;; Don't use (smie-indent-virtual :not-hanging) here, because we
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
904 ;; want to jump back over a sequence of same-level ops such as
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
905 ;; a -> b -> c
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
906 ;; -> d
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
907 ;; So as to align with the earliest appropriate place.
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
908 (smie-indent-virtual)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
909 (tokinfo
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
910 (if (and (= (point) pos) (smie-bolp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
911 (or (eq offset 'point)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
912 (and (consp offset) (memq 'point offset))))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
913 ;; Since we started at BOL, we're not computing a virtual
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
914 ;; indentation, and we're still at the starting point, so
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
915 ;; we can't use `current-column' which would cause
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
916 ;; indentation to depend on itself.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
917 nil
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
918 (smie-indent-column offset 'parent parent
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
919 ;; If we're still at pos, indent-virtual
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
920 ;; will inf-loop.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
921 (unless (= (point) pos) 'virtual))))))))))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
922
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
923 (defun smie-indent-comment ()
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
924 "Compute indentation of a comment."
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
925 ;; Don't do it for virtual indentations. We should normally never be "in
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
926 ;; front of a comment" when doing virtual-indentation anyway. And if we are
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
927 ;; (as can happen in octave-mode), moving forward can lead to inf-loops.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
928 (and (smie-bolp)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
929 (looking-at comment-start-skip)
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
930 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
931 (forward-comment (point-max))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
932 (skip-chars-forward " \t\r\n")
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
933 (smie-indent-calculate))))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
934
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
935 (defun smie-indent-comment-continue ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
936 ;; indentation of comment-continue lines.
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
937 (let ((continue (and comment-continue
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
938 (comment-string-strip comment-continue t t))))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
939 (and (< 0 (length continue))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
940 (looking-at (regexp-quote continue)) (nth 4 (syntax-ppss))
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
941 (let ((ppss (syntax-ppss)))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
942 (save-excursion
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
943 (forward-line -1)
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
944 (if (<= (point) (nth 8 ppss))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
945 (progn (goto-char (1+ (nth 8 ppss))) (current-column))
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
946 (skip-chars-forward " \t")
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
947 (if (looking-at (regexp-quote continue))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
948 (current-column))))))))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
949
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
950 (defun smie-indent-after-keyword ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
951 ;; Indentation right after a special keyword.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
952 (save-excursion
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
953 (let* ((pos (point))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
954 (toklevel (smie-indent-backward-token))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
955 (tok (car toklevel))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
956 (tokinfo (assoc tok smie-indent-rules)))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
957 ;; Set some default indent rules.
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
958 (if (and toklevel (null (cadr toklevel)) (null tokinfo))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
959 (setq tokinfo (list (car toklevel))))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
960 ;; (if (and tokinfo (null toklevel))
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
961 ;; (error "Token %S has indent rule but has no parsing info" tok))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
962 (when toklevel
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
963 (unless tokinfo
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
964 ;; The default indentation after a keyword/operator is 0 for
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
965 ;; infix and t for prefix.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
966 ;; Using the BNF syntax, we could come up with better
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
967 ;; defaults, but we only have the precedence levels here.
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
968 (setq tokinfo (list tok 'default-rule
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
969 (if (cadr toklevel) 0 (smie-indent-offset t)))))
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
970 (let ((offset
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
971 (or (smie-indent-offset-rule tokinfo pos)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
972 (smie-indent-offset t))))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
973 (let ((before (point)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
974 (goto-char pos)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
975 (smie-indent-column offset before)))))))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
976
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
977 (defun smie-indent-exps ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
978 ;; Indentation of sequences of simple expressions without
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
979 ;; intervening keywords or operators. E.g. "a b c" or "g (balbla) f".
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
980 ;; Can be a list of expressions or a function call.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
981 ;; If it's a function call, the first element is special (it's the
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
982 ;; function). We distinguish function calls from mere lists of
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
983 ;; expressions based on whether the preceding token is listed in
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
984 ;; the `list-intro' entry of smie-indent-rules.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
985 ;;
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
986 ;; TODO: to indent Lisp code, we should add a way to specify
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
987 ;; particular indentation for particular args depending on the
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
988 ;; function (which would require always skipping back until the
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
989 ;; function).
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
990 ;; TODO: to indent C code, such as "if (...) {...}" we might need
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
991 ;; to add similar indentation hooks for particular positions, but
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
992 ;; based on the preceding token rather than based on the first exp.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
993 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
994 (let ((positions nil)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
995 arg)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
996 (while (and (null (car (smie-backward-sexp)))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
997 (push (point) positions)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
998 (not (smie-bolp))))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
999 (save-excursion
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1000 ;; Figure out if the atom we just skipped is an argument rather
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1001 ;; than a function.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1002 (setq arg (or (null (car (smie-backward-sexp)))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1003 (member (funcall smie-backward-token-function)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1004 (cdr (assoc 'list-intro smie-indent-rules))))))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1005 (cond
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1006 ((null positions)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1007 ;; We're the first expression of the list. In that case, the
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1008 ;; indentation should be (have been) determined by its context.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1009 nil)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1010 (arg
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1011 ;; There's a previous element, and it's not special (it's not
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1012 ;; the function), so let's just align with that one.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1013 (goto-char (car positions))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1014 (current-column))
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1015 ((cdr positions)
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1016 ;; We skipped some args plus the function and bumped into something.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1017 ;; Align with the first arg.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1018 (goto-char (cadr positions))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1019 (current-column))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1020 (positions
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1021 ;; We're the first arg.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1022 (goto-char (car positions))
110036
af3f1edc363f * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109841
diff changeset
1023 ;; FIXME: Use smie-indent-column.
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1024 (+ (smie-indent-offset 'args)
108897
68586a267c40 * lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108894
diff changeset
1025 ;; We used to use (smie-indent-virtual), but that
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1026 ;; doesn't seem right since it might then indent args less than
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1027 ;; the function itself.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1028 (current-column)))))))
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1029
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1030 (defvar smie-indent-functions
108894
ca3bfaa18e56 Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108878
diff changeset
1031 '(smie-indent-fixindent smie-indent-bob smie-indent-close smie-indent-comment
109841
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
1032 smie-indent-comment-continue smie-indent-keyword smie-indent-after-keyword
3a11454ef7ca Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 109840
diff changeset
1033 smie-indent-exps)
108865
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1034 "Functions to compute the indentation.
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1035 Each function is called with no argument, shouldn't move point, and should
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1036 return either nil if it has no opinion, or an integer representing the column
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1037 to which that point should be aligned, if we were to reindent it.")
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1038
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1039 (defun smie-indent-calculate ()
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1040 "Compute the indentation to use for point."
9d8fb76d6857 Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108864
diff changeset
1041 (run-hook-with-args-until-success 'smie-indent-functions))
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1042
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1043 (defun smie-indent-line ()
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1044 "Indent current line using the SMIE indentation engine."
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1045 (interactive)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1046 (let* ((savep (point))
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1047 (indent (condition-case-no-debug nil
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1048 (save-excursion
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1049 (forward-line 0)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1050 (skip-chars-forward " \t")
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1051 (if (>= (point) savep) (setq savep nil))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1052 (or (smie-indent-calculate) 0))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1053 (error 0))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1054 (if (not (numberp indent))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1055 ;; If something funny is used (e.g. `noindent'), return it.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1056 indent
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1057 (if (< indent 0) (setq indent 0)) ;Just in case.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1058 (if savep
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1059 (save-excursion (indent-line-to indent))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1060 (indent-line-to indent)))))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1061
109838
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1062 (defun smie-indent-debug ()
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1063 "Show the rules used to compute indentation of current line."
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1064 (interactive)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1065 (let ((smie-indent-debug-log '()))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1066 (smie-indent-calculate)
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1067 ;; FIXME: please improve!
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1068 (message "%S" smie-indent-debug-log)))
64936c70841e Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 108923
diff changeset
1069
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1070 (defun smie-setup (op-levels indent-rules)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1071 (set (make-local-variable 'smie-indent-rules) indent-rules)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1072 (set (make-local-variable 'smie-op-levels) op-levels)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1073 (set (make-local-variable 'indent-line-function) 'smie-indent-line))
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1074
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1075
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1076 (provide 'smie)
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1077 ;;; smie.el ends here