diff --git a/ChangeLog b/ChangeLog index f1355d1b0..0d90e0fbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2007-05-08 Stefan Monnier + * inf-haskell.el (inferior-haskell-use-cabal): New custom var. + (inferior-haskell-cabal-of-buf): New fun. + (inferior-haskell-load-file): Use it to try and do the right thing in + multi-directory projects using a Cabal file. + + * haskell-cabal.el (inferior-haskell-string-prefix-p) + (haskell-cabal-find-file): New functions. + * inf-haskell.el (inferior-haskell-string-to-strings): Remove `separator' argument. Call split string without separator arg either, so that it drops null strings. diff --git a/NEWS b/NEWS index d78c6620e..9c1ab0de9 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ Changes since 2.3: +* inf-haskell.el looks for a Cabal file to determine the root of a project. + If all works well, this will make C-c C-l automatically switch to the root + dir, so that dependencies in other directories are automatically found. + If it doesn't, complain and/or set inferior-haskell-use-cabal to nil. + * The new command haskell-hoogle helps you query Hoogle from Emacs. Changes since 2.2: diff --git a/inf-haskell.el b/inf-haskell.el index ecb31ab8b..05602a51c 100644 --- a/inf-haskell.el +++ b/inf-haskell.el @@ -66,6 +66,10 @@ The command can include arguments." "Regexps for error messages generated by inferior Haskell processes. The format should be the same as for `compilation-error-regexp-alist'.") +(defcustom inferior-haskell-use-cabal t + "If non-nil, try and find a Cabal file to get the project root directory." + :type 'boolean) + (define-derived-mode inferior-haskell-mode comint-mode "Inf-Haskell" "Major mode for interacting with an inferior Haskell process." (set (make-local-variable 'comint-prompt-regexp) @@ -170,22 +174,40 @@ The process PROC should be associated to a comint buffer." (and (not (re-search-forward comint-prompt-regexp nil t)) (accept-process-output proc)))))) +(defvar inferior-haskell-cabal-buffer nil) + +(defun inferior-haskell-cabal-of-buf (buf) + (require 'haskell-cabal) + (with-current-buffer buf + (or inferior-haskell-cabal-buffer + (and (not (local-variable-p 'inferior-haskell-cabal-buffer)) + (set (make-local-variable 'inferior-haskell-cabal-buffer) + (haskell-cabal-find-file)))))) + ;;;###autoload (defun inferior-haskell-load-file (&optional reload) "Pass the current buffer's file to the inferior haskell process." (interactive) ;; Save first, so we're sure that `buffer-file-name' is non-nil afterward. (save-buffer) - (let ((file buffer-file-name) + (let ((buf (current-buffer)) + (file buffer-file-name) (proc (inferior-haskell-process))) (with-current-buffer (process-buffer proc) - ;; Not sure if it's useful/needed and if it actually works. - ;; (unless (equal (file-name-as-directory default-directory) - ;; (file-name-directory file)) - ;; (inferior-haskell-send-string - ;; proc (concat ":cd " (file-name-directory file) "\n"))) (compilation-forget-errors) - (let ((parsing-end (marker-position (process-mark proc)))) + (let ((parsing-end (marker-position (process-mark proc))) + cabal) + ;; Go to the root of the Cabal project, if applicable. + (when (and inferior-haskell-use-cabal + (setq cabal (inferior-haskell-cabal-of-buf buf))) + ;; Not sure if it's useful/needed and if it actually works. + (unless (equal default-directory + (with-current-buffer cabal default-directory)) + (setq default-directory + (with-current-buffer cabal default-directory)) + (inferior-haskell-send-command + proc (concat ":cd " default-directory))) + (setq file (file-relative-name file))) (inferior-haskell-send-command proc (if reload ":reload" (concat ":load \"" file "\""))) ;; Move the parsing-end marker after sending the command so