Mercurial > emacs
annotate lisp/emacs-lisp/smie.el @ 108797:d674108e8753
Provide hooks to use a different tokenizer in SMIE.
* lisp/emacs-lisp/smie.el (smie-forward-token-function)
(smie-backward-token-function): New vars.
(smie-backward-sexp, smie-forward-sexp)
(smie-indent-hanging-p, smie-indent-calculate): Use them.
(smie-default-backward-token): Rename from smie-backward-token and
skip comments.
(smie-default-forward-token): Rename from smie-forward-token and
skip comments.
(smie-next-sexp): Handle nil results from next-token.
(smie-indent-calculate): Add a new case for special `fixindent' comments.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Thu, 27 May 2010 00:41:36 -0400 |
parents | 2f547b05b620 |
children | f241d9fe71fe |
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 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
48 ;; looks at "as little as possible" of the buffer make an indentation |
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 ;; |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
61 ;; OTOH we had to kill many chickens, read many coffee grounds, and practiced |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
62 ;; untold numbers of black magic spells. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
63 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
64 ;;; Code: |
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 (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
|
67 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
68 ;;; 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
|
69 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
70 (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
|
71 (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
|
72 (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
|
73 (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
|
74 (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
|
75 (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
|
76 ;; 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
|
77 ;; 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
|
78 ;; 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
|
79 ;; 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
|
80 (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
|
81 (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
|
82 (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
|
83 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
84 (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
|
85 "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
|
86 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
|
87 come before \"*\"), of elements of the form \(left OP ...) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
88 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
|
89 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
|
90 (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
|
91 (dolist (prec precs) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
92 (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
|
93 (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
|
94 '((left . >) (right . <) (assoc . =)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
95 (when selfrule |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
96 (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
|
97 (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
|
98 (let ((op1 '<) (op2 '>)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
99 (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
|
100 (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
|
101 (setq op1 '> op2 '<) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
102 (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
|
103 (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
|
104 (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
|
105 prec2-table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
106 |
108766
2f547b05b620
* emacs-lisp/smie.el (smie-set-prec2tab): Check override before use.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108652
diff
changeset
|
107 (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
|
108 (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
|
109 (car tables) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
110 (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
|
111 (dolist (table tables) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
112 (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
|
113 (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
|
114 table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
115 prec2))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
116 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
117 (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
|
118 (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
|
119 (first-ops-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
120 (last-ops-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
121 (first-nts-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
122 (last-nts-table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
123 (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
|
124 (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
|
125 (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
|
126 again) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
127 (dolist (rules bnf) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
128 (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
|
129 (last-ops ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
130 (first-ops ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
131 (last-nts ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
132 (first-nts ())) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
133 (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
|
134 (assert (consp rhs)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
135 (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
|
136 (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
|
137 (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
|
138 (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
|
139 ;; 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
|
140 ;; 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
|
141 ;; 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
|
142 ;; 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
|
143 ;; 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
|
144 ;; 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
|
145 ;; 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
|
146 ;; 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
|
147 (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
|
148 (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
|
149 (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
|
150 (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
|
151 (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
|
152 (pushnew (car shr) last-nts) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
153 (when (consp (cdr shr)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
154 (assert (not (member (cadr shr) nts))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
155 (pushnew (cadr shr) last-ops))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
156 (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
|
157 (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
|
158 (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
|
159 (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
|
160 ;; 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
|
161 ;; 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
|
162 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
163 (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
|
164 (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
|
165 (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
|
166 (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
|
167 (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
|
168 (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
|
169 (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
|
170 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
171 (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
|
172 ;; 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
|
173 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
174 (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
|
175 (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
|
176 (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
|
177 (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
|
178 (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
|
179 (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
|
180 (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
|
181 (setq again t) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
182 (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
|
183 ;; 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
|
184 (dolist (rules bnf) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
185 (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
|
186 (while (cdr rhs) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
187 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
188 ((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
|
189 (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
|
190 (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
|
191 ((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
|
192 (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
|
193 (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
|
194 (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
|
195 (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
|
196 '= override))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
197 (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
|
198 (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
|
199 prec2)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
200 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
201 (defun smie-prec2-levels (prec2) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
202 "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
|
203 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
|
204 `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
|
205 ;; 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
|
206 ;; the left and right precedence level), which are represented by |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
207 ;; cons cells. Those are the vary cons cells that appear in the |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
208 ;; 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
|
209 (let ((table ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
210 (csts ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
211 (eqs ()) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
212 tmp x y) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
213 ;; 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
|
214 ;; 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
|
215 ;; 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
|
216 (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
|
217 (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
|
218 (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
|
219 (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
|
220 (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
|
221 (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
|
222 (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
|
223 (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
|
224 (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
|
225 (ecase v |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
226 (= (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
|
227 (< (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
|
228 (> (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
|
229 prec2) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
230 ;; 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
|
231 (let ((eqs eqs)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
232 (while eqs |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
233 (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
|
234 (to (cdar eqs))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
235 (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
|
236 (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
|
237 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
|
238 (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
|
239 (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
|
240 (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
|
241 ;; 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
|
242 ;; 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
|
243 (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
|
244 (dolist (cst csts) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
245 (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
|
246 (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
|
247 ;; 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
|
248 (let ((i 0)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
249 (while csts |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
250 (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
|
251 (progress nil)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
252 (dolist (cst csts) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
253 (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
|
254 (setq progress t) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
255 ;; 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
|
256 ;; 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
|
257 ;; 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
|
258 ;; constraint (neither equality nor inequality), so |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
259 ;; anything will do. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
260 ;; 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
|
261 ;; 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
|
262 ;; 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
|
263 ;; distinguish associative operators (which will have |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
264 ;; left = right). |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
265 (unless (caar cst) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
266 (setcar (car cst) i) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
267 (incf i)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
268 (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
|
269 (unless progress |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
270 (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
|
271 (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
|
272 ;; 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
|
273 (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
|
274 (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
|
275 (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
|
276 ;; 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
|
277 ;; 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
|
278 (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
|
279 ;; 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
|
280 ;; 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
|
281 ;; 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
|
282 ;; 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
|
283 ;; 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
|
284 ;; 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
|
285 (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
|
286 (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
|
287 (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
|
288 table)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
289 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
290 ;;; 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
|
291 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
292 (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
|
293 "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
|
294 Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
295 Parsing is done using 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
|
296 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
297 (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
|
298 "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
|
299 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
|
300 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
|
301 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
|
302 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
|
303 |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
304 (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
|
305 "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
|
306 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
|
307 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
|
308 |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
309 (defalias 'smie-op-left 'car) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
310 (defalias 'smie-op-right 'cadr) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
311 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
312 (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
|
313 (forward-comment (- (point))) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
314 (buffer-substring (point) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
315 (progn (if (zerop (skip-syntax-backward ".")) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
316 (skip-syntax-backward "w_'")) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
317 (point)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
318 |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
319 (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
|
320 (forward-comment (point-max)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
321 (buffer-substring (point) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
322 (progn (if (zerop (skip-syntax-forward ".")) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
323 (skip-syntax-forward "w_'")) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
324 (point)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
325 |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
326 (defun smie-associative-p (toklevels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
327 ;; in "a + b + c" we want to stop at each +, but in |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
328 ;; "if a then b else c" we don't want to stop at each keyword. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
329 ;; 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
|
330 ;; 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
|
331 ;; 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
|
332 ;; figure out that it's an associative operator. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
333 ;; This is not 100% foolproof, tho, since a grammar like |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
334 ;; (exp ("A" exp "C") ("A" exp "B" exp "C")) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
335 ;; will cause "B" to have equal left and right levels, even though |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
336 ;; it is not an associative operator. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
337 ;; A better check would be the check the actual previous operator |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
338 ;; against this one to see if it's the same, but we'd have to change |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
339 ;; `levels' to keep a stack of operators rather than only levels. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
340 (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
|
341 |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
342 (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
|
343 "Skip over one sexp. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
344 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
|
345 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
|
346 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
|
347 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
|
348 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
|
349 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
|
350 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
|
351 Possible return values: |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
352 (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
|
353 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
|
354 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
|
355 (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
|
356 (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
|
357 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
|
358 (catch 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
359 (let ((levels ())) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
360 (while |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
361 (let* ((pos (point)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
362 (token (funcall next-token)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
363 (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
|
364 |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
365 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
366 ((null toklevels) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
367 (when (zerop (length token)) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
368 (condition-case err |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
369 (progn (goto-char pos) (funcall next-sexp 1) nil) |
108652
79ce86edba9f
* emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108649
diff
changeset
|
370 (scan-error (throw 'return (list t (caddr err))))) |
79ce86edba9f
* emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108649
diff
changeset
|
371 (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
|
372 ;; 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
|
373 (throw 'return (list t (point)))))) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
374 ((null (funcall op-back toklevels)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
375 ;; A token like a paren-close. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
376 (assert (funcall op-forw toklevels)) ;Otherwise, why mention it? |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
377 (push (funcall op-forw toklevels) levels)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
378 (t |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
379 (while (and levels (< (funcall op-back toklevels) (car levels))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
380 (setq levels (cdr levels))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
381 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
382 ((null levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
383 (if (and halfsexp (funcall op-forw toklevels)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
384 (push (funcall op-forw toklevels) levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
385 (throw 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
386 (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
|
387 (goto-char pos))))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
388 (t |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
389 (if (and levels (= (funcall op-back toklevels) (car levels))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
390 (setq levels (cdr levels))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
391 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
392 ((null levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
393 (cond |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
394 ((null (funcall op-forw toklevels)) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
395 (throw 'return (list nil (point) token))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
396 ((smie-associative-p toklevels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
397 (throw 'return |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
398 (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
|
399 (goto-char pos)))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
400 ;; We just found a match to the previously pending operator |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
401 ;; but this new operator is still part of a larger RHS. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
402 ;; E.g. we're now looking at the "then" in |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
403 ;; "if a then b else c". So we have to keep parsing the |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
404 ;; rest of the construct. |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
405 (t (push (funcall op-forw toklevels) levels)))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
406 (t |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
407 (if (funcall op-forw toklevels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
408 (push (funcall op-forw toklevels) levels)))))))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
409 levels) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
410 (setq halfsexp nil))))) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
411 |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
412 (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
|
413 "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
|
414 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
|
415 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
|
416 Possible return values: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
417 (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
|
418 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
|
419 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
|
420 (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
|
421 (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
|
422 nil: we skipped over an identifier, matched parentheses, ..." |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
423 (smie-next-sexp |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
424 (indirect-function smie-backward-token-function) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
425 (indirect-function 'backward-sexp) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
426 (indirect-function 'smie-op-left) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
427 (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
|
428 halfsexp)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
429 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
430 (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
|
431 "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
|
432 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
|
433 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
|
434 Possible return values: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
435 (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
|
436 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
|
437 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
|
438 (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
|
439 (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
|
440 nil: we skipped over an identifier, matched parentheses, ..." |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
441 (smie-next-sexp |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
442 (indirect-function smie-forward-token-function) |
108649
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
443 (indirect-function 'forward-sexp) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
444 (indirect-function 'smie-op-right) |
c9e786f54683
Fix handling of non-associative equal levels.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108642
diff
changeset
|
445 (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
|
446 halfsexp)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
447 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
448 (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
|
449 "Move backward through N logical elements." |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
450 (interactive "p") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
451 (if (< n 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
452 (smie-forward-sexp-command (- n)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
453 (let ((forward-sexp-function nil)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
454 (while (> n 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
455 (decf n) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
456 (let ((pos (point)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
457 (res (smie-backward-sexp 'halfsexp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
458 (if (and (car res) (= pos (point)) (not (bolp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
459 (signal 'scan-error |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
460 (list "Containing expression ends prematurely" |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
461 (cadr res) (cadr res))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
462 nil)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
463 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
464 (defun smie-forward-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
|
465 "Move forward through N logical elements." |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
466 (interactive "p") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
467 (if (< n 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
468 (smie-backward-sexp-command (- n)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
469 (let ((forward-sexp-function nil)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
470 (while (> n 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
471 (decf n) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
472 (let ((pos (point)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
473 (res (smie-forward-sexp 'halfsexp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
474 (if (and (car res) (= pos (point)) (not (bolp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
475 (signal 'scan-error |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
476 (list "Containing expression ends prematurely" |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
477 (cadr res) (cadr res))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
478 nil)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
479 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
480 ;;; The indentation engine. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
481 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
482 (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
|
483 "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
|
484 :type 'integer) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
485 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
486 (defvar smie-indent-rules 'unset |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
487 "Rules of the following form. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
488 \(TOK OFFSET) how to indent right after TOK. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
489 \(TOK O1 O2) how to indent right after TOK: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
490 O1 is the default; |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
491 O2 is used if TOK is \"hanging\". |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
492 \((T1 . T2) . OFFSET) how to indent token T2 w.r.t T1. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
493 \((t . TOK) . OFFSET) how to indent TOK with respect to its parent. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
494 \(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
|
495 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
|
496 \(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
|
497 \(args . OFFSET) indentation of arguments. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
498 A nil offset defaults to `smie-indent-basic'.") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
499 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
500 (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
|
501 ;; 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
|
502 ;; 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
|
503 (and (save-excursion |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
504 (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
|
505 ;; 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
|
506 (forward-char 1)) |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
507 (skip-chars-forward " \t") |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
508 (eolp)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
509 (save-excursion (skip-chars-backward " \t") (not (bolp))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
510 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
511 (defun smie-bolp () |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
512 (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
|
513 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
514 (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
|
515 (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
|
516 (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
|
517 smie-indent-basic)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
518 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
519 (defun smie-indent-calculate (&optional virtual) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
520 "Compute the indentation to use for point. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
521 If VIRTUAL is non-nil, it means we're not trying to indent point but just |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
522 need to compute the column at which point should be indented |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
523 in order to figure out the indentation of some other (further down) point. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
524 VIRTUAL can take two different non-nil values: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
525 - :bolp: means that the current indentation of point can be trusted |
108642
66f3c521df14
* emacs-lisp/smie.el: Fix typos in docstrings.
Juanma Barranquero <lekktu@gmail.com>
parents:
108632
diff
changeset
|
526 to be good only if it follows a line break. |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
527 - :hanging: means that the current indentation of point can be |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
528 trusted to be good except if the following token is hanging." |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
529 ;; FIXME: This has accumulated a lot of rules, some of which aren't |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
530 ;; clearly orthogonal any more, so we should probably try and |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
531 ;; restructure it somewhat. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
532 (or |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
533 ;; Trust pre-existing indentation on other lines. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
534 (and virtual |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
535 (if (eq virtual :hanging) (not (smie-indent-hanging-p)) (smie-bolp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
536 (current-column)) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
537 ;; Obey the `fixindent' special comment. |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
538 (when (save-excursion |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
539 (comment-normalize-vars) |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
540 (re-search-forward (concat comment-start-skip |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
541 "fixindent" |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
542 comment-end-skip) |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
543 ;; 1+ to account for the \n comment termination. |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
544 (1+ (line-end-position)) t)) |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
545 (current-column)) |
108652
79ce86edba9f
* emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108649
diff
changeset
|
546 ;; Start the file at column 0. |
79ce86edba9f
* emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108649
diff
changeset
|
547 (save-excursion |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
548 (forward-comment (- (point))) |
108652
79ce86edba9f
* emacs-lisp/smie.el (smie-next-sexp): Break inf-loop at BOB.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108649
diff
changeset
|
549 (if (bobp) 0)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
550 ;; Align close paren with opening paren. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
551 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
552 ;; (forward-comment (point-max)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
553 (when (looking-at "\\s)") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
554 (while (not (zerop (skip-syntax-forward ")"))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
555 (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
|
556 (condition-case nil |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
557 (progn |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
558 (backward-sexp 1) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
559 (smie-indent-calculate :hanging)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
560 (scan-error nil)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
561 ;; Align closing token with the corresponding opening one. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
562 ;; (e.g. "of" with "case", or "in" with "let"). |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
563 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
564 (let* ((pos (point)) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
565 (token (funcall smie-forward-token-function)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
566 (toklevels (cdr (assoc token smie-op-levels)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
567 (when (car toklevels) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
568 (let ((res (smie-backward-sexp 'halfsexp)) tmp) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
569 ;; If we didn't move at all, that means we didn't really skip |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
570 ;; what we wanted. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
571 (when (< (point) pos) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
572 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
573 ((eq (car res) (car toklevels)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
574 ;; We bumped into a same-level operator. align with it. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
575 (goto-char (cadr res)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
576 ;; Don't use (smie-indent-calculate :hanging) here, because we |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
577 ;; want to jump back over a sequence of same-level ops such as |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
578 ;; a -> b -> c |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
579 ;; -> d |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
580 ;; So as to align with the earliest appropriate place. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
581 (smie-indent-calculate :bolp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
582 ((equal token (save-excursion |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
583 (funcall smie-backward-token-function))) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
584 ;; in cases such as "fn x => fn y => fn z =>", |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
585 ;; jump back to the very first fn. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
586 ;; FIXME: should we only do that for special tokens like "=>"? |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
587 (smie-indent-calculate :bolp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
588 ((setq tmp (assoc (cons (caddr res) token) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
589 smie-indent-rules)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
590 (goto-char (cadr res)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
591 (+ (cdr tmp) (smie-indent-calculate :hanging))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
592 (t |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
593 (+ (or (cdr (assoc (cons t token) smie-indent-rules)) 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
594 (current-column))))))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
595 ;; Indentation of a comment. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
596 (and (looking-at comment-start-skip) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
597 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
598 (forward-comment (point-max)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
599 (skip-chars-forward " \t\r\n") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
600 (smie-indent-calculate nil))) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
601 ;; indentation inside a comment. |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
602 ;; FIXME: Hey, this is not generic!! |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
603 (and (looking-at "\\*") (nth 4 (syntax-ppss)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
604 (let ((ppss (syntax-ppss))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
605 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
606 (forward-line -1) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
607 (if (<= (point) (nth 8 ppss)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
608 (progn (goto-char (1+ (nth 8 ppss))) (current-column)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
609 (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
|
610 (if (looking-at "\\*") |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
611 (current-column)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
612 ;; Indentation right after a special keyword. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
613 (save-excursion |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
614 (let* ((tok (funcall smie-backward-token-function)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
615 (tokinfo (assoc tok smie-indent-rules)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
616 (toklevel (assoc tok smie-op-levels))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
617 (when (or tokinfo (and toklevel (null (cadr toklevel)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
618 (if (or (smie-indent-hanging-p) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
619 ;; If calculating the virtual indentation point, prefer |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
620 ;; looking up the virtual indentation of the alignment |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
621 ;; point as well. This is used for indentation after |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
622 ;; "fn x => fn y =>". |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
623 virtual) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
624 (+ (smie-indent-calculate :bolp) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
625 (or (caddr tokinfo) (cadr tokinfo) (smie-indent-offset t))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
626 (+ (current-column) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
627 (or (cadr tokinfo) (smie-indent-offset t))))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
628 ;; Main loop (FIXME: whatever that means!?). |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
629 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
630 (let ((positions nil) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
631 (begline nil) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
632 arg) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
633 (while (and (null (car (smie-backward-sexp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
634 (push (point) positions) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
635 (not (setq begline (smie-bolp))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
636 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
637 ;; Figure out if the atom we just skipped is an argument rather |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
638 ;; than a function. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
639 (setq arg (or (null (car (smie-backward-sexp))) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
640 (member (funcall smie-backward-token-function) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
641 (cdr (assoc 'list-intro smie-indent-rules)))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
642 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
643 ((and arg positions) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
644 (goto-char (car positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
645 (current-column)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
646 ((and (null begline) (cdr positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
647 ;; We skipped some args plus the function and bumped into something. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
648 ;; Align with the first arg. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
649 (goto-char (cadr positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
650 (current-column)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
651 ((and (null begline) positions) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
652 ;; We're the first arg. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
653 ;; FIXME: it might not be a funcall, in which case we might be the |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
654 ;; second element. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
655 (goto-char (car positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
656 (+ (smie-indent-offset 'args) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
657 ;; We used to use (smie-indent-calculate :bolp), but that |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
658 ;; doesn't seem right since it might then indent args less than |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
659 ;; the function itself. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
660 (current-column))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
661 ((and (null arg) (null positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
662 ;; We're the function itself. Not sure what to do here yet. |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
663 ;; FIXME: This should not be possible, because it should mean |
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
664 ;; we're right after some special token. |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
665 (if virtual (current-column) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
666 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
667 (let* ((pos (point)) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
668 (tok (funcall smie-backward-token-function)) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
669 (toklevels (cdr (assoc tok smie-op-levels)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
670 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
671 ((numberp (car toklevels)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
672 ;; We're right after an infix token. Let's skip over the |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
673 ;; lefthand side. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
674 (goto-char pos) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
675 (let (res) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
676 (while (progn (setq res (smie-backward-sexp 'halfsexp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
677 (and (not (smie-bolp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
678 (equal (car res) (car toklevels))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
679 ;; We should be right after a token of equal or |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
680 ;; higher precedence. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
681 (cond |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
682 ((and (consp res) (memq (car res) '(t nil))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
683 ;; The token of higher-precedence is like an open-paren. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
684 ;; Sample case for t: foo { bar, \n[TAB] baz }. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
685 ;; Sample case for nil: match ... with \n[TAB] | toto ... |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
686 ;; (goto-char (cadr res)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
687 (smie-indent-calculate :hanging)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
688 ((and (consp res) (<= (car res) (car toklevels))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
689 ;; We stopped at a token of equal or higher precedence |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
690 ;; because we found a place with which to align. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
691 (current-column)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
692 ))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
693 ;; For other cases.... hmm... we'll see when we get there. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
694 ))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
695 ((null positions) |
108797
d674108e8753
Provide hooks to use a different tokenizer in SMIE.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
108766
diff
changeset
|
696 (funcall smie-backward-token-function) |
108632
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
697 (+ (smie-indent-offset 'args) (smie-indent-calculate :bolp))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
698 ((car (smie-backward-sexp)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
699 ;; No arg stands on its own line, but the function does: |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
700 (if (cdr positions) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
701 (progn |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
702 (goto-char (cadr positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
703 (current-column)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
704 (goto-char (car positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
705 (+ (current-column) (smie-indent-offset 'args)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
706 (t |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
707 ;; We've skipped to a previous arg on its own line: align. |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
708 (goto-char (car positions)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
709 (current-column))))))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
710 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
711 (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
|
712 "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
|
713 (interactive) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
714 (let* ((savep (point)) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
715 (indent (condition-case nil |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
716 (save-excursion |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
717 (forward-line 0) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
718 (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
|
719 (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
|
720 (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
|
721 (error 0)))) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
722 (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
|
723 ;; 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
|
724 indent |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
725 (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
|
726 (if savep |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
727 (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
|
728 (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
|
729 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
730 ;;;###autoload |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
731 (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
|
732 (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
|
733 (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
|
734 (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
|
735 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
736 |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
737 (provide 'smie) |
d38b0dd2bdbe
Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
738 ;;; smie.el ends here |