Skip to content
Dan edited this page Jun 30, 2013 · 3 revisions

ghc-mod is a backend designed command to enrich Haskell programming on editors like Emacs and Vim and it also features a front-end for Emacs as a set of elisp scripts. It's a really cool piece of software and if you have not tried it yet I highly recommend you to invest into installing and using it.

What we would like, however, is to edit files on the mounted filesystem using Emacs on the host machine, but run ghc-mod inside the VM. In order to do that we need to install ghc-mod both on our host machine and on the VM.

While installing ghc-mod on the host machine running the latest haskell-platform is pretty straightforward it is harder to do so on the VM running GHC 7.7 due to the fact that many libraries are not ready for GHC 7.7 and base 4.7 yet. We have to resort to installing most of the things from source

Note: you don't have do install ghc-mod manually if you are not using GHC 7.7 on the guest machine.

# run this on the guest machine
mkdir ghcmod && cd ghcmod

# patching and installing hlint
darcs get http://community.haskell.org/~ndm/darcs/hlint/
cd hlint
wget http://co-dan.github.io/patched/making-hlint-work-with-base-4_7.dpatch
darcs apply making-hlint-work-with-base-4_7.dpatch
cabal install
cd ..

# patching installing convertible
cabal unpack convertible
cd convertible*
wget http://co-dan.github.io/patched/convertible.patch
patch -p1 Data/Convertible/Utils.hs convertible.patch
cabal install
cd ..

# installing ghc-syb-utils
git clone https://github.com/co-dan/ghc-syb.git
cd ghc-syb/utils/
cabal install
cd ..

# finally getting and installing ghc-mod
git clone https://github.com/co-dan/ghc-mod.git
cd ghc-mod
cabal install

Ghc-mod itself uses the GHC API extensively so it's no surprise we have to change at least some code. Now that we have installed ghc-mod on the guest VM we need to set up our host's Emacs configuration to communicate properly with the VM. First of all put this in your Emacs config:

(setq load-path (cons "~/Library/Haskell/ghc-7.6.3/lib/ghc-mod-2.0.3/share" load-path))
(autoload 'ghc-init "ghc" nil t)
(add-hook 'haskell-mode-hook (lambda () (ghc-init)))
;; (setq ghc-module-command "ghc-mod")
(setq ghc-module-command "~/vado-ghc-mod.sh")

~/vado-ghc-mod.sh should contain the following (please modify the variables according to your needs):

#!/bin/bash
VADO=/Users/dan/Library/Haskell/bin/vado
LOCAL_PATH=/Users/dan/projects/ghcjs/mnt/
REMOTE_PATH=/home/vagrant/
cd $LOCAL_PATH
$VADO -t ghc-mod ${@//$LOCAL_PATH/$REMOTE_PATH} | sed "s,$REMOTE_PATH,$LOCAL_PATH,g"

I know that it's a hack, but it does work and I guess that's what shell scripts are for ;)

Now go to ~/.bashrc on the guest machine and make sure that the PATH variable is set correctly:

PATH=/home/vagrant/ghcjs/bin:/home/vagrant/.cabal/bin:/home/vagrant/ghc/bin:/home/vagrant/jsshell:/home/vagrant/node-v0.10.10-linux-x86/bin:$PATH

# PATH is set *before* this line:
[ -z "$PS1" ] && return

# <snip>

And that's it, you should be done!

Before: Before After: After

Clone this wiki locally