Emacs Haskell缩进

23

请帮我设置Emacs haskell-mode的适当缩进

当我试图输入ADT或记录之类的内容时,按下<ENTER>后会进入错误的列,而按下<TAB>键不能切换到正确的列,直到我输入|或';'为止!

data MyADT = Oh
           | Hi
           | Hello
             | <- the cursor is here again!

我试图解决我设定的问题

(define-key global-map (kbd "RET") 'reindent-then-newline-and-indent)

我在我的.emacs文件中加入了这段代码,但按下<enter>键时它不会自动缩进当前行!

另一个奇怪的行为:case语句的缩进

oneChar c =  case lookup c simpleEscapes of
  | <- what? here?!

1
case语句是正确的行为。 - jrockway
1
如果您按两次Tab键,它会在正确的缩进位置插入一个'|'。 - edon
如果还没有 |,那么就不会返回任何内容。因此,在按下 Tab 键之前,我必须在该行中输入一些内容。 - Valentin Golev
@jrockwaym,即使第一个也可以被某些人认为是正确的。 - Valentin Golev
3
也许需要为不同的人实现一些不同的缩进算法。我们需要一些Emacs大师来帮忙。 - jxy
我同意jrockway的观点,即oneChar的行为是正确的。使用2个空格插入下一级缩进就足够了。在“case”下面输入|会给你太多的空白。 - HaskellElephant
3个回答

9

听起来你是先输入<Enter>,然后输入"|",最后再输入<Tab>。如果我这样做,我也会得到相同的结果。但是如果我先输入<Enter>,然后输入<Tab>,再输入两次<Tab>,它就会自动插入"|"并正确对齐,如下所示:

data MyADT = Oh
           | Hi
           |<Cursor>

当我使用M-x eval-expression haskell-version <Enter>命令检查我的haskell-mode版本时,我得到了“v2_4”的结果。
Emacs的haskell-mode并不能完全分析源代码,因此“自动”功能是近似的。在新行上按<Tab>键多次可以循环显示几种可能的缩进方式,有时还会插入类似于代数数据类型的"|"文本。

4

注意:我不是Haskell用户,所以请谨慎参考。

当您在Hello后按下RET时,Emacs不知道您要添加一个|快速搜索显示您可以有其他符号)。 Haskell开发人员认为适当的缩进应该位于Hello中的H正下方。 如果缩进自动与上一行的|对齐,则所有您键入|的情况都会导致不正确的缩进。 做也不行,不做也不行...

其他编程模式(C / C ++,Lisp,Tcl,...)也存在同样的问题-它们无法预先知道您将在下一行放置什么,因此缩进可能不是您希望的。

一种解决方案是使用“电气化”键,即它们插入字符并强制重新缩进。 您可以使用以下代码轻松定义|为电气化:

(defun haskell-electric-| ()
  "it's electric!  (insert | and indent as long as the | follows whitespace)"
  (interactive)
  (insert "|")
  (if (string-match-p "^\\s-*|" (buffer-substring (line-beginning-position) 
                                                  (point)))
      (haskell-indentation-indent-line)))
(define-key haskell-mode-map "|" 'haskell-electric-|)

我添加了一个检查,以确保插入的 | 只前面有空格,您可以根据需要自定义或完全删除检查。
我推测在Haskell中可能还有其他值得电化的符号。

3

我注释了这一行

;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)

现在我的"tab"行为很好:至少它允许我选择一列而不是绑定到它喜欢的那一列。但是完全没有自动缩进有点让我烦恼,所以我希望这只是一个临时解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接