• Stars
    star
    388
  • Rank 110,734 (Top 3 %)
  • Language
    Emacs Lisp
  • Created about 8 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Dante: Emacs mode for Interactive Haskell

https://badges.gitter.im/dante-mode/Lobby.svg https://melpa.org/packages/dante-badge.svg https://stable.melpa.org/packages/dante-badge.svg

Dante provides a frontend to GHCi features: type-checking, execution, completion and cross referencing. It integrates with standard Emacs tooling as much as possible.

Feature summary and cheat-sheet

FeatureMode/CommandKeybinding
On the fly type checkingflymake-mode
Completioncompany-mode
Type in echo areaeldoc-mode
Goto definitionxref-find-definitionsM-.
Find usesxref-find-referencesM-?
Remote operation(automatic with tramp)
Error correctionattrap-attrap
Type of selectiondante-type-atC-c .
Info at pointdante-infoC-c ,
REPLoiddante-eval-blockC-c ”
Restartdante-restart
Diagnosisdante-diagnose

REPLoid

You can evaluate code by writing it in a comment of the form -- >>> and run dante-eval-block.

Example:

example :: [String]
example = ["This is an example", "of", "interactive", "evaluation"]

-- >>> intercalate " " example

In the above file, if you invoke dante-eval-block on the line containing “intercalate”, you’ll get:

-- >>> intercalate " " example
-- "This is an example of interactive evaluation"
--

Several commands in the same block will be executed in at once, so you can have local let statements.

-- >>> let foo = "foo"
--
-- >>> foo ++ "bar"
-- "foobar"
---

Any GHCi command can be put in such a block, but note however that:

  1. The GHCi state will not be maintained across several calls to dante-eval-block. In fact, Dante liberally executes :r and :l, and (re)sets various GHCi options.
  2. It is not supported to load and/or unload modules in such blocks, or set unexpected options. This may work, or may mess with Dante internals.

So if your goal is run your webserver/database/etc. within GHCi, you should not do it using dante.

Completion

Completion works only when the current file can be loaded by GHCi (ie. is free of errors). So, this is not very useful. To mitigate the problem, Dante defers type-errors to runtime when loading.

Remote operation

When loading a remote (Tramp) path, GHCi will be run on the remote host, automatically.

However, if programs such as nix-shell are not found on the remote host, you may need to adjust the tramp path. For example:

(add-to-list 'tramp-remote-path 'tramp-own-remote-path)

Error correction

Error correction is implemented in the sister package attrap.

Using hlint

Dante is a GHCi interaction mode. Therefore it does not provide any support for hlint. However, you can use a third party support for hlint in addition to Dante. In fact attrap even provides support for interactive application of hints. See that package documentation for configuration.

Installation

Dante can be installed by any usual means. (Use-package is a pretty popular option)

Configuration

Eldoc

Dante has builtin Eldoc support (showing info about the symbol at point in the echo area when idle.) Unfortunately, at the time of writing (Oct 2022), the standard Haskell mode uses the old eldoc API, overriding Dante’s Eldoc support. I recommend just disabling the standard Haskell mode Eldoc support, which IMO isn’t very helpful anyway, like so:

(add-hook 'haskell-mode-hook
          (defun my-fix-hs-eldoc ()
            (setq eldoc-documentation-strategy #'eldoc-documentation-default)))

Configuring the GHCi loading method

Configuration can be important to make sure that GHCi is properly loaded by dante. Even though Dante will do its best to figure out the proper way to load GHCi for your project, it may still fail. You can guide Dante’s behavior by customizing variables. Note in particular that customization can be done on a per-file, per-package or per-project basis by using file- and directory-local variables (as recommended above).

In fact typical way to configure GHCi command line is to a add a .dir-locals.el file to your project root which sets the loading method. The loading method is a recipe to find out the root of the project and the command line to use to start GHCi.

((nil . ((dante-methods . (new-impure-nix)))))

Replace new-impure-nix with the proper value, which you can figure out by M-x describe-variable <RET> dante-methods-alist.

Configuring the Cabal target

For a multi-target project, it can be necessary to tell dante which target to pass to the cabal repl or stack command. The best method is to create another .dir-locals.el file in the top-level directory of the sources of the target in question. For instance, if a sil-parser-test executable resides in stand-in-language/test/, you can create the following file in that directory:

((nil . ((dante-target . "sil:sil-parser-test"))))

When using stack and a test suite, the following configuration in the test source directory will cause the --test flag to be passed when loading the files there:

((nil . ((dante-target . "--test"))))

More control over the GHCi command line

For more direct control over the command line, you can set dante-repl-command-line directly. If Dante additionally fails to find the project root using any of the dante-methods, configure dante-project-root explicitly. (Do it using dir-locals.el.)

Example full configuration

(use-package dante
  :ensure t ; ask use-package to install the package
  :after haskell-mode
  :commands 'dante-mode
  :init
  ;; flycheck backend deprecated October 2022
  ;; (add-hook 'haskell-mode-hook 'flycheck-mode)

  (add-hook 'haskell-mode-hook 'flymake-mode)
  (remove-hook 'flymake-diagnostic-functions 'flymake-proc-legacy-flymake)
  (add-hook 'haskell-mode-hook 'dante-mode)
  (add-hook 'haskell-mode-hook
            (defun my-fix-hs-eldoc ()
              (setq eldoc-documentation-strategy #'eldoc-documentation-default)))
  :config
  (require 'flymake-flycheck)
  (defalias 'flymake-hlint
    (flymake-flycheck-diagnostic-function-for 'haskell-hlint))
  (add-to-list 'flymake-diagnostic-functions 'flymake-hlint)
  ;; flycheck backend deprecated October 2022
  ;; (flycheck-add-next-checker 'haskell-dante '(info . haskell-hlint)))

Troubleshooting

If dante-type-at gives Couldn't guess that module name. Does it exist? or xref-find-definitions gives ~No definitions found for: “/tmp/danteTqJJvj.hs” ~, you may need to add your targets to .dir-locals.el; see the Configuration section above.

Finally, Use M-x customize-group dante to read the documentation for all customizable variables.

In the “press”

More Repositories

1

boon

Ergonomic Command Mode for Emacs
Emacs Lisp
321
star
2

styx

A nix-based Haskell project manager
Haskell
160
star
3

nano-Agda

Tiny type-checker with dependent types
Haskell
76
star
4

attrap

ATtempt To Repair At Point (emacs flycheck extension)
Emacs Lisp
40
star
5

prettiest

The Prettiest Printer
Haskell
35
star
6

sctt

Type-Theory in Sequent Calculus
Haskell
13
star
7

glpk-hs

Haskell bindings to glpk
Haskell
12
star
8

topics

Various interesting topics I'm looking at
Haskell
12
star
9

MarXup

Markup language on top of Haskell
Haskell
11
star
10

emacs-semantics-theming

Foundation for building semantically meaningful themes over emacs
Emacs Lisp
11
star
11

lp-diagrams

An EDSL for diagrams based based on linear constraints
Haskell
7
star
12

lcr

Lightweight coroutines in elisp
Emacs Lisp
6
star
13

ProbInfer

Material for the course
Haskell
5
star
14

linear-smc

Linear Types, Symmetric Monoidal Categories, and Tensors
Haskell
5
star
15

organ

Haskell
4
star
16

hcad

Haskell library for CAD
Haskell
4
star
17

ControlledFusion

Haskell
3
star
18

inox

A language with linear types
Haskell
3
star
19

lp-diagrams-svg

SVG backend for lp-diagrams
Haskell
3
star
20

typography-geometry

Drawings for printed text documents
Haskell
3
star
21

TTNameBinders

Adventures with names and binders in type-theory
Haskell
3
star
22

whynote

Minimal Note Taking program
Haskell
3
star
23

FOL

Minimal FOL prover
Haskell
2
star
24

gasp

Another Haskell Prelude for Algebraic Classes and Structures
Haskell
2
star
25

imbib

bibtex management functions and gui
Haskell
2
star
26

hgal

Haskell Graph Automorphism Library
Haskell
2
star
27

polynomials-bernstein

Haskell
2
star
28

Cake

Build system as a Haskell library
Haskell
2
star
29

Parsek

The Parsek library developed by Koen Claessen in his functional pearl article Parallel Parsing Processes
Haskell
1
star
30

Generic-Programming-WIth-Dependent-Types

A translation to Agda of the paper with the same title of Altenkirch et al.
1
star
31

labeled-tree

Haskell labeled trees
Haskell
1
star
32

sparse-matrix

sparse matrix represented as quad-tree
Haskell
1
star
33

nnn

Not a Neural Network library
Haskell
1
star
34

labeled-graph

Haskell Labeled Graph
Haskell
1
star
35

nofib

Haskell
1
star
36

cmap

emacs: do at point
Emacs Lisp
1
star
37

dvi-processing

Processing of dvi files
Haskell
1
star
38

python-ht24

live coding results
Python
1
star