我正在尝试让intero运行。安装后,从现有堆栈项目中打开Haskell文件将导致:
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
signal(wrong-type-argument (stringp nil))
flycheck-buffer()
flycheck-buffer-automatically()
flycheck-perform-deferred-syntax-check()
set-window-buffer(#<window 1 on Lib.hs> #<buffer Lib.hs>)
window--display-buffer(#<buffer Lib.hs> #<window 1 on Lib.hs> reuse ((inhibit-same-window)))
display-buffer-same-window(#<buffer Lib.hs> ((inhibit-same-window)))
display-buffer(#<buffer Lib.hs> (display-buffer-same-window (inhibit-same-window)))
pop-to-buffer(#<buffer Lib.hs> (display-buffer-same-window (inhibit-same-window)) nil)
pop-to-buffer-same-window(#<buffer Lib.hs>)
find-file("~/test/src/Lib.hs" t)
funcall-interactively(find-file "~/test/src/Lib.hs" t)
call-interactively(find-file nil nil)
command-execute(find-file)
当我在同一缓冲区中运行
flycheck-buffer
时,即使源代码中有错误,也不会发生任何事情。这是我的
.emacs
文件的内容:(setq debug-on-error t)
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)
(package-refresh-contents)
(package-install 'intero)
(add-hook 'haskell-mode-hook 'intero-mode)
由于我使用的是Mac Os,因此我也尝试添加(如flycheck页面上的建议):
(package-install 'exec-path-from-shell)
(exec-path-from-shell-initialize)
但这没什么区别。
这是已安装的软件包版本:
$ ls ~/.emacs.d/elpa/
archives/
company-20191114.1356/
dash-20191109.1327/
epl-20180205.2049/
flycheck-20191126.1329/
haskell-mode-20191120.1923/
intero-20191103.1239/
pkg-info-20150517.1143/
这是使用GNU Emacs 26.3。
最佳答案
TL; DR
我发现了两个问题,并为每个问题(至少是暂时的)进行了修复。
我正在为它们都提交拉取请求,但与此同时,您可以通过直接编辑intero.el文件或(使用推荐的el-patch包)(推荐方式)自己解决问题。
1)未设置intero-ghc-version
这是由于使用了intero-ghc-version
局部变量而不是在(intero-ghc-version)
函数(L.2668)intero.el中调用函数intero-ghci-output-flags
的事实
修复:修补了intero-ghci-output-flags
函数:
代替
(split-string intero-ghc-version "\\."))))
经过
(split-string (intero-ghc-version) "\\."))))
(注意添加的括号)
2)将
append
误用于intero-start-process-in-buffer
中的字符串连接append
用于列表,concat
用于字符串,这是一个容易犯的错误,尤其是在Haskell中,String
与[Char]
等效(因此从技术上讲,是列表!)。修复:修补了intero.el的
intero-start-process-in-buffer
L.2335函数:代替
(process-send-string process (append ":set " flag "\n")))
经过
(process-send-string process (concat ":set " flag "\n")))
当前版本source code的第2335行,使用el-patch)
完成这些修改后,您就应该启动并运行了!
初始答案
同样的问题在这里。
这不是一个确定的答案,但是我有同样的问题,并且可能是由于
intero-ghci-output-flags
变量未正确设置而导致该问题被归因于函数intero-ghc-version
的运行。随时纠正我,因为我可能错过了一些东西。
通过遵循错误消息,我确认它是在
(flycheck-start-current-syntax-check checker)
函数的flycheck-buffer
中发生的。直接从haskell缓冲区运行此命令,则表明从intero.el文件(第2671行)中的
(split-string intero-ghc-version "\\.")
函数调用intero-ghci-output-flags
时发生了错误。这会尝试拆分内部版本(由文件中上面的
intero-ghc-version
函数设置)。通过运行
nil
可以确认该变量的值为M-x describe-variable -> intero-ghc-version
。在测试期间,我从
(intero-ghc-version)
获得了看似看不到的结果。有时(至少在第一次运行时?)它返回“8.4.4”,
有时它会失败并显示
"Wrong type argument: stringp, (58 115 101 116 32 45 102 111 98 106 ...)
我能够手动运行函数
intero-ghci-output-flags
并获得正确的输出而不会出现错误,一次,并且如果我第二次运行它会失败。但是,函数
(intero-ghc-version-raw)
始终返回“8.4.4”。经过实验后,自发出现的错误消息被转换为:
Debugger entered--Lisp error: (wrong-type-argument stringp (58 115 101 116 32 45 102 111 98 106 101 99 116 45 99 111 100 101 . "\n"))
process-send-string(#<process stack> (58 115 101 116 32 45 102 111 98 106 101 99 116 45 99 111 100 101 . "\n"))
#f(compiled-function (flag) #<bytecode 0x1785fe9>)("-fobject-code")
mapc(#f(compiled-function (flag) #<bytecode 0x1785fe9>) ("-fobject-code"))
intero-start-process-in-buffer(#<buffer intero:backend:pubiber /home/mika/programmation/haskell/pubiber> nil #<buffer Lib.hs> nil)
intero-get-worker-create(backend nil #<buffer Lib.hs> nil)
intero-buffer(backend)
intero-eldoc()
错误消息中的ASCII字符序列为“:set -fobject-code”。
消息中的“-fobject-code”是
intero-ghci-output-flags
函数的结果,因此看来它终于可以正常工作,但是其余代码失败了。注意:
每当intero尝试启动 session 时,都会重新评估文件的事实可能解释了为什么多次运行函数时,我得到不一致的结果。
PS 正在运行arch linux,系统在几分钟前更新,所有emacs软件包已更新。
----编辑----
因此,在看多一点之后,在函数
intero-start-process-in-buffer
中,该函数使用这些标志在第2334-2337行中启动内部交互过程: (set-process-query-on-exit-flag process nil)
(mapc
(lambda (flag)
(process-send-string process (append ":set " flag "\n")))
(intero-ghci-output-flags))
(process-send-string process ":set -fdefer-type-errors\n")
他们使用
append
而不是concat
来创建命令。用
append
替换concat
可以解决第二个错误,并且intero可以正常启动并且似乎可以正常工作(在设置intero-ghc-version
之后)。----编辑2 ----
刚刚想出了原始问题:
该函数使用变量
intero-ghc-version
而不是使用相同名称调用该函数。该函数应该充当值的惰性加载器,第一次调用intero-ghc-version-raw
,然后在随后的时间返回缓存的值。直接调用该变量不允许最初设置该值。
有关临时修补程序,请参阅TL; DR。