[Haskell-cafe] Bug in Emacs Haskell Mode

Ronald Guida oddron at gmail.com
Tue Jun 24 17:46:56 EDT 2008

Emacs Haskell Mode has the following useful feature: when "Haskell ->
Load File" is used to load a file into GHCi from Emacs, Haskell Mode
automatically looks for a "*.cabal" file in an attempt to find the
project directory.

When Haskell Mode finds the *.cabal file, it fails to check whether it
has found a file or a folder.  As a result, if I want to load a
Haskell file that has no corresponding .cabal file, then Haskell Mode
locates my "~/.cabal" *folder* and assumes that it's my project

I have a "~/.cabal" folder because Cabal-Install puts it there.
Cabal-Install is part of Haskell's new package management system.

Now I don't know very much Emacs Lisp, but I figured out a fix for the
problem.  In Haskell-Mode-2.4, in the file haskell-cabal.el, I changed
the function "haskell-cabal-find-file" so that it explicitly checks to
make sure that any *.cabal file is in fact a file and not a folder.

I don't know if comparing the first letter of the file mode string to
'd' is the right way to diferentiate a folder from a file, but so far
it appears to work for me, so I thought I'd share it.

(defun haskell-cabal-find-file ()
  "Return a buffer visiting the cabal file of the current directory, or nil."
  (catch 'found
    (let ((user (nth 2 (file-attributes default-directory)))
          ;; Abbreviate, so as to stop when we cross ~/.
          (root (abbreviate-file-name default-directory))
      (while (and root (equal user (nth 2 (file-attributes root))))
	(let ((files (directory-files root 'full "\\.cabal\\'")))
	  (if (and files
		   (not (equal 100 (aref (nth 8
			   (file-attributes (car files))) 0))))
	      (throw 'found (find-file-noselect (car files)))
	    (if (equal root
		       (setq root (file-name-directory
				   (directory-file-name root))))
		(setq root nil))))

More information about the Haskell-Cafe mailing list