Skip to content

Commit f3111ab

Browse files
committed
correct indentation for block with multiple matches
1 parent e9d8cea commit f3111ab

File tree

2 files changed

+124
-6
lines changed

2 files changed

+124
-6
lines changed

elixir-smie.el

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@
173173
(not (or (memq (char-before) '(?\{ ?\[))
174174
(looking-back elixir-smie--operator-regexp (- (point) 3) t))))
175175

176+
(defun elixir-smie-last-line-end-with-block-operator-p ()
177+
"Return non-nil if the previous line ends with a `->' operator."
178+
(save-excursion
179+
(forward-line -1)
180+
(move-end-of-line 1)
181+
(looking-back elixir-smie--block-operator-regexp (- (point) 3) t)))
182+
176183
(defun elixir-smie--semi-ends-match ()
177184
"Return non-nil if the current line concludes a match block."
178185
(when (not (eobp))
@@ -292,7 +299,8 @@
292299
(t (smie-rule-parent))))
293300
(`(:before . "MATCH-STATEMENT-DELIMITER")
294301
(cond
295-
((smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
302+
((and (smie-rule-parent-p "do")
303+
(smie-rule-hanging-p))
296304
(smie-rule-parent))
297305
((and (not (smie-rule-sibling-p))
298306
(nth 2 smie--parent)
@@ -302,12 +310,29 @@
302310
(not (nth 2 smie--parent))
303311
(smie-rule-hanging-p))
304312
(smie-rule-parent))))
313+
(`(:after . "MATCH-STATEMENT-DELIMITER")
314+
(cond
315+
((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
316+
(smie-rule-hanging-p)
317+
(smie-rule-sibling-p))
318+
(if (elixir-smie-last-line-end-with-block-operator-p)
319+
(smie-rule-parent)
320+
0))
321+
(t
322+
(smie-rule-parent))))
305323
(`(:before . "fn")
306324
(smie-rule-parent))
307325
(`(:before . "do:")
308326
(cond
309327
((smie-rule-parent-p "def" "if")
310328
(smie-rule-parent))))
329+
(`(:before . "do")
330+
(cond
331+
((and (smie-rule-parent-p "case")
332+
(smie-rule-hanging-p))
333+
(smie-rule-parent elixir-smie-indent-basic))
334+
(t
335+
elixir-smie-indent-basic)))
311336
(`(:before . "end")
312337
(smie-rule-parent))
313338
;; Closing paren on the other line
@@ -323,12 +348,28 @@
323348
;; ()
324349
;; .....
325350
((smie-rule-parent-p "do")
326-
(smie-rule-parent elixir-smie-indent-basic))
351+
(smie-rule-parent))
327352
(t (smie-rule-parent))))
328353
(`(:before . "[")
329354
(cond
330355
((smie-rule-hanging-p)
331356
(smie-rule-parent))))
357+
(`(:before . "{")
358+
(cond
359+
;; Example
360+
;;
361+
;; case parse do
362+
;; { [ help: true ], _, _ }
363+
;; -> :help
364+
;; { _, [ user, project, count ], _ }
365+
((and (not (smie-rule-hanging-p))
366+
(smie-rule-parent-p "do"))
367+
(smie-rule-parent))
368+
((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
369+
(not (smie-rule-hanging-p)))
370+
(if (elixir-smie-last-line-end-with-block-operator-p)
371+
(smie-rule-parent elixir-smie-indent-basic)
372+
(smie-rule-parent -2)))))
332373
(`(:after . "{")
333374
(cond
334375
((smie-rule-hanging-p)
@@ -346,7 +387,21 @@
346387
(`(:before . "->")
347388
(cond
348389
((smie-rule-hanging-p)
349-
(smie-rule-parent elixir-smie-indent-basic))))
390+
(smie-rule-parent elixir-smie-indent-basic))
391+
;; Example
392+
;;
393+
;; case parse do
394+
;; { [ help: true ], _, _ }
395+
;; -> :help
396+
;; ...
397+
((and (not (smie-rule-hanging-p))
398+
(smie-rule-parent-p "do"))
399+
elixir-smie-indent-basic)
400+
((and (not (smie-rule-hanging-p))
401+
(smie-rule-parent-p "MATCH-STATEMENT-DELIMITER"))
402+
(smie-rule-parent)
403+
)
404+
))
350405
(`(:after . "->")
351406
(cond
352407
;; This first condition is kind of complicated so I'll try to make this
@@ -372,8 +427,11 @@
372427
;; Otherwise, if just indent by two.
373428
((smie-rule-hanging-p)
374429
(cond
375-
((smie-rule-parent-p "after" "catch" "do" "rescue" "try")
376-
elixir-smie-indent-basic)
430+
((smie-rule-parent-p "catch" "rescue")
431+
(smie-rule-parent (+ elixir-smie-indent-basic
432+
elixir-smie-indent-basic)))
433+
((smie-rule-parent-p "after" "do" "try")
434+
(smie-rule-parent elixir-smie-indent-basic))
377435
(t (smie-rule-parent elixir-smie-indent-basic))))))
378436
(`(:before . ";")
379437
(cond
@@ -390,16 +448,32 @@
390448
((and (smie-rule-parent-p "if")
391449
(smie-rule-hanging-p))
392450
(smie-rule-parent))
451+
((and (smie-rule-parent-p "else")
452+
(smie-rule-hanging-p))
453+
(smie-rule-parent elixir-smie-indent-basic))
393454
((smie-rule-parent-p "after" "catch" "def" "defmodule" "defp" "do" "else"
394455
"fn" "if" "rescue" "try" "unless")
395-
(smie-rule-parent elixir-smie-indent-basic))
456+
(smie-rule-parent))
457+
;; Example
458+
;;
459+
;; case parse do
460+
;; { [ help: true ], _, _ }
461+
;; -> :help
462+
;; { _, [ user, project, count ], _ }
463+
;; -> { user, project, count }
464+
;; ...
465+
((and (smie-rule-parent-p "->")
466+
(smie-rule-hanging-p))
467+
(smie-rule-parent))
396468
))
397469
(`(:after . ";")
398470
(cond
399471
((smie-rule-parent-p "def")
400472
(smie-rule-parent))
401473
((smie-rule-parent-p "if")
402474
(smie-rule-parent))
475+
((smie-rule-parent-p "after")
476+
(smie-rule-parent elixir-smie-indent-basic))
403477
((and (smie-rule-parent-p "(")
404478
(boundp 'smie--parent)
405479
(save-excursion

test/elixir-mode-indentation-test.el

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,50 @@ defmodule Foo do
11841184
end
11851185
")
11861186

1187+
(elixir-def-indentation-test complex-case-with-matches (:tags '(indentation))
1188+
"
1189+
case parse do
1190+
{ [ help: true ], _, _ }
1191+
-> :help
1192+
{ _, [ user, project, count ], _ } ->
1193+
{ user, project, count }
1194+
{ _, [ user, project ], _ } -> { user, project, @default_count }
1195+
_ -> :help
1196+
end"
1197+
"
1198+
case parse do
1199+
{ [ help: true ], _, _ }
1200+
-> :help
1201+
{ _, [ user, project, count ], _ } ->
1202+
{ user, project, count }
1203+
{ _, [ user, project ], _ } -> { user, project, @default_count }
1204+
_ -> :help
1205+
end")
1206+
1207+
1208+
(elixir-def-indentation-test complex-case-with-matches/2 (:tags '(indentation))
1209+
"
1210+
case parse do
1211+
{ [ help: true ], _, _ }
1212+
-> :help
1213+
{ _, [ user, project, count ], _ }
1214+
-> { user, project, count }
1215+
{ _, [ user, project ], _ }
1216+
-> { user, project, @default_count }
1217+
_ -> :help
1218+
end"
1219+
"
1220+
case parse do
1221+
{ [ help: true ], _, _ }
1222+
-> :help
1223+
{ _, [ user, project, count ], _ }
1224+
-> { user, project, count }
1225+
{ _, [ user, project ], _ }
1226+
-> { user, project, @default_count }
1227+
_ -> :help
1228+
end")
1229+
1230+
11871231
;; We don't want automatic whitespace cleanup here because of the significant
11881232
;; whitespace after `Record' above. By setting `whitespace-action' to nil,
11891233
;; `whitespace-mode' won't automatically clean up trailing whitespace (in my

0 commit comments

Comments
 (0)