In this blog post I talk about my progress in haskell-interactive-mode (clone of haskell-mode).

I implemented collapse functionality with hideshow.el. I wrote tests and documentation too. I did not plan on implementing this feature while writing the proposal, but I implemented it anyway because it was easy to get started with (I was an Elisp noob at that time). There was one interesting problem that I had to solve. Normally with languages with braces this functionality is very easy to implement, just find the braces, then find the region and then hide it. Haskell supports braces but most of the time people use the offset rule (indentation). I found that python-mode uses the offset rule too. They identify the blocks with the amount of white space infront and then they do the hiding. One member of the community suggested that I take a look at the origami package. That package seemed to have a lot of features but I decided to go with hideshow because it was the standard in emacs. You don’t have to learn new key-bingings, you can use the same thing that you would use with the other popular major modes. Quite possibly we could have had the same key-bindings with origami too. But, Sigh! It is not like the most important feature of all time. Moving on.

At this point, I’m not an elisp noob anymore. The most important thing that I had to do was, split haskell-interactive-mode from haskell-mode. As a start, I forked the repo, browsed the code around and identified which files go where. There were some parts that are common to both the projects, such as font-lock (syntax highlighting in emacs parlance), etc. I did not perform the split but I did file that as an issue for future reference (the issue tells elaborately which files should go where).

Then I saw what was going on in the haskell-interactive-mode (Major mode for ghci repl). It looks like a clone of comint mode (the features). There is Inf-Haskell, it is depricated and is a major-mode for ghci repl, It is based on comint.

At this point what I would like to do is improve Inf-Haskell. This is because comint comes with a lot of builtin good features such as command history, creating process in buffer and what not. Again it is the standard so it is just like the M-x shell. You get all the shortcuts that you get with M-x shell or M-x ielm for a little or no additional code. Less code, easy maintainance and less effort.

One feature that you get with haskell-interactive-mode is that you automatically get the correct repl. If your project directory contains .stack.yaml file or something like .cabal file you get the stack ghci or cabal repl or the plain ghci. You have the option to customize what repl you will use and what command line argument that you will use. So potentially you could also use Hugs if you like. I was able to pull most of the code for this from the exising code itself, that was a win.

One thing that is bad about both haskell-interactive-mode and Inf-Haskell is that they don’t have tests. I did write one test for Inf-Haskell (What!!! Just one test?). Yes calm down. That too to check if the interactive method to start the repl works or not by quering the repl process.

Now I faced a new problem, the default distro that Travis ran at that time was Precise pangolin, Yes Ubuntu 12.04. We had an option to run Trusty Tahr (Ubuntu 14.04), but that distro is too old too. Enter docker. Now I can use what ever distro I want. I can install the newest packages (ghci and Emacs) from the package managers and that is awesome. Then I setup AppVeyor with choco, I wasted some time trying to install ghci from the haskell website (for windows installation), I tried to put things in path and yes it was not pretty. I had zero experience with powershell and that was not very helpful. One StackOverflow user suggested that I use Choco. Seriously package managers make our lives so much more easier. In the mean while I reinstalled Windows 10 on my VM.

I did not know this, but what I thought was haskell-interactive-mode was giving me all the cool features like loading the file, getting completions from ghci etc. But there is interactive-haskell-mode (minor mode) in haskell.el. Yes the naming was not very helpful and I was downright ignorant because I was already using interactive-haskell-mode with a hook. Now that I know my way around. interactive-haskell-mode is currently dependent on haskell-interactive-mode, but I wanna change that, interactive-haskell-mode should depend on the comint based Inf-Haskell. If I complete doing this, we can kill haskell-interactive-mode. So how much of that have I completed? Well I’ve made completion-at-point-functions to run with Inf-Haskell. Where is the proof? Where are the tests? Tests are on their way. Wont this break interactive-haskell-mode? Yes it is broken, except completion-at-point-functions everything else is based on haskell-interactive-mode.

Did I tell you that I hosted the docs on readthedocs.io? It looks amazing!

I have to talk about one more thing. The auto completions that you get with interactive-haskell-mode is based on this cool feature of ghci. If you type :complete repl "import Data.B" into ghci, it gives you this:

Prelude> :complete repl "import Data.B"
25 25 "import "
"Data.Bifunctor"
"Data.Binary"
"Data.Binary.Builder"
"Data.Binary.Get"
"Data.Binary.Get.Internal"
"Data.Binary.Put"
"Data.Bits"
"Data.Bool"
"Data.ByteString"
"Data.ByteString.Builder"
"Data.ByteString.Builder.Extra"
"Data.ByteString.Builder.Internal"
"Data.ByteString.Builder.Prim"
"Data.ByteString.Builder.Prim.Internal"
"Data.ByteString.Char8"
"Data.ByteString.Internal"
"Data.ByteString.Lazy"
"Data.ByteString.Lazy.Builder"
"Data.ByteString.Lazy.Builder.ASCII"
"Data.ByteString.Lazy.Builder.Extras"
"Data.ByteString.Lazy.Char8"
"Data.ByteString.Lazy.Internal"
"Data.ByteString.Short"
"Data.ByteString.Short.Internal"
"Data.ByteString.Unsafe"
Prelude>

In the mean while my .emacs file has been growing. I installed helm on my Emacs, helm is one of the best packages that I’ve ever used with Emacs, it has definitely increased my productivity. My mentor asked me to use paredit. I’ve been using it for almost two days now. That is longer than the last time I tried using it.

The task that lies ahead of me is writing a lot of tests.

Edit: The name of the major mode for ghci is Inf-haskell and not inferior-haskell-mode.