]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/factor-smie.el
Append input history to ~/.factor-history upon UI Listener ending
[factor.git] / misc / fuel / factor-smie.el
1 ;;; factor-smie.el --- Helper function for indenting factor code
2
3 ;; Copyright (C) 2016  Björn Lindqvist
4 ;; See http://factorcode.org/license.txt for BSD license.
5
6 ;;; Commentary:
7
8 ;; Factor indentation using the SMIE framework.
9
10 ;;; Code:
11 (require 'smie)
12
13 (defcustom factor-block-offset 4
14   "Indentation of Factor statements."
15   :type 'integer
16   :safe 'integerp
17   :group 'factor)
18
19 ;; These prefixes starts a definition and causes the indent-level to
20 ;; increase.
21 (defconst factor-indent-def-starts
22   '("" ":"
23     "AFTER" "BEFORE"
24     "COM-INTERFACE" "CONSULT"
25     "ENUM" "ERROR"
26     "FROM"
27     "GLSL-PROGRAM"
28     "IDENTITY-MEMO" "INTERSECTION"
29     "M" "M:" "MACRO" "MACRO:"
30     "MAIN-WINDOW" "MEMO" "MEMO:" "METHOD"
31     "SYNTAX"
32     "PREDICATE" "PROTOCOL"
33     "SINGLETONS"
34     "STRUCT" "SYMBOLS" "TAG" "TUPLE"
35     "TYPED" "TYPED:"
36     "UNIFORM-TUPLE"
37     "UNION-STRUCT" "UNION"
38     "VARIANT" "VERTEX-FORMAT"))
39
40 ;; These prefixes starts a definition but does not cause the indent
41 ;; level to increase.
42 (defconst factor-no-indent-def-starts
43   '("ARTICLE"
44     "FUNCTION" "FUNCTION-ALIAS"
45     "HELP"
46     "PRIMITIVE"
47     "SPECIALIZED-ARRAYS"))
48
49 (defconst factor-indent-def-regex
50   (format "^\\(%s:\\)$" (regexp-opt factor-indent-def-starts)))
51
52 (defconst factor-smie-grammar
53   (smie-prec2->grammar
54    (smie-bnf->prec2
55     '(
56       (exp (":" exp ";"))
57       ))))
58
59 (defun factor-smie-rules (kind token)
60   (pcase (cons kind token)
61     (`(:before . ";") factor-block-offset)
62     (`(:list-intro . ,_) t)
63     ))
64
65 (defun factor-smie-token (dir)
66   (pcase dir
67     (`forward (forward-comment (point-max)))
68     (`backward (forward-comment (- (point)))))
69   (let ((tok (buffer-substring-no-properties
70               (point)
71               (let ((syntax "w_\\\""))
72                 (pcase dir
73                   (`forward (skip-syntax-forward syntax))
74                   (`backward (skip-syntax-backward syntax)))
75                 (point)))))
76     ;; Token normalization. This way we only need one rule in
77     ;; factor-smie-grammar.
78     (cond ((string-match factor-indent-def-regex tok) ":")
79           (t tok))))
80
81 (defun factor-smie-forward-token ()
82   (factor-smie-token 'forward))
83
84 (defun factor-smie-backward-token ()
85   (factor-smie-token 'backward))
86
87 (defun factor-smie-indent ()
88   (unless (looking-at ";\\_>")
89     (save-excursion
90       (let ((x nil))
91         (while (progn (setq x (smie-backward-sexp))
92                       (null (car-safe x))))
93         (when (string-match factor-indent-def-regex
94                             (or (nth 2 x) ""))
95           (goto-char (nth 1 x))
96           (+ factor-block-offset (smie-indent-virtual)))))))
97
98 (provide 'factor-smie)
99
100 ;;; factor-smie.el ends here