Skip to content

Commit

Permalink
correct indentation for block with multiple matches
Browse files Browse the repository at this point in the history
  • Loading branch information
tonini committed Aug 4, 2015
1 parent e9d8cea commit f3111ab
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 6 deletions.
86 changes: 80 additions & 6 deletions elixir-smie.el
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@
(not (or (memq (char-before) '(?\{ ?\[))
(looking-back elixir-smie--operator-regexp (- (point) 3) t))))

(defun elixir-smie-last-line-end-with-block-operator-p ()
"Return non-nil if the previous line ends with a `->' operator."
(save-excursion
(forward-line -1)
(move-end-of-line 1)
(looking-back elixir-smie--block-operator-regexp (- (point) 3) t)))

(defun elixir-smie--semi-ends-match ()
"Return non-nil if the current line concludes a match block."
(when (not (eobp))
Expand Down Expand Up @@ -292,7 +299,8 @@
(t (smie-rule-parent))))
(`(:before . "MATCH-STATEMENT-DELIMITER")
(cond
((smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
((and (smie-rule-parent-p "do")
(smie-rule-hanging-p))
(smie-rule-parent))
((and (not (smie-rule-sibling-p))
(nth 2 smie--parent)
Expand All @@ -302,12 +310,29 @@
(not (nth 2 smie--parent))
(smie-rule-hanging-p))
(smie-rule-parent))))
(`(:after . "MATCH-STATEMENT-DELIMITER")
(cond
((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
(smie-rule-hanging-p)
(smie-rule-sibling-p))
(if (elixir-smie-last-line-end-with-block-operator-p)
(smie-rule-parent)
0))
(t
(smie-rule-parent))))
(`(:before . "fn")
(smie-rule-parent))
(`(:before . "do:")
(cond
((smie-rule-parent-p "def" "if")
(smie-rule-parent))))
(`(:before . "do")
(cond
((and (smie-rule-parent-p "case")
(smie-rule-hanging-p))
(smie-rule-parent elixir-smie-indent-basic))
(t
elixir-smie-indent-basic)))
(`(:before . "end")
(smie-rule-parent))
;; Closing paren on the other line
Expand All @@ -323,12 +348,28 @@
;; ()
;; .....
((smie-rule-parent-p "do")
(smie-rule-parent elixir-smie-indent-basic))
(smie-rule-parent))
(t (smie-rule-parent))))
(`(:before . "[")
(cond
((smie-rule-hanging-p)
(smie-rule-parent))))
(`(:before . "{")
(cond
;; Example
;;
;; case parse do
;; { [ help: true ], _, _ }
;; -> :help
;; { _, [ user, project, count ], _ }
((and (not (smie-rule-hanging-p))
(smie-rule-parent-p "do"))
(smie-rule-parent))
((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
(not (smie-rule-hanging-p)))
(if (elixir-smie-last-line-end-with-block-operator-p)
(smie-rule-parent elixir-smie-indent-basic)
(smie-rule-parent -2)))))
(`(:after . "{")
(cond
((smie-rule-hanging-p)
Expand All @@ -346,7 +387,21 @@
(`(:before . "->")
(cond
((smie-rule-hanging-p)
(smie-rule-parent elixir-smie-indent-basic))))
(smie-rule-parent elixir-smie-indent-basic))
;; Example
;;
;; case parse do
;; { [ help: true ], _, _ }
;; -> :help
;; ...
((and (not (smie-rule-hanging-p))
(smie-rule-parent-p "do"))
elixir-smie-indent-basic)
((and (not (smie-rule-hanging-p))
(smie-rule-parent-p "MATCH-STATEMENT-DELIMITER"))
(smie-rule-parent)
)
))
(`(:after . "->")
(cond
;; This first condition is kind of complicated so I'll try to make this
Expand All @@ -372,8 +427,11 @@
;; Otherwise, if just indent by two.
((smie-rule-hanging-p)
(cond
((smie-rule-parent-p "after" "catch" "do" "rescue" "try")
elixir-smie-indent-basic)
((smie-rule-parent-p "catch" "rescue")
(smie-rule-parent (+ elixir-smie-indent-basic
elixir-smie-indent-basic)))
((smie-rule-parent-p "after" "do" "try")
(smie-rule-parent elixir-smie-indent-basic))
(t (smie-rule-parent elixir-smie-indent-basic))))))
(`(:before . ";")
(cond
Expand All @@ -390,16 +448,32 @@
((and (smie-rule-parent-p "if")
(smie-rule-hanging-p))
(smie-rule-parent))
((and (smie-rule-parent-p "else")
(smie-rule-hanging-p))
(smie-rule-parent elixir-smie-indent-basic))
((smie-rule-parent-p "after" "catch" "def" "defmodule" "defp" "do" "else"
"fn" "if" "rescue" "try" "unless")
(smie-rule-parent elixir-smie-indent-basic))
(smie-rule-parent))
;; Example
;;
;; case parse do
;; { [ help: true ], _, _ }
;; -> :help
;; { _, [ user, project, count ], _ }
;; -> { user, project, count }
;; ...
((and (smie-rule-parent-p "->")
(smie-rule-hanging-p))
(smie-rule-parent))
))
(`(:after . ";")
(cond
((smie-rule-parent-p "def")
(smie-rule-parent))
((smie-rule-parent-p "if")
(smie-rule-parent))
((smie-rule-parent-p "after")
(smie-rule-parent elixir-smie-indent-basic))
((and (smie-rule-parent-p "(")
(boundp 'smie--parent)
(save-excursion
Expand Down
44 changes: 44 additions & 0 deletions test/elixir-mode-indentation-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,50 @@ defmodule Foo do
end
")

(elixir-def-indentation-test complex-case-with-matches (:tags '(indentation))
"
case parse do
{ [ help: true ], _, _ }
-> :help
{ _, [ user, project, count ], _ } ->
{ user, project, count }
{ _, [ user, project ], _ } -> { user, project, @default_count }
_ -> :help
end"
"
case parse do
{ [ help: true ], _, _ }
-> :help
{ _, [ user, project, count ], _ } ->
{ user, project, count }
{ _, [ user, project ], _ } -> { user, project, @default_count }
_ -> :help
end")


(elixir-def-indentation-test complex-case-with-matches/2 (:tags '(indentation))
"
case parse do
{ [ help: true ], _, _ }
-> :help
{ _, [ user, project, count ], _ }
-> { user, project, count }
{ _, [ user, project ], _ }
-> { user, project, @default_count }
_ -> :help
end"
"
case parse do
{ [ help: true ], _, _ }
-> :help
{ _, [ user, project, count ], _ }
-> { user, project, count }
{ _, [ user, project ], _ }
-> { user, project, @default_count }
_ -> :help
end")


;; We don't want automatic whitespace cleanup here because of the significant
;; whitespace after `Record' above. By setting `whitespace-action' to nil,
;; `whitespace-mode' won't automatically clean up trailing whitespace (in my
Expand Down

0 comments on commit f3111ab

Please sign in to comment.