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