Alignment doesn't understand QualifiedDo
haskell mode does not recognize QualifiedDo notation and gets alignment wrong.
The following simple example, from the Qualified Do user guide, should align like
{-# LANGUAGE QualifiedDo #-}
import qualified Some.Module.Monad as M
action :: M.SomeType a
action = M.do x <- u
res
M.return x
But haskell-mod aligns it as
{-# LANGUAGE QualifiedDo #-}
import qualified Some.Module.Monad as M
action :: M.SomeType a
action = M.do x <- u
res
M.return x
Probably thinking that M.do is a function, and not special notation.
It currently accepts the following alignment which also parses correctly, but looks ugly.
action :: M.SomeType a
action =
M.do
x <- u
res
M.return x
Furthermore, since the notation is not recognized, it will get confused with other multi-line notation, like list. Such as in the following example, which Haskell mode will align to configurations that don't parse.
action :: M.SomeType a
action =
M.do
x <- u
fooList
[ M.do
res1
, M.do
res2
]
M.return
I hit the same problem
This is my current workaround in a project specific basis:
- Add the "LVM.do" to
haskell-indentation-expression-list), the same as howdois. - override function haskell-indentation-peek-token with your additional qualified do.
(add-hook 'haskell-mode-hook
(lambda ()
(xref-etags-mode)
;; support LVM.do keyword
(push
`("LVM.do" . ,(apply-partially 'haskell-indentation-with-starter
'haskell-indentation-expression-layout))
haskell-indentation-expression-list)
(defun haskell-indentation-peek-token ()
"Return token starting at point."
(cond ((looking-at "\\(if\\|then\\|else\\|let\\|in\\|mdo\\|rec\\|do\\|LVM.do\\|proc\\|case\\|of\\|where\\|module\\|signature\\|deriving\\|import\\|data\\|type\\|newtype\\|class\\|instance\\)\\([^[:alnum:]'_]\\|$\\)")
(match-string-no-properties 1))
((looking-at "[][(){}[,;]")
(match-string-no-properties 0))
((looking-at "\\(\\\\\\|->\\|<-\\|::\\|=\\||\\|=>\\)\\([^-:!#$%&*+./<=>?@\\\\^|~]\\|$\\)")
(match-string-no-properties 1))
((looking-at "\\(→\\|←\\|∷\\|⇒\\)\\([^-:!#$%&*+./<=>?@\\\\^|~]\\|$\\)")
(let ((tok (match-string-no-properties 1)))
(or (cdr (assoc tok haskell-indentation-unicode-tokens)) tok)))
((looking-at"[-:!#$%&*+./<=>?@\\\\^|~`]" )
'operator)
(t 'value)))
))
I will think a bit how to make this part of a PR to upstream.