Closed dmvianna closed 1 year ago
I don't know much about the merits of new-repl vs repl, but instead of using new-repl, you can solve your issue by assigning a value to the dante-target variable. This can be done very conveniently using Emacs' native directory variable feature (https://www.gnu.org/software/emacs/manual/html_node/elisp/Directory-Local-Variables.html).
For an example how I use this, have a look at my project here: https://github.com/sboehler/beans. There is a .dir-locals.el file in each source directory (/app, /src, /test) which defines a target for the cabal repl command issued by dante. So whenever I open a Haskell file in /src, the associated dante process will use lib:beans as target.
In addition, I use a .dir-locals.el file at the project root, to customize general Haskell-mode settings.
Hope this helps!
Interesting.
cabal repl exe:level02-exe
works as expected.
;; .dir-locals.el
((haskell-mode . (
(dante-target . "exe:level02-exe")
)))
Does not help. Notice below that Dante does pick up the config from .dir-locals.el
.
This is the buffer associated with the GHCi session. This buffer
is normally hidden, but the GHCi process ended.
EXTRA TROUBLESHOOTING INFO
Process state change: exited abnormally with code 1
default-directory "/Users/dmvianna/sandbox/applied-fp-course/"
dante-command-line ("nix-shell" "--run" "cabal repl exe:level02-exe --builddir=dist/dante")
dante-state dead
dante-queue (#[257 "r\302\301!\203\302\301!q\210\212\301b\210\300!*\207" [#[257 "\211\306\307\310\"\304\"\211\303\205\211\211\203\307\311\"\301!\262\202R\302\211\205)\312 ?\313 )\300\2036\314\2027\315\316\317\320\321\322\323\300\301\304%\324\"\325\326%\"\262\262\262\262\262\262\207" [nil #[257 "\303\304p!!\301\305\306\307\310\311\312\313\314\300
\"\315\"\316\317%\"\320\203I@\321!
>\2040\322\323\324D\"\210\211\325H\326=\204=\211B\262\210\211T\262A\262\202\266\211\237\262\"\207" [haskell-dante #[128 "\301\302\300#\207" [#s(flycheck-syntax-check #<buffer Core.hs> haskell-dante nil "/Users/dmvianna/sandbox/applied-fp-course/src/Level02/") apply flycheck-report-buffer-checker-status] 5 "
(fn &rest ARGS)"] cl-struct-flycheck-error-tags dante-local-name buffer-file-name finished nil mapcar make-byte-code 257 "\302\300p\301$\207" vconcat vector [dante-fly-message] 6 "
(fn IT)" 0 type-of signal wrong-type-argument flycheck-error 7 splice] 13 "
(fn MESSAGES)"] 171 nil "/Users/dmvianna/sandbox/applied-fp-course/src/Level02/Core.hs" dante-temp-epoch s-equals\? buffer-local-value dante-loaded-file dante-load-message flycheck-running-p save-buffer ":set -fbyte-code" ":set -fobject-code" dante-async-call make-byte-code 257 "p\211\303q\305\300\204\304\203\306\202\307\300\203\310\202\311\312\302!Q!\313\311\314\315\316\317\320\321\301\302#\322\"\323\324%#\262\262\262\207" vconcat vector [dante-async-write ":r" ":l " "*" "" dante-local-name dante-load-loop nil make-byte-code 257 "\211\211G\305U\203\211A\262\242\202\306\307\310GD\"\211A\262\242@\301\211\266\203\302q\300!\262\262\207" vconcat vector [dante-loaded-file dante-load-message 3 signal wrong-number-of-arguments nil] 7 "
(fn V14)"] 16 "
(fn V9)" flycheck-mode] 20 "
(fn V3)"] #<marker at 1183 in Core.hs> marker-buffer] 3 "
(fn BUFFER)"])
dante-loaded-file "<DANTE:NO-FILE-LOADED>"
dante-load-message nil
lcr-process-callback #[257 "\303\304\305\300#\210r\306\302!\203\306\302!q\210\212\302b\210\301!*\207" [#<buffer dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> #[257 "\302\303\"\210\300\304\305\306#!\210\307\301!\207" [#[257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" [("[31;1merror:[0m file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I), at [1m/Users/dmvianna/sandbox/applied-fp-course/default.nix[0m:1:20
") (nil) (#[0 "\303\242?\211\203\305\306\307\310\311\312\302\303\304#\313\"\314\315%!\202,\316\302\242\317\320\224SO!\301q\300!\262\262\207" [#[257 "\300\301!\207" [dante-set-state running] 3 "
(fn START-MESSAGES)"] #<buffer Core.hs> ("[31;1merror:[0m file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I), at [1m/Users/dmvianna/sandbox/applied-fp-course/default.nix[0m:1:20
") (nil) #6 dante-async-read make-byte-code 257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" vconcat vector [dante-ghci-prompt string-match lcr-yield] 7 "
(fn V60)" s-trim-right 0 1] 10]) dante-ghci-prompt string-match lcr-yield] 7 "
(fn V60)"] #<buffer dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> dante-debug inputs s-replace "
" "" dante-schedule-next] 6 "
(fn INPUT)"] #<marker at 1 in dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> lcr-set-local lcr-process-callback nil marker-buffer] 5 "
(fn INPUT)"]
WHAT TO DO NEXT
Verify that the GHCi REPL can be loaded manually, then try to
customize (probably file-locally or directory-locally)
`dante-project-root' and/or `dante-repl-command-line'. If you
fixed the problem, just kill this buffer, Dante will make a fresh
one and attempt to restart GHCi automatically.
If you do not want Dante will not attempt to restart GHCi, just
leave this buffer around. You can always run `dante-restart' to
make it try again.
How did you add dante
to your emacs? I think I had the same issue with the recommended use-package
setup from the README file (https://github.com/jyp/dante#installation). I am now using the code below and it seems to work, my recent key insight was that the flycheck-mode
hook has to be enabled before the dante-mode
hook:
(use-package dante
:ensure t
:after haskell-mode
:commands 'dante-mode
:init
(add-hook 'haskell-mode-hook 'flycheck-mode)
(add-hook 'haskell-mode-hook 'dante-mode)
:config
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint))
)
Can you test this?
---
This is the buffer associated with the GHCi session. This buffer
is normally hidden, but the GHCi process ended.
EXTRA TROUBLESHOOTING INFO
Process state change: exited abnormally with code 1
default-directory "/Users/dmvianna/sandbox/applied-fp-course/"
dante-command-line ("nix-shell" "--run" "cabal repl exe:level02-exe --builddir=dist/dante")
dante-state dead
dante-queue (#[257 "r\302\301!\203 \302\301!q\210\212\301b\210\300!*\207" [#[257 "\211\306\307\310\"\304\"\211\303\205 \211\211\203 \307\311\"\301!\262\202R \302\211\205) \312 ?\313 )\300\2036 \314\2027 \315\316\317\320\321\322\323\300\301\304%\324\"\325\326%\"\262\262\262\262\262\262\207" [nil #[257 "\303\304p!!\301\305\306\307\310\311\312\313\314\300
\"\315\"\316\317%\"\320\203I @\321!
>\2040 \322\323\324D\"\210\211\325H\326=\204= \211B\262\210\211T\262A\262\202 \266\211\237\262\"\207" [haskell-dante #[128 "\301\302\300#\207" [#s(flycheck-syntax-check #<buffer Core.hs> haskell-dante nil "/Users/dmvianna/sandbox/applied-fp-course/src/Level02/") apply flycheck-report-buffer-checker-status] 5 "
(fn &rest ARGS)"] cl-struct-flycheck-error-tags dante-local-name buffer-file-name finished nil mapcar make-byte-code 257 "\302\300p\301$\207" vconcat vector [dante-fly-message] 6 "
(fn IT)" 0 type-of signal wrong-type-argument flycheck-error 7 splice] 13 "
(fn MESSAGES)"] 3 nil "/Users/dmvianna/sandbox/applied-fp-course/src/Level02/Core.hs" dante-temp-epoch s-equals\? buffer-local-value dante-loaded-file dante-load-message flycheck-running-p save-buffer ":set -fbyte-code" ":set -fobject-code" dante-async-call make-byte-code 257 "p\211\303q\305\300\204 \304\203 \306\202 \307\300\203 \310\202 \311\312\302!Q!\313\311\314\315\316\317\320\321\301\302#\322\"\323\324%#\262\262\262\207" vconcat vector [dante-async-write ":r" ":l " "*" "" dante-local-name dante-load-loop nil make-byte-code 257 "\211\211G\305U\203 \211A\262\242\202 \306\307\310GD\"\211A\262\242@\301\211\266\203\302q\300!\262\262\207" vconcat vector [dante-loaded-file dante-load-message 3 signal wrong-number-of-arguments nil] 7 "
(fn V562)"] 16 "
(fn V557)" flycheck-mode] 20 "
(fn V551)"] #<marker at 1 in Core.hs> marker-buffer] 3 "
(fn BUFFER)"])
dante-loaded-file "<DANTE:NO-FILE-LOADED>"
dante-load-message nil
lcr-process-callback #[257 "\303\304\305\300#\210r\306\302!\203 \306\302!q\210\212\302b\210\301!*\207" [#<buffer dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> #[257 "\302\303\"\210\300\304\305\306#!\210\307\301!\207" [#[257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" [("[31;1merror:[0m file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I), at [1m/Users/dmvianna/sandbox/applied-fp-course/default.nix[0m:1:20
") (nil) (#[0 "\303\242?\211\203 \305\306\307\310\311\312\302\303\304#\313\"\314\315%!\202, \316\302\242\317\320\224SO!\301q\300!\262\262\207" [#[257 "\300\301!\207" [dante-set-state running] 3 "
(fn START-MESSAGES)"] #<buffer Core.hs> ("[31;1merror:[0m file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I), at [1m/Users/dmvianna/sandbox/applied-fp-course/default.nix[0m:1:20
") (nil) #6 dante-async-read make-byte-code 257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" vconcat vector [dante-ghci-prompt string-match lcr-yield] 7 "
(fn V608)" s-trim-right 0 1] 10]) dante-ghci-prompt string-match lcr-yield] 7 "
(fn V608)"] #<buffer dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> dante-debug inputs s-replace "
" "" dante-schedule-next] 6 "
(fn INPUT)"] #<marker at 1 in dante:applied-fp-course:exe:level02-exe:/Users/dmvianna/sandbox/applied-fp-course/> lcr-set-local lcr-process-callback nil marker-buffer] 5 "
(fn INPUT)"]
WHAT TO DO NEXT
Verify that the GHCi REPL can be loaded manually, then try to
customize (probably file-locally or directory-locally)
`dante-project-root' and/or `dante-repl-command-line'. If you
fixed the problem, just kill this buffer, Dante will make a fresh
one and attempt to restart GHCi automatically.
If you do not want Dante will not attempt to restart GHCi, just
leave this buffer around. You can always run `dante-restart' to
make it try again.
Has new-repl superseded repl? If so I'll switch to that, but my understanding was that "it's not quite ready yet". Now, it should be easy to customize dante-repl-command-line-methods-alist
to your liking.
BTW the answer given by @sboehler should work as well. Dante really simply runs the command line that you see, so if it works manually it should work via dante as well.
afaik new-repl doesn't support multiple targets, and without a specified
target, it defaults to all
, which doesn't work.
On Sat, Sep 1, 2018, 3:06 PM Jean-Philippe Bernardy < notifications@github.com> wrote:
Has new-repl superseded repl? If so I'll switch to that, but my understanding was that "it's not quite ready yet". Now, it should be easy to customize dante-repl-command-line-methods-alist to your liking.
BTW the answer given by @sboehler https://github.com/sboehler should work as well. Dante really simply runs the command line that you see, so if it works manually it should work via dante as well.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jyp/dante/issues/83#issuecomment-417880669, or mute the thread https://github.com/notifications/unsubscribe-auth/ACNoMSJejKNlSe6iwDoCo3VyQuMRLv3eks5uWtrMgaJpZM4WPB10 .
@dmvianna the following note might be relevant: #58
Useless. It works with new-repl
and without .dir-locals.el
seamlessly. If I just place .dir-locals.el
in the directory it simply kills dante. With or without new-repl
, and with or without flycheck
, and in whatever order. And by the way, I want flycheck to work.
I made a emacs module which has a feature that returns cabal target based on current buffer .
It is not perfect but it works for me at least. I tested it with some of my projects and the applied fp course. It does not need to set .dir-locals.el but the downside is that it requires more memory due to haskell runtime.
In order to use below setup, You need to enable emacs dynamic module feature.
You can check your emacs build configuration with (print system-configuration-options)
in emacs.
If you see --with-modules
then you are good to go.
git clone https://github.com/templateK/edm-haskell.git
cd edm-haskell
cabal new-build flib:edm-haskell
mkdir -p ~/.emacs.d/native
# in macos
cp $(find . -name "libedm-haskell.dylib" -type f) ~/.emacs.d/native/
# in linux
cp $(find . -name "libedm-haskell.so" -type f) ~/.emacs.d/native/
(use-package dante
:after flycheck
:init
(defun dante-dynamic-target ()
"Return dante-target based on it's cell type."
;; check dante-target defined as non-empty string.
(if (and (boundp 'dante-target)
dante-target
(not (numberp dante-target))
(not (string-empty-p dante-target)))
dante-target
;; otherwise try to get cabal project target through edm-haskell.
(if-let* ((cabal-file (haskell-cabal-find-file))
(cabal-target (edm-haskell-cabal-target cabal-file (buffer-file-name))))
cabal-target
;; if all above fails, just return nil or you can change to other default value.
nil)))
:config
;; emacs must be build with configure option --with-modules
;; to see configuration (print system-configuration-options)
;; dylib filename must be absolute path otherwise it throws "dlopen: image not found."
(let ((edm-filename (concat (getenv "HOME") "/.emacs.d/native/libedm-haskell.dylib")))
(if (and (file-exists-p edm-filename) (file-executable-p edm-filename))
(progn
(module-load edm-filename)
(fset 'dante-target 'dante-dynamic-target)
(setq-default dante-repl-command-line
'("cabal" "new-repl" (dante-target) "--builddir=dist-newstyle/dante")))
(setq-default dante-repl-command-line '("cabal" "repl" dante-target "--builddir=dist/dante"))))
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint))
) ;; end of dante
dante-buffer-name
function in dante.el
in order to use edm-haskelldante.el
@@ -654,7 +654,7 @@
"Create a dante process buffer name."
(let* ((root (dante-project-root))
(package-name (dante-package-name)))
- (concat "*dante:" package-name ":" dante-target ":" root "*")))
+ (concat "*dante:" package-name ":" (dante-target) ":" root "*")))
After the patch, don't forget to compile dante.el. You can do that with byte-compile-file
in emacs.
@sboehler You recommend setting dirlocals yet in your repository you have since removed them. What is the way you currently deal with multiple targets? Do you have any recommendations?
@gregor-alexandru I have stopped using dante in that project.
@sboehler did you find any replacement for it?
Not sure if this is still relevant for others. However, in my case, I forgot to add a .ghci
file to the project root and seems like I've encounter the same issue (not being able to load the executable target). Adding the following line solved the issue: :set -iapp/
. app
here is the directory where my executable module lives.
Can multiple-targets work yet? I'd simply like to be able to work on tests and a library simultaneously.
The relevant intero
: https://github.com/chrisdone/intero/blob/master/elisp/intero.el#L621
The relevant stack
docs: https://docs.haskellstack.org/en/stable/build_command/#target-syntax
I still have no clue how to use dante's targets, and just would like them to work on my tests.
I'm on spacemacs but I did not have trouble getting this to work with .dir-locals.el
for sbv's benchmarking suite library.
;; SBVBenchSuite/.dir-locals.el
((nil . ((dante-project-root . "~/Programming/sbv")
(dante-target . "sbv:SBVBench"))))
I even have another dir-locals.el
at the library level:
~/Programming/sbv:master? λ pwd
/home/doyougnu/Programming/sbv
~/Programming/sbv:master? λ ls -a
. .hlint.yaml LICENSE buildUtils release.nix
.. .travis.yml Makefile cabal.project.local sbv.cabal
.appveyor.yml CHANGES.md README.md cabal.project.local~ shell.nix
.dir-locals.el COPYRIGHT SBVBenchSuite default.nix
.ghci Data SBVTestSuite dist
.git Documentation SMTSolverVersions.md dist-newstyle
.gitignore INSTALL Setup.hs profile-shell.nix
@doyougnu how specifying 1 target makes it work with multiple targets?
There are two .dir-locals.el
files: one for sbv:SBVBench
in the SBVBenchSuite/
directory, and another for just sbv
in the project's root directory. So if I open a file in the SBVBenchSuite
directory then dante finds the first .dir-locals.el
file, namely the one I posted above. However, if I open a file in src
then it finds the .dir-locals.el
file in the root directory.
This setup is discussed in detail in the emacs manual, you'll want to check out Directory Variables
and File Local Variables
. This is an example of using directory variables, you could set any of these variables as a local file variable in some Foo.hs
file. Here is my project root .dir-locals.el
;; sbv/.dir-locals.el
((nil . ((dante-methods . (nix-ghci)))))
I only set the dante-methods
here and let dante use the default sbv
target it finds from the project root. If you really had to you could just overwrite dante-repl-command-line
to change the entire dante repl call.
got it working (using dante-repl-command-line
on doom emacs):
(use-package dante
:ensure t
:after haskell-mode
:commands 'dante-mode
:init
(add-hook 'haskell-mode-hook 'flycheck-mode)
(add-hook 'haskell-mode-hook 'company-mode)
(add-hook 'haskell-mode-hook 'dante-mode)
:config
(setq-default dante-repl-command-line
;; Edit this if you use stack. Also set dante-target as needed (maybe "--test").
'("cabal" "new-repl" dante-target "--builddir=dist-newstyle/dante"))
)
;; stand-in-language/src/.dir-locals.el
((nil . ((dante-project-root . "/home/hhefesto/src/stand-in-language/")
;; (dante-target . "")
)))
;; stand-in-language/test/.dir-locals.el
((nil . ((dante-project-root . "/home/hhefesto/src/stand-in-language/")
(dante-target . "sil:sil-parser-test"))))
Thanks, @hhefesto.
Also if you struggle to get dante working with flycheck and Haskell hlint
, as i did, you can add
(use-package dante
:ensure t
:after haskell-mode
:commands 'dante-mode
:init
(add-hook 'haskell-mode-hook 'flycheck-mode)
(add-hook 'haskell-mode-hook 'company-mode)
(add-hook 'haskell-mode-hook 'dante-mode)
:config
(setq-default dante-repl-command-line
'("cabal" "new-repl" dante-target "--builddir=dist-newstyle/dante"))
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint))
)
to your Doom Emacs config.el
I've put more information regarding this in the doc.
is hardcoded into
dante
. However, it will not work in a project with multiple targets such as qfpl applied fp course. I find that (at least in my system)works fine in the shell.
Would it be possible to address this limitation in Dante by using
new-repl
in nix-shell? Dante works fine when I replacecabal repl
withcabal new-repl
in my system.