HSoC status update
In this blog post I talk about my progress in
haskell-interactive-mode (clone of
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-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
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
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