Mercurial > emacs
annotate lisp/emacs-lisp/smie.el @ 110161:eb977e012180
Provide blink-matching support to SMIE.
* lisp/emacs-lisp/smie.el (smie-bnf-closer-alist): New function.
(smie-blink-matching-triggers, smie-blink-matching-inners): New vars.
(smie-blink-matching-check, smie-blink-matching-open): New functions.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 03 Sep 2010 13:18:45 +0200 |
parents | 5cab4c4229ff |
children | 06323f4d421b |
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 |
110161
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
78 ;; We have 4 different representations of a "grammar": |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
79 ;; - a BNF table, which is a list of BNF rules of the form |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
80 ;; (NONTERM RHS1 ... RHSn) where each RHS is a list of terminals (tokens) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
81 ;; or nonterminals. Any element in these lists which does not appear as |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
82 ;; the `car' of a BNF rule is taken to be a terminal. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
83 ;; - A list of precedences (key word "precs"), is a list, sorted |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
84 ;; from lowest to highest precedence, of precedence classes that |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
85 ;; have the form (ASSOCIATIVITY TERMINAL1 .. TERMINALn), where |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
86 ;; ASSOCIATIVITY can be `assoc', `left', `right' or `nonassoc'. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
87 ;; - a 2 dimensional precedence table (key word "prec2"), is a 2D |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
88 ;; table recording the precedence relation (can be `<', `=', `>', or |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
89 ;; nil) between each pair of tokens. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
90 ;; - a precedence-level table (key word "levels"), while is a alist |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
91 ;; giving for each token its left and right precedence level (a |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
92 ;; number or nil). This is used in `smie-op-levels'. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
93 ;; The prec2 tables are only intermediate data structures: the source |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
94 ;; code normally provides a mix of BNF and precs tables, and then |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
95 ;; turns them into a levels table, which is what's used by the rest of |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
96 ;; the SMIE code. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
97 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
98 (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
|
99 (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
|
100 (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
|
101 (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
|
102 (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
|
103 (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
|
104 ;; 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
|
105 ;; 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
|
106 ;; 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
|
107 ;; 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
|
108 (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
|
109 (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
|
110 (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
|
111 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
112 (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
|
113 "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
|
114 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
|
115 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
|
116 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
|
117 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
|
118 (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
|
119 (dolist (prec precs) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
120 (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
|
121 (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
|
122 '((left . >) (right . <) (assoc . =)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
123 (when selfrule |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
124 (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
|
125 (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
|
126 (let ((op1 '<) (op2 '>)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
127 (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
|
128 (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
|
129 (setq op1 '> op2 '<) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
130 (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
|
131 (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
|
132 (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
|
133 prec2-table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
134 |
108766
2f547b05b620
* emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108652
diff
changeset
|
135 (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
|
136 (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
|
137 (car tables) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
138 (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
|
139 (dolist (table tables) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
140 (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
|
141 (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
|
142 table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
143 prec2))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
144 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
145 (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
|
146 (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
|
147 (first-ops-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
148 (last-ops-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
149 (first-nts-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
150 (last-nts-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
151 (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
|
152 (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
|
153 (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
|
154 again) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
155 (dolist (rules bnf) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
156 (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
|
157 (last-ops ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
158 (first-ops ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
159 (last-nts ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
160 (first-nts ())) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
161 (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
|
162 (assert (consp rhs)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
163 (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
|
164 (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
|
165 (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
|
166 (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
|
167 ;; 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
|
168 ;; 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
|
169 ;; 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
|
170 ;; 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
|
171 ;; 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
|
172 ;; 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
|
173 ;; 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
|
174 ;; 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
|
175 (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
|
176 (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
|
177 (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
|
178 (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
|
179 (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
|
180 (pushnew (car shr) last-nts) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
181 (when (consp (cdr shr)) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
182 (assert (not (member (cadr shr) nts))) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
183 (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
|
184 (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
|
185 (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
|
186 (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
|
187 (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
|
188 ;; 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
|
189 ;; 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
|
190 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
191 (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
|
192 (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
|
193 (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
|
194 (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
|
195 (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
|
196 (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
|
197 (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
|
198 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
199 (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
|
200 ;; 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
|
201 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
202 (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
|
203 (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
|
204 (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
|
205 (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
|
206 (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
|
207 (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
|
208 (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
|
209 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
210 (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
|
211 ;; 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
|
212 (dolist (rules bnf) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
213 (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
|
214 (while (cdr rhs) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
215 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
216 ((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
|
217 (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
|
218 (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
|
219 ((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
|
220 (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
|
221 (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
|
222 (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
|
223 (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
|
224 '= override))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
225 (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
|
226 (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
|
227 prec2)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
228 |
110161
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
229 ;; (defun smie-prec2-closer-alist (prec2 include-inners) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
230 ;; "Build a closer-alist from a PREC2 table. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
231 ;; The return value is in the same form as `smie-closer-alist'. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
232 ;; INCLUDE-INNERS if non-nil means that inner keywords will be included |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
233 ;; in the table, e.g. the table will include things like (\"if\" . \"else\")." |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
234 ;; (let* ((non-openers '()) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
235 ;; (non-closers '()) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
236 ;; ;; For each keyword, this gives the matching openers, if any. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
237 ;; (openers (make-hash-table :test 'equal)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
238 ;; (closers '()) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
239 ;; (done nil)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
240 ;; ;; First, find the non-openers and non-closers. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
241 ;; (maphash (lambda (k v) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
242 ;; (unless (or (eq v '<) (member (cdr k) non-openers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
243 ;; (push (cdr k) non-openers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
244 ;; (unless (or (eq v '>) (member (car k) non-closers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
245 ;; (push (car k) non-closers))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
246 ;; prec2) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
247 ;; ;; Then find the openers and closers. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
248 ;; (maphash (lambda (k _) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
249 ;; (unless (member (car k) non-openers) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
250 ;; (puthash (car k) (list (car k)) openers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
251 ;; (unless (or (member (cdr k) non-closers) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
252 ;; (member (cdr k) closers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
253 ;; (push (cdr k) closers))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
254 ;; prec2) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
255 ;; ;; Then collect the matching elements. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
256 ;; (while (not done) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
257 ;; (setq done t) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
258 ;; (maphash (lambda (k v) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
259 ;; (when (eq v '=) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
260 ;; (let ((aopeners (gethash (car k) openers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
261 ;; (dopeners (gethash (cdr k) openers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
262 ;; (new nil)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
263 ;; (dolist (o aopeners) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
264 ;; (unless (member o dopeners) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
265 ;; (setq new t) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
266 ;; (push o dopeners))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
267 ;; (when new |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
268 ;; (setq done nil) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
269 ;; (puthash (cdr k) dopeners openers))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
270 ;; prec2)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
271 ;; ;; Finally, dump the resulting table. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
272 ;; (let ((alist '())) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
273 ;; (maphash (lambda (k v) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
274 ;; (when (or include-inners (member k closers)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
275 ;; (dolist (opener v) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
276 ;; (unless (equal opener k) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
277 ;; (push (cons opener k) alist))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
278 ;; openers) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
279 ;; alist))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
280 |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
281 (defun smie-bnf-closer-alist (bnf &optional no-inners) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
282 ;; We can also build this closer-alist table from a prec2 table, |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
283 ;; but it takes more work, and the order is unpredictable, which |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
284 ;; is a problem for smie-close-block. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
285 ;; More convenient would be to build it from a levels table since we |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
286 ;; always have this table (contrary to the BNF), but it has all the |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
287 ;; disadvantages of the prec2 case plus the disadvantage that the levels |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
288 ;; table has lost some info which would result in extra invalid pairs. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
289 "Build a closer-alist from a BNF table. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
290 The return value is in the same form as `smie-closer-alist'. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
291 NO-INNERS if non-nil means that inner keywords will be excluded |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
292 from the table, e.g. the table will not include things like (\"if\" . \"else\")." |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
293 (let ((nts (mapcar #'car bnf)) ;non terminals. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
294 (alist '())) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
295 (dolist (nt bnf) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
296 (dolist (rhs (cdr nt)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
297 (unless (or (< (length rhs) 2) (member (car rhs) nts)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
298 (if no-inners |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
299 (let ((last (car (last rhs)))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
300 (unless (member last nts) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
301 (pushnew (cons (car rhs) last) alist :test #'equal))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
302 ;; Reverse so that the "real" closer gets there first, |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
303 ;; which is important for smie-close-block. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
304 (dolist (term (reverse (cdr rhs))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
305 (unless (member term nts) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
306 (pushnew (cons (car rhs) term) alist :test #'equal))))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
307 (nreverse alist))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
308 |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
309 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
310 (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
|
311 ;; 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
|
312 ;; 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
|
313 ;; - 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
|
314 ;; 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
|
315 ;; 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
|
316 ;; 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
|
317 ;; 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
|
318 ;; - 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
|
319 ;; 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
|
320 ;; 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
|
321 ;; 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
|
322 "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
|
323 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
|
324 `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
|
325 ;; 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
|
326 ;; the left and right precedence level), which are represented by |
110161
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
327 ;; cons cells. Those are the very cons cells that appear in the |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
328 ;; 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
|
329 (let ((table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
330 (csts ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
331 (eqs ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
332 tmp x y) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
333 ;; 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
|
334 ;; 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
|
335 ;; 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
|
336 (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
|
337 (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
|
338 (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
|
339 (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
|
340 (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
|
341 (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
|
342 (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
|
343 (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
|
344 (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
|
345 (ecase v |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
346 (= (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
|
347 (< (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
|
348 (> (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
|
349 prec2) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
350 ;; 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
|
351 (let ((eqs eqs)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
352 (while eqs |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
353 (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
|
354 (to (cdar eqs))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
355 (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
|
356 (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
|
357 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
|
358 (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
|
359 (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
|
360 (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
|
361 ;; 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
|
362 ;; 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
|
363 (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
|
364 (dolist (cst csts) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
365 (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
|
366 (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
|
367 ;; 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
|
368 (let ((i 0)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
369 (while csts |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
370 (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
|
371 (progress nil)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
372 (dolist (cst csts) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
373 (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
|
374 (setq progress t) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
375 ;; 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
|
376 ;; 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
|
377 ;; 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
|
378 ;; constraint (neither equality nor inequality), so |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
379 ;; anything will do. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
380 ;; 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
|
381 ;; 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
|
382 ;; 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
|
383 ;; distinguish associative operators (which will have |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
384 ;; left = right). |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
385 (unless (caar cst) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
386 (setcar (car cst) i) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
387 (incf i)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
388 (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
|
389 (unless progress |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
390 (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
|
391 (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
|
392 ;; 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
|
393 (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
|
394 (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
|
395 (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
|
396 ;; 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
|
397 ;; 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
|
398 (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
|
399 ;; 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
|
400 ;; 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
|
401 ;; 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
|
402 ;; 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
|
403 ;; 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
|
404 ;; 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
|
405 (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
|
406 (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
|
407 (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
|
408 table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
409 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
410 ;;; 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
|
411 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
412 (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
|
413 "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
|
414 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
|
415 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
|
416 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
|
417 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
|
418 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
|
419 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
|
420 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
|
421 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
422 (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
|
423 "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
|
424 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
|
425 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
|
426 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
|
427 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
|
428 |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
429 (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
|
430 "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
|
431 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
|
432 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
|
433 |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
434 (defalias 'smie-op-left 'car) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
435 (defalias 'smie-op-right 'cadr) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
436 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
437 (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
|
438 (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
|
439 (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
|
440 (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
|
441 (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
|
442 (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
|
443 (point)))) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
444 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
445 (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
|
446 (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
|
447 (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
|
448 (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
|
449 (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
|
450 (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
|
451 (point)))) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
452 |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
453 (defun smie-associative-p (toklevels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
454 ;; 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
|
455 ;; "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
|
456 ;; 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
|
457 ;; 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
|
458 ;; 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
|
459 ;; 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
|
460 ;; 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
|
461 ;; 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
|
462 ;; 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
|
463 (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
|
464 |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
465 (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
|
466 "Skip over one sexp. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
467 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
|
468 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
|
469 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
|
470 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
|
471 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
|
472 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
|
473 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
|
474 Possible return values: |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
475 (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
|
476 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
|
477 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
|
478 (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
|
479 (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
|
480 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
|
481 (catch 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
482 (let ((levels ())) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
483 (while |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
484 (let* ((pos (point)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
485 (token (funcall next-token)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
486 (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
|
487 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
488 ((null toklevels) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
489 (when (zerop (length token)) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
490 (condition-case err |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
491 (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
|
492 (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
|
493 (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
|
494 (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
|
495 (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
|
496 (+ (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
|
497 (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
|
498 -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
|
499 (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
|
500 ;; 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
|
501 (throw 'return (list t (point)))))) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
502 ((null (funcall op-back toklevels)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
503 ;; A token like a paren-close. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
504 (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
|
505 (push toklevels levels)) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
506 (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
|
507 (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
|
508 (funcall op-forw (car levels)))) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
509 (setq levels (cdr levels))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
510 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
511 ((null levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
512 (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
|
513 (push toklevels levels) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
514 (throw 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
515 (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
|
516 (goto-char pos))))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
517 (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
|
518 (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
|
519 (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
|
520 (funcall op-forw (car levels)))) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
521 (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
|
522 ;; 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
|
523 ;; operator. Is this the end? |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
524 (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
|
525 ;; 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
|
526 ;; 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
|
527 (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 (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
|
529 (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
|
530 ;; 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
|
531 ;; 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
|
532 ((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
|
533 ;; 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
|
534 (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
|
535 ;; 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
|
536 ;; 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
|
537 ;; (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
|
538 ((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
|
539 (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
|
540 ;; 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
|
541 ;; - 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
|
542 ;; 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
|
543 ((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
|
544 (smie-associative-p (car lastlevels))) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
545 (throw 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
546 (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
|
547 (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
|
548 ;; - 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
|
549 ;; (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
|
550 ;; 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
|
551 (t (setq levels lastlevels)))))))) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
552 levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
553 (setq halfsexp nil))))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
554 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
555 (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
|
556 "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
|
557 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
|
558 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
|
559 Possible return values: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
560 (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
|
561 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
|
562 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
|
563 (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
|
564 (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
|
565 nil: we skipped over an identifier, matched parentheses, ..." |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
566 (smie-next-sexp |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
567 (indirect-function smie-backward-token-function) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
568 (indirect-function 'backward-sexp) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
569 (indirect-function 'smie-op-left) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
570 (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
|
571 halfsexp)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
572 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
573 (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
|
574 "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
|
575 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
|
576 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
|
577 Possible return values: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
578 (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
|
579 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
|
580 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
|
581 (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
|
582 (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
|
583 nil: we skipped over an identifier, matched parentheses, ..." |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
584 (smie-next-sexp |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
585 (indirect-function smie-forward-token-function) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
586 (indirect-function 'forward-sexp) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
587 (indirect-function 'smie-op-right) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
588 (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
|
589 halfsexp)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
590 |
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
|
591 ;;; 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
|
592 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
593 (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
|
594 "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
|
595 (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
|
596 (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
|
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 (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
|
599 "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
|
600 (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
|
601 (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
|
602 (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
|
603 (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
|
604 (setq n (- n (if forw 1 -1))) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
605 (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
|
606 (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
|
607 (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
|
608 (smie-backward-sexp 'halfsexp)))) |
109840
51f5fd9b5515
* smie.el (smie-forward-sexp-command): Fix typo.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109838
diff
changeset
|
609 (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
|
610 (signal 'scan-error |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
611 (list "Containing expression ends prematurely" |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
612 (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
|
613 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
|
614 |
64936c70841e
Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108923
diff
changeset
|
615 (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
|
616 "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
|
617 |
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
|
618 (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
|
619 "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
|
620 (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
|
621 (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
|
622 (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
|
623 (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
|
624 (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
|
625 (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
|
626 (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
|
627 (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
|
628 (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
|
629 (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
|
630 (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
|
631 (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
|
632 ;; 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
|
633 ;; 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
|
634 ;; 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
|
635 ;; 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
|
636 (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
|
637 ((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
|
638 (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
|
639 (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
|
640 ;; 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
|
641 ;; "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
|
642 ;; 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
|
643 ;; 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
|
644 (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
|
645 (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
|
646 (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
|
647 (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
|
648 (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
|
649 (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
|
650 (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
|
651 (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
|
652 (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
|
653 (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
|
654 ((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
|
655 ;; 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
|
656 (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
|
657 (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
|
658 (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
|
659 (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
|
660 (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
|
661 (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
|
662 (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
|
663 |
110067
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
664 (defun smie-down-list (&optional arg) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
665 "Move forward down one level paren-like blocks. Like `down-list'. |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
666 With argument ARG, do this that many times. |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
667 A negative argument means move backward but still go down a level. |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
668 This command assumes point is not in a string or comment." |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
669 (interactive "p") |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
670 (let ((start (point)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
671 (inc (if (< arg 0) -1 1)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
672 (offset (if (< arg 0) 1 0)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
673 (next-token (if (< arg 0) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
674 smie-backward-token-function |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
675 smie-forward-token-function))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
676 (while (/= arg 0) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
677 (setq arg (- arg inc)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
678 (while |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
679 (let* ((pos (point)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
680 (token (funcall next-token)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
681 (levels (assoc token smie-op-levels))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
682 (cond |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
683 ((zerop (length token)) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
684 (if (if (< inc 0) (looking-back "\\s(\\|\\s)" (1- (point))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
685 (looking-at "\\s(\\|\\s)")) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
686 ;; Go back to `start' in case of an error. This presumes |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
687 ;; none of the token we've found until now include a ( or ). |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
688 (progn (goto-char start) (down-list inc) nil) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
689 (forward-sexp inc) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
690 (/= (point) pos))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
691 ((and levels (null (nth (+ 1 offset) levels))) nil) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
692 ((and levels (null (nth (- 2 offset) levels))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
693 (let ((end (point))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
694 (goto-char start) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
695 (signal 'scan-error |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
696 (list "Containing expression ends prematurely" |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
697 pos end)))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
698 (t))))))) |
5cab4c4229ff
* lisp/emacs-lisp/smie.el (smie-down-list): New command.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110036
diff
changeset
|
699 |
110161
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
700 (defvar smie-blink-matching-triggers '(?\s ?\n) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
701 "Chars which might trigger `blink-matching-open'. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
702 These can include the final chars of end-tokens, or chars that are |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
703 typically inserted right after an end token. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
704 I.e. a good choice can be: |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
705 (delete-dups |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
706 (mapcar (lambda (kw) (aref (cdr kw) (1- (length (cdr kw))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
707 smie-closer-alist))") |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
708 |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
709 (defcustom smie-blink-matching-inners t |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
710 "Whether SMIE should blink to matching opener for inner keywords. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
711 If non-nil, it will blink not only for \"begin..end\" but also for \"if...else\"." |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
712 :type 'boolean) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
713 |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
714 (defun smie-blink-matching-check (start end) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
715 (save-excursion |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
716 (goto-char end) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
717 (let ((ender (funcall smie-backward-token-function))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
718 (cond |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
719 ((not (and ender (rassoc ender smie-closer-alist))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
720 ;; This not is one of the begin..end we know how to check. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
721 (blink-matching-check-mismatch start end)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
722 ((not start) t) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
723 (t |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
724 (goto-char start) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
725 (let ((starter (funcall smie-forward-token-function))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
726 (not (member (cons starter ender) smie-closer-alist)))))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
727 |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
728 (defun smie-blink-matching-open () |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
729 "Blink the matching opener when applicable. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
730 This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'." |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
731 (when (and blink-matching-paren |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
732 smie-closer-alist ; Optimization. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
733 (eq (char-before) last-command-event) ; Sanity check. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
734 (memq last-command-event smie-blink-matching-triggers) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
735 (save-excursion |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
736 ;; FIXME: Here we assume that closers all end |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
737 ;; with a word-syntax char. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
738 (unless (eq ?\w (char-syntax last-command-event)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
739 (forward-char -1)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
740 (and (looking-at "\\>") |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
741 (not (nth 8 (syntax-ppss)))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
742 (save-excursion |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
743 (let ((pos (point)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
744 (token (funcall smie-backward-token-function))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
745 (if (= 1 (length token)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
746 ;; The trigger char is itself a token but is not |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
747 ;; one of the closers (e.g. ?\; in Octave mode), |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
748 ;; so go back to the previous token |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
749 (setq token (save-excursion |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
750 (funcall smie-backward-token-function))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
751 (goto-char pos)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
752 ;; Here we assume that smie-backward-token-function |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
753 ;; returns a token that is a string and whose content |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
754 ;; match the buffer's representation of this token. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
755 (when (and (> (length token) 1) (stringp token) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
756 (memq (aref token (1- (length token))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
757 smie-blink-matching-triggers) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
758 (not (eq (aref token (1- (length token))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
759 last-command-event))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
760 ;; Token ends with a trigger char, so don't blink for |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
761 ;; anything else than this trigger char, lest we'd blink |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
762 ;; both when inserting the trigger char and when inserting a |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
763 ;; subsequent SPC. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
764 (setq token nil)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
765 (when (and (rassoc token smie-closer-alist) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
766 (or smie-blink-matching-inners |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
767 (null (nth 2 (assoc token smie-op-levels))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
768 ;; The major mode might set blink-matching-check-function |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
769 ;; buffer-locally so that interactive calls to |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
770 ;; blink-matching-open work right, but let's not presume |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
771 ;; that's the case. |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
772 (let ((blink-matching-check-function #'smie-blink-matching-check)) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
773 (blink-matching-open))))))) |
eb977e012180
Provide blink-matching support to SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
110067
diff
changeset
|
774 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
775 ;;; The indentation engine. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
776 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
777 (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
|
778 "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
|
779 :type 'integer) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
780 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
781 (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
|
782 ;; 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
|
783 ;; structure Foo = |
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
784 ;; Bar (toto) |
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
785 ;; and |
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
786 ;; structure Foo = |
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
787 ;; struct ... end |
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
788 ;; 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
|
789 ;; 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
|
790 "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
|
791 \((: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
|
792 \(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
|
793 \(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
|
794 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
|
795 \(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
|
796 \(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
|
797 \((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
|
798 |
108897
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
799 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
|
800 |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
801 \(: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
|
802 \(: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
|
803 \(: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
|
804 \(: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
|
805 \(: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
|
806 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
|
807 |
110036
af3f1edc363f
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109841
diff
changeset
|
808 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
|
809 |
64936c70841e
Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108923
diff
changeset
|
810 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
|
811 `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
|
812 `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
|
813 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
|
814 \(+ 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
|
815 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
|
816 |
64936c70841e
Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108923
diff
changeset
|
817 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
|
818 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
|
819 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
|
820 |
110036
af3f1edc363f
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Let :parent take
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109841
diff
changeset
|
821 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
|
822 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
|
823 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
824 (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
|
825 ;; 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
|
826 ;; 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
|
827 (and (save-excursion |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
828 (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
|
829 ;; 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
|
830 (forward-char 1)) |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
831 (skip-chars-forward " \t") |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
832 (eolp)) |
108864
f241d9fe71fe
* lisp/emacs-lisp/smie.el (smie-indent-calculate): Simplify and cleanup.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108797
diff
changeset
|
833 (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
|
834 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
835 (defun smie-bolp () |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
836 (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
|
837 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
838 (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
|
839 (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
|
840 (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
|
841 smie-indent-basic)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
842 |
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
|
843 (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
|
844 |
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 (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
|
846 "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
|
847 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
|
848 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
|
849 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
|
850 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
|
851 (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
|
852 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
|
853 offset) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
854 (while (consp rules) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
855 (let ((rule (pop rules))) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
856 (cond |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
857 ((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
|
858 ((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
|
859 ((eq (car rule) :hanging) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
860 (when (smie-indent-hanging-p) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
861 (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
|
862 ((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
|
863 (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
|
864 (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
|
865 ((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
|
866 (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
|
867 (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
|
868 (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
|
869 (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
|
870 ((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
|
871 (unless prev |
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
872 (save-excursion |
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
873 (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
|
874 (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
|
875 (setq rules (cddr rule)))) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
876 ((eq (car rule) :next) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
877 (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
|
878 (unless after |
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
879 (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
|
880 (save-excursion |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
881 (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
|
882 (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
|
883 (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
|
884 (setq rules (cddr rule)))) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
885 ((eq (car rule) :parent) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
886 (unless parent |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
887 (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
|
888 (if after (goto-char after)) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
889 (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
|
890 (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
|
891 (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
|
892 (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
|
893 (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
|
894 (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
|
895 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
|
896 ;; 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
|
897 ;; 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
|
898 (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
|
899 (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
|
900 (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
|
901 offset)) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
902 |
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
|
903 (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
|
904 "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
|
905 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
|
906 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
|
907 (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
|
908 ((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
|
909 (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
|
910 (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
|
911 ((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
|
912 (+ 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
|
913 (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
|
914 ((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
|
915 (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
|
916 (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
|
917 (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
|
918 (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
|
919 ;; 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
|
920 ;; 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
|
921 ;; 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
|
922 (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
|
923 ((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
|
924 ;; 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
|
925 ;; 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
|
926 ;; 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
|
927 ;; 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
|
928 ;; (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
|
929 ;; 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
|
930 ;; 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
|
931 ;; 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
|
932 ;; 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
|
933 ;; 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
|
934 ;; 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
|
935 (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
|
936 (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
|
937 ((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
|
938 (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
|
939 (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
|
940 (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
|
941 (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
|
942 ((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
|
943 ((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
|
944 (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
|
945 (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
|
946 |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
947 (defun smie-indent-forward-token () |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
948 "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
|
949 (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
|
950 (cond |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
951 ((< 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
|
952 ((looking-at "\\s(") |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
953 (forward-char 1) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
954 (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
|
955 |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
956 (defun smie-indent-backward-token () |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
957 "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
|
958 (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
|
959 (cond |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
960 ((< 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
|
961 ;; 4 == Open paren syntax. |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
962 ((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
|
963 (forward-char -1) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
964 (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
|
965 |
108897
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
966 (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
|
967 ;; 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
|
968 ;; 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
|
969 ;; 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
|
970 ;; 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
|
971 ;; 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
|
972 "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
|
973 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
|
974 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
|
975 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
|
976 ;; 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
|
977 (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
|
978 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
979 (defun smie-indent-fixindent () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
980 ;; Obey the `fixindent' special comment. |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
981 (and (smie-bolp) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
982 (save-excursion |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
983 (comment-normalize-vars) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
984 (re-search-forward (concat comment-start-skip |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
985 "fixindent" |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
986 comment-end-skip) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
987 ;; 1+ to account for the \n comment termination. |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
988 (1+ (line-end-position)) t)) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
989 (current-column))) |
108865
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
990 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
991 (defun smie-indent-bob () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
992 ;; 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
|
993 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
994 (forward-comment (- (point))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
995 (if (bobp) 0))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
996 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
997 (defun smie-indent-close () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
998 ;; 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
|
999 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1000 ;; (forward-comment (point-max)) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1001 (when (looking-at "\\s)") |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1002 (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
|
1003 (skip-chars-forward " \t")) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1004 (condition-case nil |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1005 (progn |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1006 (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
|
1007 (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
|
1008 (scan-error nil))))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1009 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1010 (defun smie-indent-keyword () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1011 ;; 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
|
1012 ;; (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
|
1013 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1014 (let* ((pos (point)) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1015 (toklevels (smie-indent-forward-token)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1016 (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
|
1017 (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
|
1018 (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
|
1019 (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
|
1020 ;; Different cases: |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1021 ;; - smie-bolp: "indent according to others". |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1022 ;; - common hanging: "indent according to others". |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1023 ;; - SML-let hanging: "indent like parent". |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1024 ;; - if-after-else: "indent-like parent". |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1025 ;; - middle-of-line: "trust current position". |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1026 (cond |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1027 ((null (cdr toklevels)) nil) ;Not a keyword. |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1028 ((smie-bolp) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1029 ;; 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
|
1030 ;; based on other rules (typically smie-indent-after-keyword). |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1031 nil) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1032 (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
|
1033 ;; 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
|
1034 ;; 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
|
1035 (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
|
1036 smie-indent-rules) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1037 ;; 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
|
1038 `((: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
|
1039 ;; (after (prog1 (point) (goto-char pos))) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1040 (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
|
1041 (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
|
1042 |
68586a267c40
* lisp/emacs-lisp/smie.el (smie-indent-offset-rule): Rename from
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108894
diff
changeset
|
1043 ;; 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
|
1044 ;; 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
|
1045 ;; 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
|
1046 (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
|
1047 (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
|
1048 (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
|
1049 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
|
1050 (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
|
1051 ;; 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
|
1052 `((: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
|
1053 ;; (: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
|
1054 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
|
1055 (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
|
1056 (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
|
1057 (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
|
1058 ;; 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
|
1059 ;; - 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
|
1060 ;; - 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
|
1061 ;; - 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
|
1062 ;; 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
|
1063 ;; ? 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
|
1064 ;; ? 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
|
1065 ;; 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
|
1066 ;; - 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
|
1067 ;; - 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
|
1068 ;; - 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
|
1069 ;; - 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
|
1070 ;; ? 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
|
1071 ;; ? bump immediately into a parent. |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1072 (cond |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1073 ((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
|
1074 (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
|
1075 ;; 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
|
1076 ;; 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
|
1077 ;; 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
|
1078 ;; of a buffer. |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1079 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
|
1080 ((eq (car parent) (car toklevels)) |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1081 ;; 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
|
1082 (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
|
1083 (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
|
1084 (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
|
1085 (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
|
1086 ;; 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
|
1087 ;; 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
|
1088 ;; 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
|
1089 ;; 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
|
1090 ;; 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
|
1091 ;; 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
|
1092 ;; 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
|
1093 ;; 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
|
1094 (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
|
1095 ;; 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
|
1096 ;; 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
|
1097 ;; 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
|
1098 ;; 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
|
1099 ;; 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
|
1100 ;; 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
|
1101 ;; 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
|
1102 ;; 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
|
1103 ;; |
64936c70841e
Try and remove some of SMIE's black magic by generalizing some rules.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108923
diff
changeset
|
1104 ;; 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
|
1105 ;; 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
|
1106 ;; 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
|
1107 ;; 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
|
1108 ;; 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
|
1109 ;; 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
|
1110 ;; 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
|
1111 ;; 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
|
1112 ;; 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
|
1113 (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
|
1114 (goto-char (cadr parent)) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1115 ;; 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
|
1116 ;; 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
|
1117 ;; a -> b -> c |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1118 ;; -> d |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1119 ;; 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
|
1120 (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
|
1121 (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
|
1122 (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
|
1123 (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
|
1124 (and (consp offset) (memq 'point offset)))) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1125 ;; 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
|
1126 ;; 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
|
1127 ;; 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
|
1128 ;; 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
|
1129 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
|
1130 (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
|
1131 ;; 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
|
1132 ;; 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
|
1133 (unless (= (point) pos) 'virtual)))))))))) |
108865
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1134 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1135 (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
|
1136 "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
|
1137 ;; 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
|
1138 ;; 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
|
1139 ;; (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
|
1140 (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
|
1141 (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
|
1142 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1143 (forward-comment (point-max)) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1144 (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
|
1145 (smie-indent-calculate)))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1146 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1147 (defun smie-indent-comment-continue () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1148 ;; 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
|
1149 (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
|
1150 (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
|
1151 (and (< 0 (length continue)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1152 (looking-at (regexp-quote continue)) (nth 4 (syntax-ppss)) |
109841
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1153 (let ((ppss (syntax-ppss))) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1154 (save-excursion |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1155 (forward-line -1) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1156 (if (<= (point) (nth 8 ppss)) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1157 (progn (goto-char (1+ (nth 8 ppss))) (current-column)) |
3a11454ef7ca
Reindent smie.el
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
109840
diff
changeset
|
1158 (skip-chars-forward " \t") |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1159 (if (looking-at (regexp-quote continue)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1160 (current-column)))))))) |
108865
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1161 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1162 (defun smie-indent-after-keyword () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1163 ;; 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
|
1164 (save-excursion |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1165 (let* ((pos (point)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1166 (toklevel (smie-indent-backward-token)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1167 (tok (car toklevel)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1168 (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
|
1169 ;; 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
|
1170 (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
|
1171 (setq tokinfo (list (car toklevel)))) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1172 ;; (if (and tokinfo (null toklevel)) |
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1173 ;; (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
|
1174 (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
|
1175 (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
|
1176 ;; 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
|
1177 ;; 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
|
1178 ;; 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
|
1179 ;; 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
|
1180 (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
|
1181 (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
|
1182 (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
|
1183 (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
|
1184 (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
|
1185 (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
|
1186 (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
|
1187 (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
|
1188 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1189 (defun smie-indent-exps () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1190 ;; 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
|
1191 ;; 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
|
1192 ;; 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
|
1193 ;; 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
|
1194 ;; 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
|
1195 ;; 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
|
1196 ;; 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
|
1197 ;; |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1198 ;; 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
|
1199 ;; 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
|
1200 ;; 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
|
1201 ;; function). |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1202 ;; 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
|
1203 ;; 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
|
1204 ;; 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
|
1205 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1206 (let ((positions nil) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1207 arg) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1208 (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
|
1209 (push (point) positions) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1210 (not (smie-bolp)))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1211 (save-excursion |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1212 ;; 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
|
1213 ;; than a function. |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1214 (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
|
1215 (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
|
1216 (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
|
1217 (cond |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1218 ((null positions) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1219 ;; 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
|
1220 ;; 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
|
1221 nil) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1222 (arg |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1223 ;; 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
|
1224 ;; 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
|
1225 (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
|
1226 (current-column)) |
108865
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1227 ((cdr positions) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1228 ;; 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
|
1229 ;; Align with the first arg. |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1230 (goto-char (cadr positions)) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1231 (current-column)) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1232 (positions |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1233 ;; We're the first arg. |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1234 (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
|
1235 ;; 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
|
1236 (+ (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
|
1237 ;; 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
|
1238 ;; 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
|
1239 ;; the function itself. |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1240 (current-column))))))) |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1241 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1242 (defvar smie-indent-functions |
108894
ca3bfaa18e56
Make (after keyword) indent-rules more flexible.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108878
diff
changeset
|
1243 '(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
|
1244 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
|
1245 smie-indent-exps) |
108865
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1246 "Functions to compute the indentation. |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1247 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
|
1248 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
|
1249 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
|
1250 |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1251 (defun smie-indent-calculate () |
9d8fb76d6857
Split smie-indent-calculate into more manageable chunks.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108864
diff
changeset
|
1252 "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
|
1253 (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
|
1254 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1255 (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
|
1256 "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
|
1257 (interactive) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1258 (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
|
1259 (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
|
1260 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1261 (forward-line 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1262 (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
|
1263 (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
|
1264 (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
|
1265 (error 0)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1266 (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
|
1267 ;; 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
|
1268 indent |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1269 (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
|
1270 (if savep |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1271 (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
|
1272 (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
|
1273 |
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
|
1274 (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
|
1275 "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
|
1276 (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
|
1277 (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
|
1278 (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
|
1279 ;; 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
|
1280 (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
|
1281 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1282 (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
|
1283 (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
|
1284 (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
|
1285 (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
|
1286 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1287 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1288 (provide 'smie) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1289 ;;; smie.el ends here |