diff --git a/core/core-modules.el b/core/core-modules.el index a1fe7b365..72cc61f7f 100644 --- a/core/core-modules.el +++ b/core/core-modules.el @@ -172,7 +172,7 @@ following properties: :path [STRING] path to category root directory Example: - (doom-module-set :lang 'haskell :flags '(+dante))" + (doom-module-set :lang 'haskell :flags '(+lsp))" (puthash (cons category module) plist doom-modules)) (defun doom-module-path (category module &optional file) diff --git a/docs/modules.org b/docs/modules.org index 539f24be7..33b2bdbf4 100644 --- a/docs/modules.org +++ b/docs/modules.org @@ -117,7 +117,7 @@ Modules that bring support for a language or group of languages to Emacs. + [[file:../modules/lang/fstar/README.org][fstar]] - F* support + [[file:../modules/lang/gdscript/README.org][gdscript]] =+lsp= - TODO + [[file:../modules/lang/go/README.org][go]] =+lsp= - TODO -+ [[file:../modules/lang/haskell/README.org][haskell]] =+dante +ghcide +lsp= - TODO ++ [[file:../modules/lang/haskell/README.org][haskell]] =+lsp= - TODO + hy - TODO + [[file:../modules/lang/idris/README.org][idris]] - TODO + java =+meghanada +eclim +lsp= - TODO diff --git a/init.example.el b/init.example.el index 9045f290b..4d42f7fcf 100644 --- a/init.example.el +++ b/init.example.el @@ -132,7 +132,7 @@ ;;fstar ; (dependent) types and (monadic) effects and Z3 ;;gdscript ; the language you waited for ;;(go +lsp) ; the hipster dialect - ;;(haskell +dante) ; a language that's lazier than I am + ;;(haskell +lsp) ; a language that's lazier than I am ;;hy ; readability of scheme w/ speed of python ;;idris ; a language you can depend on ;;json ; At least it ain't XML diff --git a/modules/lang/haskell/+dante.el b/modules/lang/haskell/+dante.el deleted file mode 100644 index 2683abd8c..000000000 --- a/modules/lang/haskell/+dante.el +++ /dev/null @@ -1,41 +0,0 @@ -;;; lang/haskell/+dante.el -*- lexical-binding: t; -*- -;;;###if (featurep! +dante) - -(use-package! dante - :hook (haskell-mode-local-vars . dante-mode) - :init - (setq dante-load-flags '(;; defaults: - "+c" - "-Wwarn=missing-home-modules" - "-fno-diagnostics-show-caret" - ;; necessary to make attrap-attrap useful: - "-Wall" - ;; necessary to make company completion useful: - "-fdefer-typed-holes" - "-fdefer-type-errors")) - :config - (when (featurep! :checkers syntax) - (flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint))) - - (set-company-backend! 'dante-mode #'dante-company) - - (defadvice! +haskell--restore-modified-state-a (fn &rest args) - "Marks the buffer as falsely modified. -Dante quietly saves the current buffer (without triggering save hooks) before -invoking flycheck, unexpectedly leaving the buffer in an unmodified state. This -is annoying if we depend on save hooks to do work on the buffer (like -reformatting)." - :around #'dante-async-load-current-buffer - (let ((modified-p (buffer-modified-p))) - (apply fn args) - (if modified-p (set-buffer-modified-p t)))) - - (when (featurep 'evil) - (add-hook 'dante-mode-hook #'evil-normalize-keymaps)) - (map! :map dante-mode-map - :localleader - "t" #'dante-type-at - "i" #'dante-info - "l" #'haskell-process-load-file - "e" #'dante-eval-block - "a" #'attrap-attrap)) diff --git a/modules/lang/haskell/+lsp.el b/modules/lang/haskell/+lsp.el deleted file mode 100644 index f46eb854c..000000000 --- a/modules/lang/haskell/+lsp.el +++ /dev/null @@ -1,11 +0,0 @@ -;;; lang/haskell/+lsp.el -*- lexical-binding: t; -*- - -(use-package! lsp-haskell - :after lsp-mode - :preface (add-hook 'haskell-mode-local-vars-hook #'lsp!) - :config - (when (featurep! +ghcide) - (setq lsp-haskell-server-path "ghcide" - lsp-haskell-server-args nil)) - ;; Does some strange indentation if it pastes in the snippet - (setq-hook! 'haskell-mode-hook yas-indent-line 'fixed)) diff --git a/modules/lang/haskell/README.org b/modules/lang/haskell/README.org index 19632902d..971ef7e1d 100644 --- a/modules/lang/haskell/README.org +++ b/modules/lang/haskell/README.org @@ -5,152 +5,69 @@ * Table of Contents :TOC: - [[#description][Description]] - - [[#external-resources][External resources]] + - [[#maintainers][Maintainers]] - [[#module-flags][Module Flags]] - [[#plugins][Plugins]] - [[#prerequisites][Prerequisites]] - - [[#cabal][Cabal]] - - [[#lsp-haskell-language-server][LSP (haskell-language-server)]] - - [[#lsp-ghcide][LSP (ghcide)]] - - [[#stack][Stack]] - - [[#haskell-packages][Haskell packages]] +- [[#features][Features]] - [[#configuration][Configuration]] - - [[#using-the-new-style-cabal-repl][Using the new-style cabal REPL]] -- [[#troubleshooting][Troubleshooting]] * Description -This module adds [[https://www.haskell.org/][Haskell]] support, powered by either [[https://github.com/jyp/dante][dante]] (the default) or LSP -(haskell-language-server or ghcide). +Adds Haskell support to Doom Emacs. -+ Code completion (~company-ghc~) -+ Look up documentation (~hoogle~) -+ eldoc support (~dante~) -+ REPL (~ghci~) -+ Syntax-checking (~flycheck~) -+ Code navigation (~dante~) -+ [[https://github.com/hlissner/doom-snippets/tree/master/haskell-mode][Snippets]] +** Maintainers +This module has no dedicated maintainers. -** External resources -Here are a few resources I've found indispensable in my Haskell adventures: - -+ [[http://learnyouahaskell.com/][Learn you a haskell for great good]] -+ [[http://haskellbook.com/][Haskell Programming from first principles]] -+ [[https://github.com/krispo/awesome-haskell][Awesome Haskell]]: an extensive list of haskell resources -+ [[https://docs.haskellstack.org/en/stable/README/][The Haskell Tool Stack docs]] - ** Module Flags -+ =+dante= Enables dante; a fork of intero aimed at lightweightedness. It - doesn't depend on =stack=, supports both ~cabal~-only and ~stack~ projects, - but lacks eldoc support. -+ =+ghcide= Enables LSP support with ghcide (requires the ~:tools lsp~ module). -+ =+lsp= Enables LSP support with haskell-language-server (requires the ~:tools lsp~ - module). ++ =+lsp= Enable LSP support with for [[https://github.com/haskell/haskell-language-server][haskell-language-server]] (requires the =:tools lsp= module). ** Plugins + [[https://github.com/haskell/haskell-mode][haskell-mode]] -+ =+dante= - + [[https://github.com/jyp/dante][dante]] - + [[https://github.com/jyp/attrap][attrap]] -+ =+lsp= - + [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]] ++ [[https://github.com/emacs-lsp/lsp-haskell][lsp-haskell]] (=+lsp=, =:tools lsp=) * Prerequisites -Depending on whether you use Dante, haskell-language-server or ghcide, your -dependencies will differ: +It is recommended to install the haskell tooling using [[https://www.haskell.org/ghcup/][ghcup]]. Only ghc is needed +for basic functionality: -+ Dante users need =cabal=, =ghc= and =ghc-mod= -+ LSP users need the =haskell-language-server= LSP server OR =ghcide= -+ All users will need the =hoogle= package - -** Cabal -To use Dante, you need =cabal= (the haskell package builder) and =ghci= (the -compiler, syntax checker & repl): - -*** MacOS -#+BEGIN_SRC sh -brew install cabal-install ghc +#+BEGIN_SRC bash +ghcup install ghc #+END_SRC -*** Arch Linux -#+BEGIN_SRC sh -sudo pacman -S cabal-install ghc -#+END_SRC - -*** openSUSE -#+BEGIN_SRC sh :dir /sudo:: -sudo zypper install cabal-install ghc -#+END_SRC - -** LSP (haskell-language-server) -You will need =stack= and =git= installed. - -You will find a comprehensive [[https://github.com/haskell/haskell-language-server#installation][instructions for haskell-language-server on its project page]], but if you are using [[https://www.haskell.org/ghcup/][ghcup]]: +but =+lsp= users should also install the language server: #+BEGIN_SRC bash ghcup install hls #+END_SRC -** LSP (ghcide) -See https://github.com/digital-asset/ghcide for install instructions. +Installing [[https://www.haskell.org/cabal/][cabal]] or [[https://docs.haskellstack.org/en/stable/README/][stack]] as well is recommended, and can be done through +=ghcup=. -** Stack -To use LSP, you need =stack=: +=haskell-mode= provides support for [[https://github.com/ndmitchell/hoogle][hoogle]], which can be installed through +system package manager, cabal, or stack. -*** MacOS -#+BEGIN_SRC sh -brew install haskell-stack -stack setup -#+END_SRC -*** Arch Linux -#+BEGIN_SRC sh -sudo pacman -S stack -# Replace pacaur with your AUR package manager of choice -pacaur -S ncurses5-compat-lib -stack setup -#+END_SRC +=haskell-language-server= provides support for [[https://github.com/ndmitchell/hlint/][hlint]], and haskell code +formatters such as [[https://github.com/lspitzner/brittany][brittany]], [[https://github.com/ennocramer/floskell][floskell]], [[https://github.com/tweag/ormolu][ormolu]], [[https://github.com/fourmolu/fourmolu][fourmolu]], and [[https://github.com/haskell/stylish-haskell][stylish-haskell]], +which can be installed through system package manager, cabal, or stack. -*** openSUSE -#+BEGIN_SRC sh :dir /sudo:: -sudo zypper install stack -stack setup -#+END_SRC +* Features +This module intergrates the haskell packages into Doom by providing things such +as repl support, project root recognition, etc. It also provide the following +keybindings: -** Haskell packages -You'll need to install the following packages using ~stack~ or ~cabal~: - -+ (Dante users) =ghc-mod= - #+BEGIN_SRC sh - stack install ghc-mod - # or - cabal install ghc-mod - #+END_SRC -+ =hoogle= - #+BEGIN_SRC sh - cabal update - cabal install happy haskell-src-exts # ghc-mod/hoogle dependencies - cabal ghc-mod hoogle - # or - stack install ghc-mod - stack install hoogle - #+END_SRC - -And ensure the binaries for these packages are in your ~PATH~, e.g. - -#+BEGIN_SRC sh -# place this in your profile file, like ~/.bash_profile or ~/.zshenv -export PATH="~/.local/bin:$PATH" -#+END_SRC +| Keybinding | Description | +|-------------------+-----------------------------------------------| +| = b= | Build the current cabal project | +| = c= | Visit the =.cabal= file of the current buffer | +| = h= | Toggle visibility of the form at point | +| = H= | hides all top level functions | * Configuration -** Using the new-style cabal REPL -=haskell-mode= will typically detect what REPL to run based on your project -(e.g. stack, (old-style) cabal or ghc). If you want the new-style cabal REPL you -must set ~haskell-process-type~ manually: +After installing your preferred formatter, make sure to set +=lsp-haskell-formatting-provider= to it. -#+BEGIN_SRC emacs-lisp -(setq haskell-process-type 'cabal-new-repl) +Make sure to configure the lsp to use your perfered formatter, e.g.: +#+BEGIN_SRC elisp +;; ~/.doom.d/config.el +(after! + (setq lsp-haskell-formatting-provider "brittany")) #+END_SRC - -* Troubleshooting -+ Stack users: a ~dist/setup-config~ file in your project may cause [[https://github.com/DanielG/ghc-mod/wiki#known-issues-related-to-stack][ghc-mod to - not work]]. diff --git a/modules/lang/haskell/config.el b/modules/lang/haskell/config.el index a65ce74fb..e5ee3f493 100644 --- a/modules/lang/haskell/config.el +++ b/modules/lang/haskell/config.el @@ -43,10 +43,10 @@ "H" #'haskell-hide-toggle-all)) -;; -;;; Backends - -(cond ((featurep! +dante) (load! "+dante")) - ((or (featurep! +lsp) - (featurep! +ghcide)) - (load! "+lsp"))) +(use-package! lsp-haskell + :when (featurep! +lsp) + :after lsp-mode + :preface (add-hook 'haskell-mode-local-vars-hook #'lsp!) + :config + ;; Does some strange indentation if it pastes in the snippet + (setq-hook! 'haskell-mode-hook yas-indent-line 'fixed)) diff --git a/modules/lang/haskell/doctor.el b/modules/lang/haskell/doctor.el index 088490cf9..726d83ede 100644 --- a/modules/lang/haskell/doctor.el +++ b/modules/lang/haskell/doctor.el @@ -5,8 +5,22 @@ (featurep! :tools lsp)) "This module requires (:tools lsp)") -(when (featurep! +dante) - (unless (executable-find "cabal") - (warn! "Couldn't find cabal, haskell-mode may have issues")) - (unless (executable-find "hlint") - (warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode"))) +(unless (executable-find "cabal") + (warn! "Couldn't find cabal. haskell-mode may have issues.")) + +(unless (executable-find "hoogle") + (warn! "Couldn't find hoogle. Documentation searching will not work.")) + +(unless (or (featurep! +lsp) + (executable-find "hlint")) + (warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode. + Install it or enable +lsp.")) + +(when (and (featurep! :editor format) + (not (executable-find "brittany"))) + (warn! "Couldn't find brittany. Code formatting will not work. + Install it or enable +lsp.")) + +(when (and (featurep! +lsp) + (not (executable-find "haskell-language-server-wrapper"))) + (warn! "Couldn't find haskell-language-server.")) diff --git a/modules/lang/haskell/packages.el b/modules/lang/haskell/packages.el index ea48bca84..4829d5a6d 100644 --- a/modules/lang/haskell/packages.el +++ b/modules/lang/haskell/packages.el @@ -3,10 +3,6 @@ (package! haskell-mode :pin "98ba3922360199d5260d47f417f096730ad057c5") -(when (featurep! +dante) - (package! dante :pin "8741419333fb85ed2c1d71f5902688f5201b0a40") - (package! attrap :pin "a5bc695af27349ae6fe4541a581e6fd449d2a026")) -(when (or (and (featurep! +lsp) - (not (featurep! :tools lsp +eglot))) - (featurep! +ghcide)) +(when (and (featurep! +lsp) + (not (featurep! :tools lsp +eglot))) (package! lsp-haskell :pin "4e62cf897dd9e9fcef25c6e8e483490a07a5d439"))