Skip to content

Commit 6f8769a

Browse files
committed
Merge pull request #75 from elixir-lang/rejigger-smie-grammar
Clean up several minor bugbears in elixir-smie.
2 parents 2a7762e + 2986d43 commit 6f8769a

File tree

2 files changed

+48
-72
lines changed

2 files changed

+48
-72
lines changed

elixir-smie.el

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
(elixir-smie-define-regexp-opt parens "(" ")" "{" "}" "[" "]" "<<" ">>"))
6363

6464
(defconst elixir-smie-block-intro-keywords
65-
'(do else catch after rescue -> COMMA OP)
65+
'(do else catch after rescue -> OP)
6666
"Keywords in which newlines cause confusion for the parser.")
6767

6868
(defun elixir-skip-comment-backward ()
@@ -81,7 +81,7 @@ Return non-nil if any line breaks were skipped."
8181
(forward-comment (buffer-size))
8282
(/= start-line-no (line-number-at-pos (point)))))
8383

84-
(defun elixir-smie-next-token-no-lookaround (forwardp nested)
84+
(defun elixir-smie-next-token-no-lookaround (forwardp)
8585
(block elixir-smie-next-token-no-lookaround
8686
;; First, skip comments; but if any comments / newlines were
8787
;; skipped, the upper level needs to check if they were significant:
@@ -132,7 +132,7 @@ Return non-nil if any line breaks were skipped."
132132

133133
(defun elixir-smie-next-token (forwardp)
134134
(block elixir-smie-next-token
135-
(let ((current-token (elixir-smie-next-token-no-lookaround forwardp nil)))
135+
(let ((current-token (elixir-smie-next-token-no-lookaround forwardp)))
136136
(when (string= "\n" current-token)
137137
;; This is a newline; if the previous token isn't an OP2, this
138138
;; means the line end marks the end of a statement & we get to
@@ -141,9 +141,10 @@ Return non-nil if any line breaks were skipped."
141141
;; statement (but see below).
142142
(if (save-excursion
143143
(block nil
144-
(let ((token (elixir-smie-next-token-no-lookaround nil t)))
145-
(while (and (not (= (point) (point-min))) (string= "\n" token))
146-
(setq token (elixir-smie-next-token-no-lookaround nil t)))
144+
(let ((token (elixir-smie-next-token-no-lookaround nil)))
145+
(while (and (not (= (point) (point-min)))
146+
(string= "\n" token))
147+
(setq token (elixir-smie-next-token-no-lookaround nil)))
147148
(when (member (intern token) elixir-smie-block-intro-keywords)
148149
(return t)))))
149150
;; it's a continuation line, return the next token after the newline:
@@ -173,7 +174,7 @@ Return non-nil if any line breaks were skipped."
173174
(not (string= "" token))
174175
;; ...nor a newline nor a semicolon.
175176
(not (or (string= "\n" token) (string= ";" token))))
176-
(setq token (elixir-smie-next-token-no-lookaround t nil))
177+
(setq token (elixir-smie-next-token-no-lookaround t))
177178
;; If we're at the top level and the token is "->",
178179
;; return t
179180
(cond ((and (= level 0) (string= "->" token))
@@ -196,56 +197,51 @@ Return non-nil if any line breaks were skipped."
196197
(not (string= "" token))
197198
(not (string= "do" token))
198199
(not (string= "fn" token)))
199-
(setq token (elixir-smie-next-token-no-lookaround nil nil))
200+
(setq token (elixir-smie-next-token-no-lookaround nil))
200201
(when (string= "->" token)
201202
(return t)))
202203
(when (string= token "do") t)))))
203204
"MATCH-STATEMENT-DELIMITER"
204205
current-token))))
205206

206207
(defun elixir-smie-forward-token ()
207-
(elixir-smie-next-token t))
208+
(elixir-smie-next-token t))
208209

209210
(defun elixir-smie-backward-token ()
210211
(elixir-smie-next-token nil))
211212

212-
(setq elixir-smie-grammar
213-
(smie-prec2->grammar
214-
(smie-bnf->prec2
215-
'((id)
216-
(statements
217-
(statement)
218-
(statement ";" statements))
219-
(statement
220-
(non-block-expr "fn" match-statement "end")
221-
(non-block-expr "do" statements "end")
222-
("if" non-block-expr "do" statements "else" statements "end")
223-
("if" non-block-expr "do" statements "end")
224-
("if" non-block-expr "COMMA" "do:" statement)
225-
("if" non-block-expr "COMMA" "do:" statement "COMMA" "else:" statement)
226-
("try" "do" statements "after" statements "end")
227-
("try" "do" statements "catch" match-statements "end")
228-
("try" "do" statements "end")
229-
("case" non-block-expr "do" match-statements "end")
230-
("def" non-block-expr "do" statements "end"))
231-
(non-block-expr
232-
(non-block-expr "OP" non-block-expr)
233-
(non-block-expr "COMMA" non-block-expr)
234-
("(" statements ")")
235-
("{" statements "}")
236-
("[" statements "]")
237-
("STRING"))
238-
(match-statements
239-
(match-statement "MATCH-STATEMENT-DELIMITER" match-statements)
240-
(match-statement))
241-
(match-statement
242-
(non-block-expr "->" statements)))
243-
'((assoc "if")
244-
(assoc "do:")
245-
(assoc "else:")
246-
(assoc "COMMA")
247-
(assoc "OP")
248-
(assoc "->" ";")))))
213+
(defconst elixir-smie-grammar
214+
(smie-prec2->grammar
215+
(smie-bnf->prec2
216+
'((id)
217+
(statements (statement)
218+
(statement ";" statements))
219+
(statement ("defrecord" non-block-expr "do" statements "end")
220+
("def" non-block-expr "do" statements "end")
221+
(non-block-expr "fn" match-statement "end")
222+
(non-block-expr "do" statements "end")
223+
("if" non-block-expr "do" statements "else" statements "end")
224+
("if" non-block-expr "do" statements "end")
225+
("if" non-block-expr "COMMA" "do:" non-block-expr)
226+
("if" non-block-expr "COMMA"
227+
"do:" non-block-expr "COMMA"
228+
"else:" non-block-expr)
229+
("try" "do" statements "after" statements "end")
230+
("try" "do" statements "catch" match-statements "end")
231+
("try" "do" statements "end")
232+
("case" non-block-expr "do" match-statements "end"))
233+
(non-block-expr (non-block-expr "OP" non-block-expr)
234+
(non-block-expr "COMMA" non-block-expr)
235+
("(" statements ")")
236+
("{" statements "}")
237+
("[" statements "]")
238+
("STRING"))
239+
(match-statements (match-statement "MATCH-STATEMENT-DELIMITER" match-statements)
240+
(match-statement))
241+
(match-statement (non-block-expr "->" statements)))
242+
'((assoc "if" "do:" "else:")
243+
(assoc "COMMA")
244+
(left "OP")))))
249245

250246
(defvar elixir-smie-indent-basic 2)
251247

@@ -282,11 +278,13 @@ Return non-nil if any line breaks were skipped."
282278
(if (smie-rule-parent-p "fn")
283279
(smie-rule-parent elixir-smie-indent-basic)
284280
elixir-smie-indent-basic)))
285-
(`(,_ . ,(or `"COMMA")) (smie-rule-separator kind))
286-
(`(:after . "end") 0)
287-
(`(:after . ,(or `"do"))
281+
(`(:after . "do")
288282
elixir-smie-indent-basic)
289-
(`(:list-intro . ,(or `"do" `";")) t)))
283+
(`(:list-intro . ,(or `"do" `";")) t)
284+
(`(:after . ";")
285+
(if (smie-rule-parent-p "if")
286+
(smie-rule-parent 0)))))
287+
290288

291289
(define-minor-mode elixir-smie-mode
292290
"SMIE-based indentation and syntax for Elixir"

test/elixir-mode-indentation-tests.el

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,28 +326,6 @@ after
326326
post_that()
327327
end")
328328

329-
(elixir-def-indentation-test indents-function ()
330-
"
331-
function do
332-
a,b,c ->
333-
three_args
334-
a,b ->
335-
two_args
336-
\[a|rest] ->
337-
one_arg_list
338-
end
339-
"
340-
"
341-
function do
342-
a,b,c ->
343-
three_args
344-
a,b ->
345-
two_args
346-
[a|rest] ->
347-
one_arg_list
348-
end
349-
")
350-
351329
(elixir-def-indentation-test indents-fn-in-assignment ()
352330
"
353331
f = fn x, y ->

0 commit comments

Comments
 (0)