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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
108632
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
1 ;;; smie.el --- Simple Minded Indentation Engine
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
2
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
3 ;; Copyright (C) 2010 Free Software Foundation, Inc.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
4
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
6 ;; Keywords: languages, lisp, internal, parsing, indentation
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
7
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
8 ;; This file is part of GNU Emacs.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
9
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
11 ;; it under the terms of the GNU General Public License as published by
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
12 ;; the Free Software Foundation, either version 3 of the License, or
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
13 ;; (at your option) any later version.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
14
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
15 ;; GNU Emacs is distributed in the hope that it will be useful,
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
18 ;; GNU General Public License for more details.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
19
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
21 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
22
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
23 ;;; Commentary:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
24
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
25 ;; While working on the SML indentation code, the idea grew that maybe
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
26 ;; I could write something generic to do the same thing, and at the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
27 ;; end of working on the SML code, I had a pretty good idea of what it
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
28 ;; could look like. That idea grew stronger after working on
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
29 ;; LaTeX indentation.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
30 ;;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
31 ;; So at some point I decided to try it out, by writing a new
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
32 ;; indentation code for Coq while trying to keep most of the code
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
33 ;; "table driven", where only the tables are Coq-specific. The result
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
34 ;; (which was used for Beluga-mode as well) turned out to be based on
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
35 ;; something pretty close to an operator precedence parser.
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
36
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
37 ;; So here is another rewrite, this time following the actual principles of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
38 ;; operator precedence grammars. Why OPG? Even though they're among the
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
39 ;; weakest kinds of parsers, these parsers have some very desirable properties
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
40 ;; for Emacs:
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
41 ;; - most importantly for indentation, they work equally well in either
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
42 ;; direction, so you can use them to parse backward from the indentation
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
43 ;; point to learn the syntactic context;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
44 ;; - they work locally, so there's no need to keep a cache of
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
45 ;; the parser's state;
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
46 ;; - because of that locality, indentation also works just fine when earlier
d38b0dd2bdbe Provide a simple generic indentation engine and use it for Prolog.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff changeset
47 ;; parts of the buffer are syntactically incorrect since the indentation
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