From c732a292712d4bbee9f032b7de8834caacf3484d Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 19:56:02 +0200 Subject: [PATCH 01/20] Spell checking strings and comments --- doc/haskell-mode.texi | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 53d10fd68..b929e15f1 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -49,22 +49,22 @@ interpreter (e.g. GHCi). @end ifnottex @menu -* Introduction:: An introduction to Haskell Mode -* Getting Help and Reporting Bugs:: How to improve Haskell Mode -* Getting Started:: How to get started -* Editing Haskell Code:: How to edit code -* Unicode support:: How to use Unicode -* Indentation:: Notes about indentation -* Declaration scanning:: How to navigate in a source file -* Compilation:: How to compile -* Inferior Haskell interpreter:: How to interact with GHCi (1) -* Interactive Haskell:: How to interact with GHCi (2) -* Editing Cabal files:: Cabal support -* Changing REPL target:: Start REPL with selected target (i.e. test,bench,etc.) -* Using with flyspell-prog-mode:: Spell check comments and strings -* Concept index:: Index of Haskell Mode concepts -* Function index:: index of commands -* Variable index:: Index of options and types +* Introduction:: An introduction to Haskell Mode +* Getting Help and Reporting Bugs:: How to improve Haskell Mode +* Getting Started:: How to get started +* Editing Haskell Code:: How to edit code +* Unicode support:: How to use Unicode +* Indentation:: Notes about indentation +* Declaration scanning:: How to navigate in a source file +* Compilation:: How to compile +* Inferior Haskell interpreter:: How to interact with GHCi (1) +* Interactive Haskell:: How to interact with GHCi (2) +* Editing Cabal files:: Cabal support +* Changing REPL target:: Start REPL with selected target (i.e. test,bench,etc.) +* Spell checking strings and comments:: Using @code{flyspell-prog-mode} +* Concept index:: Index of Haskell Mode concepts +* Function index:: Index of commands +* Variable index:: Index of options and types @end menu @ifhtml @@ -877,7 +877,7 @@ Answer ``yes'' to restart the session and run your tests, benchmarks, executable TODO/WRITEME -@node Using with flyspell-prog-mode +@node Spell checking strings and comments @chapter Using with @code{flyspell-prog-mode} Strings and comments can be checked for spelling mistakes. There is a From 15711f3a78b4dd406678b28ae114cad269150884 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:04:15 +0200 Subject: [PATCH 02/20] Move browsing haddock from wiki --- doc/haskell-mode.texi | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index b929e15f1..144ea6b05 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -61,6 +61,7 @@ interpreter (e.g. GHCi). * Interactive Haskell:: How to interact with GHCi (2) * Editing Cabal files:: Cabal support * Changing REPL target:: Start REPL with selected target (i.e. test,bench,etc.) +* Browsing Haddocks:: Using @code{w3m} to browse documentation * Spell checking strings and comments:: Using @code{flyspell-prog-mode} * Concept index:: Index of Haskell Mode concepts * Function index:: Index of commands @@ -877,6 +878,103 @@ Answer ``yes'' to restart the session and run your tests, benchmarks, executable TODO/WRITEME +@node Browsing Haddocks +@chapter Browsing Haddocks using @code{w3m} + +An experimental feature is use of the w3m browser to browse Haddock docs +inside Emacs. + +@section Get w3m + +Most Linux distributions will have a package for the binary: + +@example +$ sudo apt-get install w3m +@end example + +Now grab @code{w3m.el} from: + +@itemize +@item @url{http://emacs-w3m.namazu.org/} +@item @kbd{M-x} @code{package-install} @kbd{RET} @code{w3m} @kbd{RET} +@end itemize + +Confirm installation by trying @kbd{M-x} @code{w3m-browse-url} @kbd{RET} +@code{haskell.org} @kbd{RET}. + +If this works, you're good to go. + +@section Configure w3m + +Now that you have w3m, you probably want to configure it to be more of a +passive viewer than a full-fledged browser. For example: + +@lisp +(setq w3m-mode-map (make-sparse-keymap)) + +(define-key w3m-mode-map (kbd "RET") 'w3m-view-this-url) +(define-key w3m-mode-map (kbd "q") 'bury-buffer) +(define-key w3m-mode-map (kbd "") 'w3m-maybe-url) +(define-key w3m-mode-map [f5] 'w3m-reload-this-page) +(define-key w3m-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock) +(define-key w3m-mode-map (kbd "M-") 'w3m-view-previous-page) +(define-key w3m-mode-map (kbd "M-") 'w3m-view-next-page) +(define-key w3m-mode-map (kbd "M-.") 'w3m-haddock-find-tag) + +(defun w3m-maybe-url () + (interactive) + (if (or (equal '(w3m-anchor) (get-text-property (point) 'face)) + (equal '(w3m-arrived-anchor) (get-text-property (point) 'face))) + (w3m-view-this-url))) +@end lisp + +@section Import w3m-haddock + +It's not enabled by default in haskell-mode at present, so you need to +import it manually: + +@lisp +(require 'w3m-haddock) +@end lisp + +@section Add a hook for w3m + +In order to make haddock pages a little more palatable (and add syntax +highlighting to source view), you can add this hook: + +@lisp +(add-hook 'w3m-display-hook 'w3m-haddock-display) +@end lisp + +It's a little rough around the edges, but it's a start. + +@section Configure your package locations + +By default, the package locations is set to: + +@lisp +(defcustom haskell-w3m-haddock-dirs + '("~/.cabal/share/doc/")) +@end lisp + +If you are using an hsenv or a custom package directory, you should +configure this variable with M-x customize-variable or by writing the +custom-set-variables code for it. + +@section Finally + +You did all that! Now you're ready to bind a useful key: + +@lisp +(define-key haskell-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock) +@end lisp + +Now when you press @kbd{C-c} @kbd{C-d} it will prompt for a package to +browse to. + +This feature will be improved gradually as time goes on. + + @node Spell checking strings and comments @chapter Using with @code{flyspell-prog-mode} From 707be6a9455263e34e6985c116020a2aa74b2f1a Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:28:04 +0200 Subject: [PATCH 03/20] Move aligning code from wiki --- doc/haskell-mode.texi | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 144ea6b05..d6328502d 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -63,6 +63,7 @@ interpreter (e.g. GHCi). * Changing REPL target:: Start REPL with selected target (i.e. test,bench,etc.) * Browsing Haddocks:: Using @code{w3m} to browse documentation * Spell checking strings and comments:: Using @code{flyspell-prog-mode} +* Aligning code:: Aligning code using @code{align-regexp} * Concept index:: Index of Haskell Mode concepts * Function index:: Index of commands * Variable index:: Index of options and types @@ -1010,6 +1011,59 @@ To enable spell checking of strings and comments add this line to your @code{(add-hook 'haskell-mode-hook 'flyspell-prog-mode)} +@node Aligning code +@chapter Aligning code + +Select a region you want to align text within, @kbd{M-x} +@code{align-regexp}, and type a regexp representing the alignment +delimiter. + +For example, I often line up my Haddock comments: + +@example +f :: a -- ^ does a + -> Foo b -- ^ and b + -> c -- ^ to c +@end example + +Select the region, and let the regexp be @samp{--}: + +@example +f :: a -- ^ does a + -> Foo b -- ^ and b + -> c -- ^ to c +@end example + +Of course, this works for just about anything. Personally, I've globally +bound it to @kbd{C-x a r}: + +@lisp +(global-set-key (kbd "C-x a r") 'align-regexp) +@end lisp + +Note that you can also just use the rules below for telling the aligner +about Haskell. Once you evaluate this, you can just use @kbd{M-x} +@code{align}, which I like to bind to @kbd{M-[}. + +@lisp +(add-to-list 'align-rules-list + '(haskell-types + (regexp . "\\(\\s-+\\)\\(::\\|∷\\)\\s-+") + (modes quote (haskell-mode literate-haskell-mode)))) +(add-to-list 'align-rules-list + '(haskell-assignment + (regexp . "\\(\\s-+\\)=\\s-+") + (modes quote (haskell-mode literate-haskell-mode)))) +(add-to-list 'align-rules-list + '(haskell-arrows + (regexp . "\\(\\s-+\\)\\(->\\|→\\)\\s-+") + (modes quote (haskell-mode literate-haskell-mode)))) +(add-to-list 'align-rules-list + '(haskell-left-arrows + (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+") + (modes quote (haskell-mode literate-haskell-mode)))) +@end lisp + @node Concept index @unnumbered Concept index From 716b7151dc74aec86e294f7f0683e9deb2c940f8 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:42:12 +0200 Subject: [PATCH 04/20] Move indentation info from wiki --- doc/haskell-mode.texi | 51 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index d6328502d..5c3dc1995 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -427,40 +427,45 @@ via @kbd{M-x customize-variable}. @cindex layout rule @cindex off-side rule -For general information about indentation support in GNU Emacs, -@pxref{Indentation,,,emacs}. - In Haskell, code indentation has semantic meaning as it defines the -block structure@footnote{Haskell also supports braces and semicolons +block structure. Haskell also supports braces and semicolons notation for conveying the block structure. However, most Haskell -programs written by humans use indentation for block structuring.}. +programs written by humans use indentation for block structuring. + +Haskell Mode ships with two indentation modes: + +@itemize +@item @code{haskell-indentation-mode} (default). + +This is a semi-intelligent indentation mode doing a decent job at +recognizing Haskell syntactical constructs. It is based on a recursive +descent Haskell parser. @kbd{TAB} selects the next potential indentation +position, @kbd{S-TAB} selects the previous one. If a block is selected +you can use @kbd{TAB} to indent the block more and @kbd{S-TAB} to indent +the block less. -As GNU Emacs' default indentation function -(i.e. @code{indent-relative}) is not designed for use with Haskell's -layout rule, Haskell mode includes indentation rules adapted to -Haskell. @code{haskell-indentation-mode} binds @key{TAB} to cycle -through possible indentation points based on some clever heuristics. -@key{SHIFT-TAB} cycles in the reverse direction, and @key{RET} moves -to a new line and indents to the first possible indentation level. +@item @code{haskell-indent-mode} (optional). -@section haskell-indent-mode +This is a semi-intelligent indentation mode doing a decent job at +recognizing Haskell syntactical constructs. It is based on a decision +table. Sadly it is no longer developed and does not recognize newer +Haskell syntax. @kbd{TAB} cycles through all available indentation +positions. -If you want to use the obsolete @code{haskell-indent-mode}, the -recommended way is to load it in @code{haskell-mode-hook}. This can be -done either by using @kbd{M-x customize-variable @key{RET} -haskell-mode-hook} which provides a convenient user interface or by -adding the following line to your @file{.emacs} file: +To use @code{haskell-indent-mode}, add this to your @file{~/.emacs} +file: @lisp -(add-hook 'haskell-mode-hook 'haskell-indent-mode) +(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) @end lisp -This will turn off @code{haskell-indentation-mode}. +Note that @code{turn-on-haskell-indent} will disable +@code{haskell-indentation-mode}. -@section Interactive Block Indentation +@end itemize -@code{haskell-indentation} can move whole blocks to the left or to the -right. Just mark a block and then use @key{TAB} or @key{S-TAB}. +For general information about indentation support in GNU Emacs, +@pxref{Indentation,,,emacs}. @section Rectangle Commands From 601ac9e8d4fe8b56404446caffcce1b506251661 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:47:52 +0200 Subject: [PATCH 05/20] Move external indentation from wiki --- doc/haskell-mode.texi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 5c3dc1995..1e3e5d6ac 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -55,6 +55,7 @@ interpreter (e.g. GHCi). * Editing Haskell Code:: How to edit code * Unicode support:: How to use Unicode * Indentation:: Notes about indentation +* External indentation:: Other ways to indent code * Declaration scanning:: How to navigate in a source file * Compilation:: How to compile * Inferior Haskell interpreter:: How to interact with GHCi (1) @@ -486,6 +487,23 @@ selection mode (without redefining @kbd{C-x},@kbd{C-c},@kbd{C-v}, and @kbd{C-z}) by calling @kbd{M-x cua-selection-mode} (or adding @code{(cua-selection-mode nil)} to your @code{haskell-mode-hook}). +@node External indentation +@chapter Other ways to indent code + +@section Indentation with tabs, not spaces + +Some projects require indenting code with tabs and forbid indenting it +with spaces. For hacking on such projects, check out +@uref{https://spwhitton.name/tech/code/haskell-tab-indent,haskell-tab-indent-mode}. + +@section Structured indentation + +Another alternative is to install +@uref{https://github.com/chrisdone/structured-haskell-mode,structured-haskell-mode}. +which indents code by parsing the code with a full Haskell parser and +deciding where to indent based on that. + + @node Declaration scanning @chapter Declaration scannning From e82ef448bee3178b0251e52246c8055ff28910d3 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:52:32 +0200 Subject: [PATCH 06/20] Move Rectangular commands from wiki --- doc/haskell-mode.texi | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 1e3e5d6ac..5e796881b 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -65,6 +65,7 @@ interpreter (e.g. GHCi). * Browsing Haddocks:: Using @code{w3m} to browse documentation * Spell checking strings and comments:: Using @code{flyspell-prog-mode} * Aligning code:: Aligning code using @code{align-regexp} +* Rectangular commands:: * Concept index:: Index of Haskell Mode concepts * Function index:: Index of commands * Variable index:: Index of options and types @@ -1087,6 +1088,51 @@ about Haskell. Once you evaluate this, you can just use @kbd{M-x} (modes quote (haskell-mode literate-haskell-mode)))) @end lisp +@node Rectangular commands +@chapter Using rectangular region commands + +Emacs has a set of commands which operate on the region as if it were +rectangular. This turns out to be extremely useful when dealing with +whitespace sensitive languages. + +@itemize +@item @kbd{C-x r o} is "Open Rectangle". + +It will shift any text within the rectangle to the right side. Also see: + +@item @kbd{C-x r t} is "String Rectangle". + +It will replace any text within the rectangle with the given string on +all the lines in the region. If comment-region didn't already exist, you +could use this instead, for example. + +@item @kbd{C-x r d} is "Delete Rectangle". + +It will delete the contents of the rectangle and move anything on the +right over. + +@item @kbd{C-x r r} is "Copy Rectangle to Register". + +It will prompt you for a register number so it can save it for later. + +@item @kbd{C-x r g} is "Insert register". + +This will insert the contents of the given register, overwriting +whatever happens to be within the target rectangle. (So make room) + +@item @kbd{C-x r k} is "Kill rectangle". + +Delete rectangle and save contents for: + +@item @kbd{C-x r y} is "Yank rectangle". + +This will insert the contents of the last killed rectangle. +@end itemize + +As with all Emacs modifier combos, you can type @kbd{C-x r C-h} to find +out what keys are bound beginning with the @kbd{C-x r} prefix. + + @node Concept index @unnumbered Concept index From dccb5fc874a0eece38aae2f397cf7b69ae222a3f Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 20:58:53 +0200 Subject: [PATCH 07/20] Move autoformatting from wiki --- doc/haskell-mode.texi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 5e796881b..700da3493 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -56,6 +56,7 @@ interpreter (e.g. GHCi). * Unicode support:: How to use Unicode * Indentation:: Notes about indentation * External indentation:: Other ways to indent code +* Autoformating:: Using external formatters * Declaration scanning:: How to navigate in a source file * Compilation:: How to compile * Inferior Haskell interpreter:: How to interact with GHCi (1) @@ -504,6 +505,28 @@ Another alternative is to install which indents code by parsing the code with a full Haskell parser and deciding where to indent based on that. +@node Autoformating +@chapter Using external formatters + +You can enable @uref{https://github.com/jaspervdj/stylish-haskell,stylish-haskell} by +installing it: + +@example +$ cabal install stylish-haskell +@end example + +And by enabling it with a customization + +@lisp +(custom-set-variables + '(haskell-stylish-on-save t)) +@end lisp + +Now when you run @code{save-buffer} (or @kbd{C-x C-s}) the module will +be automatically formatted. + +Alternatively, you can run the function directly on demand with +@kbd{M-x} @code{haskell-mode-stylish-buffer}. @node Declaration scanning @chapter Declaration scannning From f5124acf327579f2e8a004dc67d05c741f070d9e Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 21:01:19 +0200 Subject: [PATCH 08/20] Move Module templates from wiki --- doc/haskell-mode.texi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 700da3493..c477108ad 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -57,6 +57,7 @@ interpreter (e.g. GHCi). * Indentation:: Notes about indentation * External indentation:: Other ways to indent code * Autoformating:: Using external formatters +* Module templates:: Module templates * Declaration scanning:: How to navigate in a source file * Compilation:: How to compile * Inferior Haskell interpreter:: How to interact with GHCi (1) @@ -528,6 +529,25 @@ be automatically formatted. Alternatively, you can run the function directly on demand with @kbd{M-x} @code{haskell-mode-stylish-buffer}. +@node Module templates +@chapter Module templates + +To enable auto-insertion of module templates, enable: + +@lisp +(add-hook 'haskell-mode-hook 'haskell-auto-insert-module-template) +@end lisp + +When you open a file called @file{Foo.hs}, it will auto-insert + +@example +-- | + +module Foo where +@end example + +And put your cursor in the comment section. + @node Declaration scanning @chapter Declaration scannning From 39458072be587614d703ae1918ede19f5f46e5d0 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 21:19:39 +0200 Subject: [PATCH 09/20] Move History from wiki --- doc/haskell-mode.texi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index c477108ad..30511939a 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -99,6 +99,31 @@ interaction with inferior GHCi/Hugs instance, and scanning declarations and placing them in a menu. @end itemize +@section Naming + +The name haskell-mode refers to the whole collection of modules in this +package. There is specifically a file `haskell-mode.el` which defines a +major mode called `haskell-mode`. Generally, in this documentation they +will be distinguished by normal font (haskell-mode) and code font +(`haskell-mode`). + +@section History + +@code{haskell-mode} has a long history. It goes all the way back +to 1992. Since then, it has received many contributions in many +forms. Some design choices that remain in haskell-mode today are +historical. Some modules are outdated or no longer used, or are used +by a few people. + +Historically there hasn't been a single individual or set of +individuals directing the package's architecture for a long period of +time, rather, patches and new modules were accepted in liberally and +we are left with a box full of interesting toys that may or may not +work. + +As of 2016 Haskell Mode is coordinated using Github at +@uref{https://github.com/haskell/haskell-mode}. + @node Getting Help and Reporting Bugs @chapter Getting Help and Reporting Bugs From 5a66fa69e05d76a6aca7ec0fc4f72e943fa3b72f Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 21:23:08 +0200 Subject: [PATCH 10/20] Move Getting help to the very end --- doc/haskell-mode.texi | 67 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 30511939a..2e72a7408 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -50,7 +50,6 @@ interpreter (e.g. GHCi). @menu * Introduction:: An introduction to Haskell Mode -* Getting Help and Reporting Bugs:: How to improve Haskell Mode * Getting Started:: How to get started * Editing Haskell Code:: How to edit code * Unicode support:: How to use Unicode @@ -68,6 +67,7 @@ interpreter (e.g. GHCi). * Spell checking strings and comments:: Using @code{flyspell-prog-mode} * Aligning code:: Aligning code using @code{align-regexp} * Rectangular commands:: +* Getting Help and Reporting Bugs:: How to improve Haskell Mode * Concept index:: Index of Haskell Mode concepts * Function index:: Index of commands * Variable index:: Index of options and types @@ -124,38 +124,6 @@ work. As of 2016 Haskell Mode is coordinated using Github at @uref{https://github.com/haskell/haskell-mode}. -@node Getting Help and Reporting Bugs -@chapter Getting Help and Reporting Bugs - -This Info manual is work in progress and incomplete. However, you can -find more information at these locations in the meantime: - -@itemize -@item -@uref{https://github.com/haskell/haskell-mode,Haskell Mode's GitHub Home} -@item -@uref{http://www.haskell.org/haskellwiki/Haskell_mode_for_Emacs,Haskell Wiki Emacs Page} -@end itemize - -If you have any questions or like to discuss something regarding Haskell -Mode, please consider sending an email to the -@uref{http://projects.haskell.org/cgi-bin/mailman/listinfo/haskellmode-emacs, -Haskellmode-emacs mailing list}. The mailing list is also available on -@uref{http://gmane.org/, Gmane} via the -@uref{http://dir.gmane.org/gmane.comp.lang.haskell.emacs, -gmane.comp.lang.haskell.emacs} newsgroup. - -If you have discovered a bug or wish to request a new feature, you can -@uref{https://github.com/haskell/haskell-mode/issues/new, file a new -issue} with Haskell Mode's issue tracker. When filing a bug, please -state your currently used software version (@kbd{M-x} -@code{haskell-version}, @kbd{M-x} @code{version}) and what steps to -perform in order to reproduce the bug you're experiencing. Finally, if -you happen to be proficient in @ref{Top,Emacs Lisp,,elisp} you are -welcome to submit patches via -@uref{https://help.github.com/articles/using-pull-requests, GitHub -Pull Requests}. - @node Getting Started @chapter Getting Started @@ -1200,6 +1168,39 @@ This will insert the contents of the last killed rectangle. As with all Emacs modifier combos, you can type @kbd{C-x r C-h} to find out what keys are bound beginning with the @kbd{C-x r} prefix. +@node Getting Help and Reporting Bugs +@chapter Getting Help and Reporting Bugs + +This Info manual is work in progress and incomplete. However, you can +find more information at these locations in the meantime: + +@itemize +@item +@uref{https://github.com/haskell/haskell-mode,Haskell Mode's GitHub Home} +@item +@uref{http://www.haskell.org/haskellwiki/Haskell_mode_for_Emacs,Haskell Wiki Emacs Page} +@end itemize + +If you have any questions or like to discuss something regarding Haskell +Mode, please consider sending an email to the +@uref{http://projects.haskell.org/cgi-bin/mailman/listinfo/haskellmode-emacs, +Haskellmode-emacs mailing list}. The mailing list is also available on +@uref{http://gmane.org/, Gmane} via the +@uref{http://dir.gmane.org/gmane.comp.lang.haskell.emacs, +gmane.comp.lang.haskell.emacs} newsgroup. + +If you have discovered a bug or wish to request a new feature, you can +@uref{https://github.com/haskell/haskell-mode/issues/new, file a new +issue} with Haskell Mode's issue tracker. When filing a bug, please +state your currently used software version (@kbd{M-x} +@code{haskell-version}, @kbd{M-x} @code{version}) and what steps to +perform in order to reproduce the bug you're experiencing. Finally, if +you happen to be proficient in @ref{Top,Emacs Lisp,,elisp} you are +welcome to submit patches via +@uref{https://help.github.com/articles/using-pull-requests, GitHub +Pull Requests}. + + @node Concept index @unnumbered Concept index From a2ae66a815733d323a44827521d898231e597abf Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 22:07:01 +0200 Subject: [PATCH 11/20] Expand installation chapter --- doc/haskell-mode.texi | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 2e72a7408..65926b561 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -50,7 +50,7 @@ interpreter (e.g. GHCi). @menu * Introduction:: An introduction to Haskell Mode -* Getting Started:: How to get started +* Installation:: How to get started * Editing Haskell Code:: How to edit code * Unicode support:: How to use Unicode * Indentation:: Notes about indentation @@ -124,12 +124,31 @@ work. As of 2016 Haskell Mode is coordinated using Github at @uref{https://github.com/haskell/haskell-mode}. -@node Getting Started -@chapter Getting Started +@node Installation +@chapter Installation -@section Quick Installation +Haskell Mode is distributed as a package in +@uref{https://melpa.org,MELPA repository}. To use MELPA as Emacs package +archive do the following: -Make sure you have this in your @uref{http://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html, init file} (usually `~/.emacs`). If you already have @code{custom-set-variables}, merge its contents: +@enumerate +@item +Customize @code{package-archives} using @kbd{M-x} @code{customize-option} @kbd{RET} @code{package-archives} @kbd{RET}. +@item +Use @kbd{INS} to add new archive, use @code{Archive name: melpa-stable} +and @code{URL or directory name: http://stable.melpa.org/packages/}. +@item +Fetch new packages using @kbd{M-x} @code{package-refresh-contents}. +@item +Install @code{haskell-mode} using @kbd{M-x} @code{package-install} +@kbd{RET} @code{haskell-mode} @kbd{RET}. + +@end enumerate + +Voila! @code{haskell-mode} is installed! You should be able to edit Haskell +source code in color now. + +The above steps should result in the following snippet in your @file{.emacs}: @lisp (require 'package) @@ -144,16 +163,6 @@ Make sure you have this in your @uref{http://www.gnu.org/software/emacs/manual/h ("melpa-stable" . "http://stable.melpa.org/packages/"))))) @end lisp -Then run Emacs, and evaluate: - - @kbd{M-x} @code{package-refresh-contents} - -and then follow by - - @kbd{M-x} @code{package-install} @kbd{RET} @code{haskell-mode} - -Voila! @code{haskell-mode} is installed! You should be able to edit -Haskell source code in color now. @section Installation - more information From 33b914fa3131fe0daf0e434b87604c411d2be083 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:15:44 +0200 Subject: [PATCH 12/20] Move Haskell-mode bindings from wiki --- doc/haskell-mode.texi | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 65926b561..7dbaed50c 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -899,6 +899,116 @@ strings specifying (further) command-line arguments. @vindex haskell-process-args-cabal-repl @vindex haskell-process-args-stack-ghci +@section Haskell Interactive Mode Setup + +The most straight-forward way to get setup with Interactive Mode is to +bind the right keybindings and set some customizations. This page +contains a good base setup. + +To enable the minor mode which activates keybindings associated with interactive mode, use: + +@lisp +(require 'haskell-interactive-mode) +(require 'haskell-process) +(add-hook 'haskell-mode-hook 'interactive-haskell-mode) +@end lisp + +@subsection Customizations + +This enables some handy and benign features. + +@lisp +(custom-set-variables + '(haskell-process-suggest-remove-import-lines t) + '(haskell-process-auto-import-loaded-modules t) + '(haskell-process-log t)) +@end lisp + + +@subsection Haskell-mode bindings + +This gives the basic ways to start a session. In a Haskell buffer: + +@itemize +@item +Run @kbd{C-`} to make a REPL open, this will create a +session, start GHCi, and open the REPL. +@item +Or: run @kbd{C-c C-l} to load the file. This will first try to start a +session as the previous command does. +@item +Or: run any command which requires a running session. It will always +prompt to create one if there isn't one already for the current project. +@end itemize + +@lisp +(define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-or-reload) +(define-key haskell-mode-map (kbd "C-`") 'haskell-interactive-bring) +(define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type) +(define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info) +(define-key haskell-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build) +(define-key haskell-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear) +(define-key haskell-mode-map (kbd "C-c c") 'haskell-process-cabal) +@end lisp + + +@subsection Cabal-mode bindings + +The below commands pretty much match the ones above, but are handy to +have in cabal-mode, too: + +@lisp +(define-key haskell-cabal-mode-map (kbd "C-`") 'haskell-interactive-bring) +(define-key haskell-cabal-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear) +(define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build) +(define-key haskell-cabal-mode-map (kbd "C-c c") 'haskell-process-cabal) +@end lisp + +@subsection GHCi process type + +By default @code{haskell-process-type} is set to @code{auto}. It is +smart enough to pick the right type based on your project structure and +installed tools, but in case something goes funky or you want to +explicitly set the process type and ignore the inferred type, you can +customize this setting by running @kbd{M-x} @code{customize-variable} +@kbd{RET} @code{haskell-process-type} @kbd{RET}, or by setting the code: + +@lisp +(custom-set-variables + '(haskell-process-type 'cabal-repl)) +@end lisp + +Here is a list of available process types: + +@itemize +@item ghci +@item cabal-repl +@item cabal-dev +@item cabal-ghci +@item stack-ghci +@end itemize + +Please, check the documentation for @code{haskell-process-type} to see how +the real type is guessed, when it's set to @code{auto}. + +@subsection Troubleshooting + +Launching your GHCi process can fail when you're first getting setup, +depending on the type you choose. If it does fail to launch, switch to +the buffer @code{*haskell-process-log*} and see what's up. The buffer +contains a log of incoming/outgoing messages to the GHCi process. + +@subsection All done! + +You're all done and ready to go! But wait! + +There're a bunch more features to this mode and for which you might +want to add configurations and keybindings. So it is suggested that +once you've setup and played with the above, you continue reading what +other features are available in the [[Haskell Interactive Mode]] +documentation. + + @node Editing Cabal files @chapter Editing Cabal files From 54f4a026c13feee512e45664b8988bfb9c015cbf Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:19:50 +0200 Subject: [PATCH 13/20] Haskell Interactive Mode Tags Using GHCi --- doc/haskell-mode.texi | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 7dbaed50c..7c6da7fc6 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1008,6 +1008,91 @@ once you've setup and played with the above, you continue reading what other features are available in the [[Haskell Interactive Mode]] documentation. +@section Haskell Interactive Mode Tags Using GHCi + +You can bind the following to use GHCi to find definitions of things: + +@lisp +(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def) +@end lisp + +The one problem with this approach is that if your code doesn't compile, +GHCi doesn't give any location info. So you need to make sure your code +compiles and the modules you want to jump to are loaded byte-compiled. + +**Heads up**: I think that when you restart GHCi you lose location +information, even if you have the .o and .hi files lying around. I'm not +sure. But sometimes `:i foo` will give `foo is defined in Bar` rather +than `foo is defined in /foo/Bar.hs:123:23`. + +Alternatively, you can use tags generation, which doesn't require a +valid compile. Keep reading for that. + +@subsection Tags Setup + +Make sure to install hasktags. + +@example + $ cabal install hasktags +@end example + +Then add the customization variable to enable tags generation on save: + +@lisp +(custom-set-variables + '(haskell-tags-on-save t)) +@end lisp + +And make sure `hasktags` is in your [[PATH]] which Emacs can see. + +@subsection Generating tags + +Now, every time you run `save-buffer` (`C-x C-s`), there is a hook +that will run and generate Emacs +[tags](https://www.gnu.org/software/emacs/manual/html_node/emacs/Tags.html) +for the whole project directory. The resulting file will be called +`TAGS`. + +**WARNING**: You should be careful that your project root isn't your +home directory or something, otherwise it will traverse all the way +down and take an impossibly long time. + +@subsection Jumping to tags + +Bind the following keybinding: + +@lisp +(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-tag-find) +@end lisp + +To jump to the location of the top-level identifier at point, run + +@example + M-x haskell-mode-tag-find +@end example + +or @kbd{M-.}. + +@subsection Hybrid: GHCi and fallback to tags + +To use GHCi first and then if that fails to fallback to tags for jumping, use: + +@lisp +(define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def-or-tag) +@end lisp + +@subsection Troubleshooting tags + +Sometimes a `TAGS` file is deleted (by you or some other +process). Emacs will complain that it doesn't exist anymore. To +resolve this simply run the following: + +@example + M-x tags-reset-tags-tables +@end example + +And you're done! + @node Editing Cabal files @chapter Editing Cabal files From e3c6a0d8e4d3003b838da2d56cf2bd655a7964b7 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:23:23 +0200 Subject: [PATCH 14/20] Move Sessions from wiki to manual --- doc/haskell-mode.texi | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 7c6da7fc6..72d0e0a0f 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1093,6 +1093,83 @@ resolve this simply run the following: And you're done! +@section Sessions + +All commands in [[Haskell Interactive Mode]] work within a +session. Consider it like a “project” or a “solution” in popular +IDEs. It tracks the root of your project and an associated process and +REPL. + +Make sure you have [[setup your keybindings|Haskell Interactive Mode Setup]]. + +@subsection Start a session + +To start a session run the following steps (assumes you've already +[[setup your keybindings|Haskell Interactive Mode Setup]]). + +* Open some Cabal or Haskell file. +* Run C-` to make a REPL open, this will create a + session, start GHCi, and open the REPL. +* Or: run `C-c C-l` to load the file. This will first try to start a + session as the previous command does. +* Or: run any command which requires a running session. It will always + prompt to create one if there isn't one already for the current project. + +It will prompt for a Cabal directory and a current directory. It +figures out where the cabal directory is and defaults for the current +directory, so you should be able to just hit RET twice. + +@subsection Switch a session + +Sometimes a particular file is used in two different +sessions/projects. You can run + +@example + M-x haskell-session-change +@end example + +If it prompts you to make a new session, tell it no (that's a +bug). It will ask you to choose from a list of sessions. + +@subsection Killing a session + +To kill a session you can run + +@example + M-x haskell-session-kill +@end example + +Which will prompt to kill all associated buffers, too. Hit `n` to +retain them. + +Alternatively, you can switch to the REPL and just kill the buffer +normally with @kbd{C-x k RET}. It will prompt + +@example + Kill the whole session (y or n)? +@end example + +You can choose @kbd{y} to kill the session itself, or @kbd{n} to just +kill the REPL buffer. You can bring it back with @kbd{M-x} +@code{haskell-interactive-bring}. + +@subsection Menu + +To see a list of all sessions you have open with some simple +statistics about memory usage, etc. run + +@example + M-x haskell-menu +@end example + +For example: + +@example + foo 14648 08:21:42 214MB /path/to/fpco/foo/ /path/to/fpco/foo/ ghci + bar 29119 00:22:03 130MB /path/to/bar/ /path/to/bar/ ghci + mu 22575 08:48:20 73MB /path/to/fpco/mu/ /path/to/fpco/mu/ ghci +@end example + @node Editing Cabal files @chapter Editing Cabal files From 147bcc4480e64ab13ad875a03a521ce7fd3f2c96 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:32:00 +0200 Subject: [PATCH 15/20] Move Compiling from wiki to manual --- doc/haskell-mode.texi | 166 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 72d0e0a0f..a240eb197 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1171,6 +1171,172 @@ For example: @end example +@section Compiling + +Once a [[session has been started|Haskell Interactive Mode Sessions]], +there are a bunch of ways to compile Haskell modules. This page covers +a few of them. + +@subsection Load into GHCi + +To compile and load a Haskell module into GHCi, run the following + +@example + M-x haskell-process-load +@end example + +Or @kbd{C-c C-l}. You'll see any compile errors in the REPL window. + +@subsection Build the Cabal project + +To compile the whole Cabal project, run the following + +@example + M-x haskell-process-cabal-build +@end example + +Or @kbd{C-c C-c}. You'll see any compile errors in the REPL window. + +@subsection Reloading modules + +To reload the current module, even when you're in other modules, you can +run @kbd{C-u M-x} @code{haskell-process-load-or-reload} or @kbd{C-u C-c +C-l}. It will now reload that module whenever you run @kbd{C-c C-l} in +the future from whatever module you're in. To disable this mode, just +run @kbd{C-u C-c C-l} again. + +@subsection Jumping to compile errors + +You can use the standard compile error navigation function: + +* @kbd{C-x `} — jump to the next error. + +Or you can move your cursor to an error in the REPL and hit `RET` to +jump to it. + +@subsection Auto-removing imports + +If the customization variable +`haskell-process-suggest-remove-import-lines` is enabled. + +@lisp +(custom-set-variables + '(haskell-process-suggest-remove-import-lines t)) +@end lisp + +Building and loading modules which output warnings like, + +@example + Warning: The import of `Control.Monad' is redundant + except perhaps to import instances from `Control.Monad' + To import instances alone, use: import Control.Monad() +@end example + +will prompt the user with + +@example +> The import line `Control.Monad' is redundant. Remove? (y, n, c: comment out) +@end example + +If you answer + + * `y`: it will delete the import, but leave the empty line + remaining (this avoids messing with line positions in subsequent + error messages). + * `n`: it will leave the import. + * `c`: it will comment out the import (this is handy for when you + just want to temporarily hide an import). + +@subsection Auto-adding of modules to import + +Enable the customization variable +@code{haskell-process-suggest-hoogle-imports}. + +@lisp +(custom-set-variables + '(haskell-process-suggest-hoogle-imports t)) +@end lisp + +Whenever GHC says something is not in scope, it will hoogle that +symbol. If there are results, it will prompt to add one of the modules +from Hoogle's results. + +You need to make sure you've generated your Hoogle database properly. + +@subsection Auto-adding of extensions + +It you use an extension which is not enabled, GHC will often inform +you. For example, if you write: + +@example +newtype X a = X (IO a) + deriving (Monad) +@end example + + +Then you'll see a message like: + +@example + x.hs:13:13: Can't make a derived instance of `Monad X': … + `Monad' is not a derivable class + Try -XGeneralizedNewtypeDeriving for GHC's newtype-deriving extension + In the newtype declaration for `X' +@end example + +This @code{-XFoo} pattern will be picked up and you will be prompted: + +@example +> Add `@{-# LANGUAGE GeneralizedNewtypeDeriving #-@}` to the top of the +> file? (y or n) +@end example + +If you answer `y`, it will temporarily jump to the buffer and it to +the top of the file. + +@subsection Orphan instances + +If GHC complains about orphan instances, you usually are doing it +intentionally, so it prompts to add @code{-fno-warn-orphans} to the top of +the file with an @kbd{OPTIONS} pragma. + +@subsection Auto-adding of dependencies + +When doing a build, you will sometimes get a message from GHC like: + +@example + src/ACE/Tokenizer.hs:11:18: Could not find module `Data.Attoparsec.Text' … + It is a member of the hidden package `attoparsec-0.11.1.0'. +@end example + +This message contains all the necessary information to add this to +your .cabal file, so you will be prompted to add it to your .cabal +file: + +@example + Add `attoparsec' to ace.cabal? (y or n) y +@end example + +If you hit `y`, it will prompt with this: + +@example + attoparsec >= 0.11.1.0 +@end example + +Which you can edit (e.g. do some PVP decision or remove constraints +entirely), and then it will open up your .cabal file and go through +each section: + +@example + Add to library? (y or n) y +@end example + +This will add it to the top of the @code{build-depends} field in your +library section. If you have any executables, it will go through each +of those, prompting, too. + +Now you can rebuild with @kbd{C-c C-c} again. + + @node Editing Cabal files @chapter Editing Cabal files From e88f3fb92974e64c9d6c061775f6361cc4a6c66b Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:38:55 +0200 Subject: [PATCH 16/20] Haskell Interactive Mode REPL --- doc/haskell-mode.texi | 223 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index a240eb197..268e6a294 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1336,6 +1336,229 @@ of those, prompting, too. Now you can rebuild with @kbd{C-c C-c} again. +@section Haskell Interactive Mode REPL + +When GHCi has been launched, it works on a read-eval-print basis. So +you will be presented with the prompt: + +@example + The lambdas must flow. + Changed directory: /path/to/your/project/ + λ> +@end example + +@subsection Bringing the REPL + +If you don't know where the REPL buffer is, you can always bring it +with: + +@example + M-x haskell-interactive-bring +@end example + +Or C-`, if you used the bindings in +[[the setup|Haskell Interactive Mode Setup]]. + +@subsection Evaluating expressions + +To evaluate expressions, simply type one out and hit `RET`. + +@example + λ> 123 + 123 +@end example + +@subsection Type of expressions + +You can use normal `:t` which is part of GHCi to get the type of +something: + +@example + λ> :t id + id :: a -> a +@end example + +But you can also just write out the value directly, + +@example + λ> id + id :: a -> a +@end example + +and because there's no @code{Show} instance for @code{(a -> a)}. This would +normally yield a compile error: + +@example + No instance for (Show (a0 -> a0)) + arising from a use of `print' + Possible fix: add an instance declaration for (Show (a0 -> a0)) + In a stmt of an interactive GHCi command: print it +@end example + +It will run `:t id` in the background and print out the result. The +same is true for ambiguous things: + +@example + λ> :t read "a" + read "a" :: Read a => a +@end example + +Because this would normally be an ambiguous constraint: + +@example + Ambiguous type variable `a0' in the constraint: + (Read a0) arising from a use of `read' + Probable fix: add a type signature that fixes these type variable(s) + In the expression: read \"a\" + In an equation for `it': it = read \"a\" +@end example + +Which is less useful than just printing the type out. + +You can disable this behaviour by disabling the customization option: + +@lisp +(custom-set-variables + '(haskell-interactive-types-for-show-ambiguous nil)) +@end lisp + +@subsection Printing mode + +You can choose between printing modes used for the results of +evaluating expressions. To do that, configure the variable +@code{haskell-interactive-mode-eval-mode}. Example: + +@lisp +(setq haskell-interactive-mode-eval-mode 'haskell-mode) +@end lisp + + +A handy function you can use is: + +@lisp +(defun haskell-interactive-toggle-print-mode () + (interactive) + (setq haskell-interactive-mode-eval-mode + (intern + (ido-completing-read "Eval result mode: " + '("fundamental-mode" + "haskell-mode" + "espresso-mode" + "ghc-core-mode" + "org-mode"))))) +@end lisp + +(Add whichever modes you want to use.) + +And then run + +@example + M-x haskell-interactive-toggle-print-mode +@end example + +Or @kbd{C-c C-v}: + +@lisp +(define-key haskell-interactive-mode-map (kbd "C-c C-v") 'haskell-interactive-toggle-print-mode) +@end lisp + +There you can choose `haskell-mode`, for example, to pretty print the +output as Haskell. + +@subsection Presentations + +If you have the `present` package installed, you can use the following +syntax to print anything which is an instance of `Data`: + +@example + λ> :present 123 + 123 +@end example + +It will print data structures lazily: + +@example + λ> :present [1..] + [1 + ,[Integer]] +@end example + +It shows types when there is an unevaluated field in a +constructor. You can click the `[Integer]` or press `RET` on it to +expand further: + +@example + λ> :present [1..] + [1 + ,2 + ,[Integer]] +@end example + +Etc. Remember: this only works for instances of `Data.Data.Data`. + +@subsection History + +A history is maintained for the duration of the REPL buffer. To go up +and down in the history, run `M-p` for previous and `M-n` for next. + +@subsection Cancelling commands + +To cancel a running REPL command, run @kbd{C-c C-c}. + +@subsection Clear the REPL + +Run @kbd{C-c C-k} to clear the REPL. + + +@subsection Trick: Put Interactive REPL in Separate Frame + + +The following @code{create-haskell-interactive-frame} is a quick hack to +move the repl to a separate frame, for those that want a more +predictable layout of windows in Emacs. + +@lisp +(defun create-unfocused-frame () + (let* + ((prv (window-frame)) + (created (make-frame))) + (select-frame-set-input-focus prv) created)) + +(defun create-haskell-interactive-frame () + (interactive) + (haskell-interactive-bring) + (create-unfocused-frame) + (delete-window)) + +@end lisp + +@subsection Troubleshooting + +If the REPL ever goes funny, you can clear the command queue via: + +@example + M-x haskell-process-clear +@end example + +Alternatively, you can just restart the process: + +@example + M-x haskell-process-restart +@end example + +You can also switch to the buffer @code{*haskell-process-log*}, which can +be enabled and disabled with the customization variable +`haskell-process-log`, to see what the cause of your troubles are. + +If the process fails and nothing unusual is in the process log, the +following command can dump the @code{haskell-process} state: + +@example + M-: (haskell-process) +@end example + +The output can be copied from the `*Messages*` buffer. + @node Editing Cabal files @chapter Editing Cabal files From 9468c11b8a7477af139cbbceec6dccdd9af02ae8 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:42:29 +0200 Subject: [PATCH 17/20] Haskell Interactive Mode Querying --- doc/haskell-mode.texi | 88 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 268e6a294..e2aa43c72 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1559,6 +1559,94 @@ following command can dump the @code{haskell-process} state: The output can be copied from the `*Messages*` buffer. +@section Haskell Interactive Mode Querying + +There a few ways GHCi lets you query information about your code. + +@subsection Get identifer type + +To print the type of the top-level identifier at point in the REPL and +in the message buffer, run the following command: + +@example + M-x haskell-process-do-type +@end example + +or @kbd{C-c C-t}. + +@subsection Insert identifier's type as type signature + +To print the type of the top-level identifier at point, run the +following command: + +@example + C-u M-x haskell-process-do-type +@end example + +or @kbd{C-u C-c C-t}. + +@subsection Get identifier info + +To print the info of the identifier at point, run the following +command: + +@example + M-x haskell-process-do-info +@end example + +or @kbd{C-c C-i}. + +@subsection Presentation mode + +When using @kbd{C-c C-i} or @kbd{C-c C-t} it will open a buffer in +haskell-presentation-mode. You can hit `q` to close the buffer. + +But you can also continue to use @kbd{C-c C-i} inside the buffer to +drill further down data types and classes. + +E.g. if you go to @code{Ord} in your code buffer and @kbd{C-c C-i}, it +will popup a buffer containing + +@example +class Eq a => Ord a where + compare :: a -> a -> Ordering + (<) :: a -> a -> Bool + (>=) :: a -> a -> Bool + (>) :: a -> a -> Bool + (<=) :: a -> a -> Bool + max :: a -> a -> a + min :: a -> a -> a + -- Defined in `GHC.Classes' +@end example + +And all the instances of that class. But then you can also move your +cursor to `Ordering` and hit `C-c C-i` again to get another popup: + +@example +data Ordering = LT | EQ | GT -- Defined in `GHC.Types' +instance Bounded Ordering -- Defined in `GHC.Enum' +instance Enum Ordering -- Defined in `GHC.Enum' +instance Eq Ordering -- Defined in `GHC.Classes' +instance Ord Ordering -- Defined in `GHC.Classes' +instance Read Ordering -- Defined in `GHC.Read' +instance Show Ordering -- Defined in `GHC.Show' +@end example + +And so on. It's a very good way of exploring a new codebase. + +@subsection Browse import's module + +To print all exported identifiers of the module imported by the import +line at point, run the following command: + +@example + M-x haskell-process-do-info +@end example + +or @kbd{C-c C-i}. It will print all exports by running @code{:browse +The.Module} in the GHCi process. + + @node Editing Cabal files @chapter Editing Cabal files From 4154007d3df004149172c1f841beeaef0d73615b Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:45:30 +0200 Subject: [PATCH 18/20] Haskell Interactive Mode Cabal integration --- doc/haskell-mode.texi | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index e2aa43c72..f1495f032 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1646,6 +1646,71 @@ line at point, run the following command: or @kbd{C-c C-i}. It will print all exports by running @code{:browse The.Module} in the GHCi process. +@section Haskell Interactive Mode Cabal integration + +There's some integration with Cabal in Haskell Interactive Mode. Once +you've started a session, the features below are available. + +@subsection Cabal building + +The most common Cabal action is building, so that has a specific command: + +@example + M-x haskell-process-cabal-build +@end example + +Or @kbd{C-c C-c}. When building, it will hide unneccessary output. + +For example, to build the `ace` package, the output is simply: + +@example + Compiling: ACE.Types.Tokens + Compiling: ACE.Combinators + Compiling: ACE.Tokenizer + Compiling: ACE.Parsers + Compiling: ACE.Pretty + Compiling: ACE + Complete: cabal build (0 compiler messages) +@end example + +Whereas the complete output is normally: + +@example + Building ace-0.5... + Preprocessing library ace-0.5... + [4 of 9] Compiling ACE.Types.Tokens ( src/ACE/Types/Tokens.hs, dist/build/ACE/Types/Tokens.o ) + [5 of 9] Compiling ACE.Combinators ( src/ACE/Combinators.hs, dist/build/ACE/Combinators.o ) [ACE.Types.Tokens changed] + [6 of 9] Compiling ACE.Tokenizer ( src/ACE/Tokenizer.hs, dist/build/ACE/Tokenizer.o ) [ACE.Types.Tokens changed] + [7 of 9] Compiling ACE.Parsers ( src/ACE/Parsers.hs, dist/build/ACE/Parsers.o ) + [8 of 9] Compiling ACE.Pretty ( src/ACE/Pretty.hs, dist/build/ACE/Pretty.o ) + [9 of 9] Compiling ACE ( src/ACE.hs, dist/build/ACE.o ) [ACE.Tokenizer changed] + In-place registering ace-0.5... +@end example + +Which is considerably more verbose but rarely useful or interesting. + +@subsection Arbitrary cabal commands + +To run an arbitrary Cabal command: + +@example + C-u M-x haskell-process-cabal +@end example + +Or run @kbd{C-u C-c c}. + +It will prompt for an input, so you can write `configure -fdev`, for example. + +@subsection Completing cabal commands + +To run some common Cabal commands, just run: + +@example + M-x haskell-process-cabal +@end example + +Or @kbd{C-c c}. This is commonly used to do @code{install}, @code{haddock}, @code{configure}, etc. + @node Editing Cabal files From e6c18b7f593bcad251873d0d951f9e34f5b8dc8a Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Sun, 3 Apr 2016 23:49:11 +0200 Subject: [PATCH 19/20] Haskell Interactive Mode Debugger --- doc/haskell-mode.texi | 194 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index f1495f032..02a8da8ff 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -1711,6 +1711,200 @@ To run some common Cabal commands, just run: Or @kbd{C-c c}. This is commonly used to do @code{install}, @code{haddock}, @code{configure}, etc. +@section Haskell Interactive Mode Debugger + +There is limited support for debugging in +GHCi. [[Haskell Interactive Mode]] provides an interface for +interacting with this. + +@subsection Opening the debug buffer + +To open the debug buffer run the following command from any buffer +associated with a session: + +@example + M-x haskell-debug +@end example + +It will open a buffer that looks like this: + +@example + Debugging haskell + + You have to load a module to start debugging. + + g - refresh + + Modules + + No loaded modules. +@end example + + +@subsection Loading modules + +To debug anything you need to load something into GHCi. Switch to a +normal file, for example: + +@example +main = do putStrLn "Hello!" + putStrLn "World" +@end example + +and load it into GHCi (@kbd{C-c C-l}). Now when you hit `g` +(to refresh) in the debugging buffer, you'll see something like: + +@example + + Debugging haskell + + b - breakpoint, g - refresh + + Context + + Not debugging right now. + + Breakpoints + + No active breakpoints. + + Modules + + Main - hello.hs +@end example + +@subsection Setting a breakpoint + +To set a breakpoint hit `b` in the debugger buffer. It will prompt for +a name. Enter `main` and hit `RET`. + +Now the buffer will look like this: + +@example + Debugging haskell + + s - step into an expression, b - breakpoint + d - delete breakpoint, g - refresh + + Context + + Not debugging right now. + + Breakpoints + + 0 - Main (1:8) + + Modules + + Main - hello.hs +@end example + +@subsection Start stepping + +Hit `s` to step through an expression: it will prompt for an +expression to evaluate and step through. Enter `main` and hit +@kbd{RET}. Now the buffer will look like this: + +@example + Debugging haskell + + s - step into an expression, b - breakpoint + d - delete breakpoint, a - abandon context, c - continue + p - previous step, n - next step + g - refresh + + Context + + main - hello.hs (stopped) + + do putStrLn "Hello!" + putStrLn "World" + + _result :: IO () = _ + + 1 do putStrLn "Hello!" putStrLn "World" + + Breakpoints + + 0 - Main (1:8) + + Modules + + Main - hello.hs +@end example + +What we see here is the current expression being evaluated: + +@example +do putStrLn "Hello!" + putStrLn "World" +@end example + +And we see the type of it: + +@example +_result :: IO () = _ +@end example + +And we see a backtrace of steps so far: + +@example +1 do putStrLn "Hello!" putStrLn "World" +@end example + +@subsection Continue stepping + +To continue stepping, just hit `s` again. Now the context will change +to: + +@example +main - hello.hs (stopped) + +putStrLn "Hello!" + +_result :: IO () = _ + + 1 do putStrLn "Hello!" putStrLn "World" +@end example + + +Hitting `s` once more, we see the context change to: + +@example +putStrLn "World" + +_result :: IO () = _ + + 2 putStrLn "Hello!" + 1 do putStrLn "Hello!" putStrLn "World" +@end example + +Finally hitting `s` again will say "Computation finished". Hitting `s` +a final time will change the display back to: + +@example + Debugging haskell + + s - step into an expression, b - breakpoint + d - delete breakpoint, g - refresh + + Context + + Finished debugging. + + 2 putStrLn "Hello!" + 1 do putStrLn "Hello!" putStrLn "World" + + Breakpoints + + 1 - Main (1:8) + + Modules + + Main - hello.hs +@end example + +And you're done debugging. @node Editing Cabal files From 7b57f8b8c5141e1f8177f508ef278ccce2bf4c96 Mon Sep 17 00:00:00 2001 From: Gracjan Polak Date: Mon, 4 Apr 2016 11:12:24 +0200 Subject: [PATCH 20/20] General formating fixes --- doc/haskell-mode.texi | 186 +++++++++++++++++++----------------------- 1 file changed, 85 insertions(+), 101 deletions(-) diff --git a/doc/haskell-mode.texi b/doc/haskell-mode.texi index 02a8da8ff..4dc628f1a 100644 --- a/doc/haskell-mode.texi +++ b/doc/haskell-mode.texi @@ -998,16 +998,6 @@ depending on the type you choose. If it does fail to launch, switch to the buffer @code{*haskell-process-log*} and see what's up. The buffer contains a log of incoming/outgoing messages to the GHCi process. -@subsection All done! - -You're all done and ready to go! But wait! - -There're a bunch more features to this mode and for which you might -want to add configurations and keybindings. So it is suggested that -once you've setup and played with the above, you continue reading what -other features are available in the [[Haskell Interactive Mode]] -documentation. - @section Haskell Interactive Mode Tags Using GHCi You can bind the following to use GHCi to find definitions of things: @@ -1020,17 +1010,17 @@ The one problem with this approach is that if your code doesn't compile, GHCi doesn't give any location info. So you need to make sure your code compiles and the modules you want to jump to are loaded byte-compiled. -**Heads up**: I think that when you restart GHCi you lose location -information, even if you have the .o and .hi files lying around. I'm not -sure. But sometimes `:i foo` will give `foo is defined in Bar` rather -than `foo is defined in /foo/Bar.hs:123:23`. +Note: I think that when you restart GHCi you lose location +information, even if you have the @file{.o} and @file{.hi} files lying around. I'm not +sure. But sometimes @code{:i foo} will give @code{foo is defined in Bar} rather +than @code{foo is defined in /foo/Bar.hs:123:23}. Alternatively, you can use tags generation, which doesn't require a -valid compile. Keep reading for that. +valid compile. @subsection Tags Setup -Make sure to install hasktags. +Make sure to install @file{hasktags}. @example $ cabal install hasktags @@ -1043,17 +1033,15 @@ Then add the customization variable to enable tags generation on save: '(haskell-tags-on-save t)) @end lisp -And make sure `hasktags` is in your [[PATH]] which Emacs can see. +And make sure @file{hasktags} is in your @code{$PATH} which Emacs can see. @subsection Generating tags -Now, every time you run `save-buffer` (`C-x C-s`), there is a hook -that will run and generate Emacs -[tags](https://www.gnu.org/software/emacs/manual/html_node/emacs/Tags.html) -for the whole project directory. The resulting file will be called -`TAGS`. +Now, every time you run @code{save-buffer} (@kbd{C-x C-s}), there is a +hook that will run and generate Emacs @xref{Tags,,,emacs} for the whole +project directory. The resulting file will be called @file{TAGS}. -**WARNING**: You should be careful that your project root isn't your +WARNING: You should be careful that your project root isn't your home directory or something, otherwise it will traverse all the way down and take an impossibly long time. @@ -1066,12 +1054,7 @@ Bind the following keybinding: @end lisp To jump to the location of the top-level identifier at point, run - -@example - M-x haskell-mode-tag-find -@end example - -or @kbd{M-.}. +@kbd{M-x} @code{haskell-mode-tag-find} or @kbd{M-.}. @subsection Hybrid: GHCi and fallback to tags @@ -1083,41 +1066,37 @@ To use GHCi first and then if that fails to fallback to tags for jumping, use: @subsection Troubleshooting tags -Sometimes a `TAGS` file is deleted (by you or some other +Sometimes a @file{TAGS} file is deleted (by you or some other process). Emacs will complain that it doesn't exist anymore. To -resolve this simply run the following: - -@example - M-x tags-reset-tags-tables -@end example - -And you're done! +resolve this simply do @kbd{M-x} @code{tags-reset-tags-tables}. @section Sessions -All commands in [[Haskell Interactive Mode]] work within a -session. Consider it like a “project” or a “solution” in popular -IDEs. It tracks the root of your project and an associated process and -REPL. - -Make sure you have [[setup your keybindings|Haskell Interactive Mode Setup]]. +All commands in Haskell Interactive Mode work within a session. Consider +it like a “project” or a “solution” in popular IDEs. It tracks the root +of your project and an associated process and REPL. @subsection Start a session -To start a session run the following steps (assumes you've already -[[setup your keybindings|Haskell Interactive Mode Setup]]). +To start a session run the following steps: -* Open some Cabal or Haskell file. -* Run C-` to make a REPL open, this will create a - session, start GHCi, and open the REPL. -* Or: run `C-c C-l` to load the file. This will first try to start a - session as the previous command does. -* Or: run any command which requires a running session. It will always - prompt to create one if there isn't one already for the current project. +@itemize +@item +Open some Cabal or Haskell file. +@item +Run @kbd{C-`} to make a REPL open, this will create a session, start +GHCi, and open the REPL. +@item +Or: run @kbd{C-c C-l} to load the file. This will first try to start a +session as the previous command does. +@item +Or: run any command which requires a running session. It will always +prompt to create one if there isn't one already for the current project. +@end itemize -It will prompt for a Cabal directory and a current directory. It -figures out where the cabal directory is and defaults for the current -directory, so you should be able to just hit RET twice. +It will prompt for a Cabal directory and a current directory. It figures +out where the cabal directory is and defaults for the current directory, +so you should be able to just hit RET twice. @subsection Switch a session @@ -1173,8 +1152,7 @@ For example: @section Compiling -Once a [[session has been started|Haskell Interactive Mode Sessions]], -there are a bunch of ways to compile Haskell modules. This page covers +There are a bunch of ways to compile Haskell modules. This page covers a few of them. @subsection Load into GHCi @@ -1207,17 +1185,16 @@ run @kbd{C-u C-c C-l} again. @subsection Jumping to compile errors -You can use the standard compile error navigation function: - -* @kbd{C-x `} — jump to the next error. +You can use the standard compile error navigation function @kbd{C-x `} — +jump to the next error. -Or you can move your cursor to an error in the REPL and hit `RET` to +Or you can move your cursor to an error in the REPL and hit @kbd{RET} to jump to it. @subsection Auto-removing imports If the customization variable -`haskell-process-suggest-remove-import-lines` is enabled. +@code{haskell-process-suggest-remove-import-lines} is enabled. @lisp (custom-set-variables @@ -1240,12 +1217,16 @@ will prompt the user with If you answer - * `y`: it will delete the import, but leave the empty line - remaining (this avoids messing with line positions in subsequent - error messages). - * `n`: it will leave the import. - * `c`: it will comment out the import (this is handy for when you - just want to temporarily hide an import). +@itemize +@item +@kbd{y}: it will delete the import, but leave the empty line remaining +(this avoids messing with line positions in subsequent error messages). +@item +@kbd{n}: it will leave the import. +@item +@kbd{c}: it will comment out the import (this is handy for when you just +want to temporarily hide an import). +@end itemize @subsection Auto-adding of modules to import @@ -1316,15 +1297,15 @@ file: Add `attoparsec' to ace.cabal? (y or n) y @end example -If you hit `y`, it will prompt with this: +If you hit @kbd{y}, it will prompt with this: @example attoparsec >= 0.11.1.0 @end example Which you can edit (e.g. do some PVP decision or remove constraints -entirely), and then it will open up your .cabal file and go through -each section: +entirely), and then it will open up your @file{.cabal} file and go +through each section: @example Add to library? (y or n) y @@ -1356,8 +1337,7 @@ with: M-x haskell-interactive-bring @end example -Or C-`, if you used the bindings in -[[the setup|Haskell Interactive Mode Setup]]. +Or @kbd{C-`}. @subsection Evaluating expressions @@ -1370,7 +1350,7 @@ To evaluate expressions, simply type one out and hit `RET`. @subsection Type of expressions -You can use normal `:t` which is part of GHCi to get the type of +You can use normal @code{:type} which is part of GHCi to get the type of something: @example @@ -1395,8 +1375,8 @@ normally yield a compile error: In a stmt of an interactive GHCi command: print it @end example -It will run `:t id` in the background and print out the result. The -same is true for ambiguous things: +It will run @code{:type id} in the background and print out the +result. The same is true for ambiguous things: @example λ> :t read "a" @@ -1459,7 +1439,8 @@ And then run Or @kbd{C-c C-v}: @lisp -(define-key haskell-interactive-mode-map (kbd "C-c C-v") 'haskell-interactive-toggle-print-mode) +(define-key haskell-interactive-mode-map (kbd "C-c C-v") + 'haskell-interactive-toggle-print-mode) @end lisp There you can choose `haskell-mode`, for example, to pretty print the @@ -1467,8 +1448,8 @@ output as Haskell. @subsection Presentations -If you have the `present` package installed, you can use the following -syntax to print anything which is an instance of `Data`: +If you have the @file{present} package installed, you can use the following +syntax to print anything which is an instance of @code{Data}: @example λ> :present 123 @@ -1483,9 +1464,9 @@ It will print data structures lazily: ,[Integer]] @end example -It shows types when there is an unevaluated field in a -constructor. You can click the `[Integer]` or press `RET` on it to -expand further: +It shows types when there is an unevaluated field in a constructor. You +can click the @code{[Integer]} or press @kbd{RET} on it to expand +further: @example λ> :present [1..] @@ -1494,12 +1475,13 @@ expand further: ,[Integer]] @end example -Etc. Remember: this only works for instances of `Data.Data.Data`. +Etc. Remember: this only works for instances of @code{Data.Data.Data}. @subsection History A history is maintained for the duration of the REPL buffer. To go up -and down in the history, run `M-p` for previous and `M-n` for next. +and down in the history, run @kbd{M-p} for previous and @kbd{M-n} for +next. @subsection Cancelling commands @@ -1557,7 +1539,7 @@ following command can dump the @code{haskell-process} state: M-: (haskell-process) @end example -The output can be copied from the `*Messages*` buffer. +The output can be copied from the @code{*Messages*} buffer. @section Haskell Interactive Mode Querying @@ -1599,7 +1581,7 @@ or @kbd{C-c C-i}. @subsection Presentation mode When using @kbd{C-c C-i} or @kbd{C-c C-t} it will open a buffer in -haskell-presentation-mode. You can hit `q` to close the buffer. +haskell-presentation-mode. You can hit @kbd{q} to close the buffer. But you can also continue to use @kbd{C-c C-i} inside the buffer to drill further down data types and classes. @@ -1620,7 +1602,8 @@ class Eq a => Ord a where @end example And all the instances of that class. But then you can also move your -cursor to `Ordering` and hit `C-c C-i` again to get another popup: +cursor to @code{Ordering} and hit @kbd{C-c C-i} again to get another +popup: @example data Ordering = LT | EQ | GT -- Defined in `GHC.Types' @@ -1699,7 +1682,8 @@ To run an arbitrary Cabal command: Or run @kbd{C-u C-c c}. -It will prompt for an input, so you can write `configure -fdev`, for example. +It will prompt for an input, so you can write @code{configure -fdev}, +for example. @subsection Completing cabal commands @@ -1709,13 +1693,13 @@ To run some common Cabal commands, just run: M-x haskell-process-cabal @end example -Or @kbd{C-c c}. This is commonly used to do @code{install}, @code{haddock}, @code{configure}, etc. +Or @kbd{C-c c}. This is commonly used to do @code{install}, +@code{haddock}, @code{configure}, etc. @section Haskell Interactive Mode Debugger -There is limited support for debugging in -GHCi. [[Haskell Interactive Mode]] provides an interface for -interacting with this. +There is limited support for debugging in GHCi. Haskell Interactive Mode +provides an interface for interacting with this. @subsection Opening the debug buffer @@ -1751,7 +1735,7 @@ main = do putStrLn "Hello!" putStrLn "World" @end example -and load it into GHCi (@kbd{C-c C-l}). Now when you hit `g` +and load it into GHCi (@kbd{C-c C-l}). Now when you hit @kbd{g} (to refresh) in the debugging buffer, you'll see something like: @example @@ -1775,8 +1759,8 @@ and load it into GHCi (@kbd{C-c C-l}). Now when you hit `g` @subsection Setting a breakpoint -To set a breakpoint hit `b` in the debugger buffer. It will prompt for -a name. Enter `main` and hit `RET`. +To set a breakpoint hit @kbd{b} in the debugger buffer. It will prompt +for a name. Enter @code{main} and hit @kbd{RET}. Now the buffer will look like this: @@ -1801,8 +1785,8 @@ Now the buffer will look like this: @subsection Start stepping -Hit `s` to step through an expression: it will prompt for an -expression to evaluate and step through. Enter `main` and hit +Hit @kbd{s} to step through an expression: it will prompt for an +expression to evaluate and step through. Enter @code{main} and hit @kbd{RET}. Now the buffer will look like this: @example @@ -1854,7 +1838,7 @@ And we see a backtrace of steps so far: @subsection Continue stepping -To continue stepping, just hit `s` again. Now the context will change +To continue stepping, just hit @kbd{s} again. Now the context will change to: @example @@ -1868,7 +1852,7 @@ _result :: IO () = _ @end example -Hitting `s` once more, we see the context change to: +Hitting @kbd{s} once more, we see the context change to: @example putStrLn "World" @@ -1879,8 +1863,8 @@ _result :: IO () = _ 1 do putStrLn "Hello!" putStrLn "World" @end example -Finally hitting `s` again will say "Computation finished". Hitting `s` -a final time will change the display back to: +Finally hitting @kbd{s} again will say "Computation finished". Hitting +@kbd{s} a final time will change the display back to: @example Debugging haskell