Skip to content

Loading…

Virthualenv integration #84

Closed
wants to merge 6 commits into from

3 participants

@boothead

I had some problems with a snap project and the code reloading under cabal-dev so I've had a stab at getting virthualenv working with haskell-mode. I've got the basics of virthualenv integration in this pull request. It's pretty alpha (and it's also the first elisp I've written) so I'd like to ask for some help to get it up to scratch.

At the moment you use it like this:

Set the virthaulenv on the current session
M-x haskell-process-ve

This prompts you for the virthualenv location and attempts to find it much like setting the .cabal file location. Note You have to already have a haskell-session for this to work.

You can then activate the virthualenv with
M-x haskell-virthualenv-activate

After you've done this the prompt in interactive mode looks like
(snap) λ>

haskell-process-type has to be ghci. It would seem to make sense to enforce or set this when activating the virthualenv but I wasn't sure if there's a use case for cabal-dev within a virthualenv so I haven't done anything about that yet.

ISSUES

  • I couldn't quite see how to set the prompt in the interactive mode straight away - the (<virthualenv-name>) only appears after I've run the first command in the interactive window
  • Should it be a minor mode?
  • The haskell-process-ve only seems to be available after I've run C-c C-l to get a session. I assume that this is due to the autoloading? It would be nice to have a better way to set the virthualenv up initially.
  • No integration with haskell-process-start as yet. I wanted to keep touching other files to a minimum initially, but I think it would make more sense to work the presence of a virthualenv on the session impact on what's passed to haskell-process-set-process inside haskell-process-start
@konn

I need the hsenv (previously called virthualenv) support for haskell-mode, too. I have to use hsenv to write the program using GHC HEAD's feature.
I hope this patch would be merged.

@bos
Haskell member

I'm sorry that this patch set didn't get any sort of timely attention. Could you please rebase it?

@boothead

I'll rewrite it @bos. I looked at getting up to date a little while ago and a lot had changed underneath. I'll close this one for now and open another one.

@boothead boothead closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 16, 2013
  1. @boothead

    Beginnings of virthualenv integration

    boothead committed with Ben Ford
  2. Add function to activate the virthualenv for a session.

    Ben Ford committed
    Also surround the logic for deactivate to check for an active vurthualenv
  3. @boothead

    WIP

    boothead committed with Ben Ford
  4. Make naming a bit more consistent

    Ben Ford committed
  5. Regenerate site file

    Ben Ford committed
This page is out of date. Refresh to see the latest.
Showing with 256 additions and 30 deletions.
  1. +1 −0 Makefile
  2. +1 −1 haskell-interactive-mode.el
  3. +9 −0 haskell-process.el
  4. +126 −0 haskell-session-virthualenv.el
  5. +119 −29 haskell-site-file.el
View
1 Makefile
@@ -22,6 +22,7 @@ ELFILES = \
haskell-package.el \
haskell-process.el \
haskell-session.el \
+ haskell-session-virthualenv.el \
haskell-string.el \
ghc-core.el \
inf-haskell.el
View
2 haskell-interactive-mode.el
@@ -256,7 +256,7 @@ Key bindings:
"Show a prompt at the end of the buffer."
(with-current-buffer (haskell-session-interactive-buffer session)
(goto-char (point-max))
- (insert (propertize haskell-interactive-prompt
+ (insert (propertize (format "%s%s" (haskell-virthualenv-prompt-prefix) haskell-interactive-prompt)
'face 'haskell-interactive-face-prompt
'read-only t
'rear-nonsticky t
View
9 haskell-process.el
@@ -29,6 +29,7 @@
(require 'haskell-mode)
(require 'haskell-interactive-mode)
(require 'haskell-session)
+(require 'haskell-session-virthualenv)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Configuration
@@ -596,6 +597,14 @@ to be loaded by ghci."
(format "Changed directory: %s"
(caddr state)))))))
+(defun haskell-process-ve (&optional not-interactive)
+ "Set virthualenv"
+ (interactive)
+ (let ((session (haskell-session))
+ (ve (haskell-virthualenv-get-dir)))
+ (haskell-process-log (format "Setting virthualenv location to %s ...\n" ve))
+ (haskell-session-set-virthualenv session ve)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Process communication
View
126 haskell-session-virthualenv.el
@@ -0,0 +1,126 @@
+;;; haskell-session-virthualenv.el -- Haskell sessions.
+
+;; Copyright (C) 2012 Ben Ford
+
+;; Author: Ben Ford <ben.fordnz@gmail.com>
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Todo:
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'haskell-cabal)
+(require 'haskell-string)
+
+(setq haskell-sve-virthualenv nil)
+(setq haskell-sve-path-backup nil)
+(setq haskell-sve-exec-path-backup nil)
+
+
+(defun haskell-sve-find-dir ()
+ "Return a buffer visiting the cabal file of the current directory, or nil."
+ (catch 'found
+ (let ((root (abbreviate-file-name default-directory))
+ ve)
+ (while root
+ (if (setq ve (car (directory-files root 'full "\\.virthualenv\\'")))
+ (throw 'found root)
+ (if (equal root
+ (setq root (file-name-directory
+ (directory-file-name root))))
+ (setq root nil))))
+ nil)))
+
+
+(defun haskell-sve-read-file (fpath)
+ (with-temp-buffer
+ (insert-file-contents fpath)
+ (buffer-string)))
+
+
+(defun haskell-sve-activate (dir)
+ "Activate the Virtual Haskell Environment in DIR"
+ (haskell-sve-deactivate)
+ (setq dir (file-name-as-directory dir))
+
+ (let* ((haskell-sve-dir (concat dir ".virthualenv/"))
+ (path-var-prependix-location (concat haskell-sve-dir "path_var_prependix"))
+ (ghc-package-path-var-location (concat haskell-sve-dir "ghc_package_path_var"))
+ (path-var-prependix (haskell-sve-read-file path-var-prependix-location))
+ (ghc-package-path-var (haskell-sve-read-file ghc-package-path-var-location))
+ (new-path-var (concat path-var-prependix ":" (getenv "PATH")))
+ (exec-path-prependix (split-string path-var-prependix ":")))
+ (setq haskell-sve-path-backup (getenv "PATH"))
+ (setenv "PATH" new-path-var)
+ (setq haskell-sve-exec-path-backup exec-path)
+ (setq exec-path (append exec-path-prependix exec-path))
+ (setenv "GHC_PACKAGE_PATH" ghc-package-path-var)
+ (setq haskell-sve-virthualenv dir)))
+
+
+(defun haskell-sve-deactivate ()
+ "Deactivate the Virtual Haskell Environment"
+ (if haskell-sve-virthualenv
+ (progn
+ (setenv "PATH" haskell-sve-path-backup)
+ (setq exec-path haskell-sve-exec-path-backup)
+ (setenv "GHC_PACKAGE_PATH" nil)
+ (setq haskell-sve-virthualenv nil)
+ (setq haskell-sve-path-backup nil)
+ (setq haskell-sve-exec-path-backup nil))))
+
+;;;###autoload
+(defun haskell-session-set-virthualenv (s v)
+ "Set the sessions virthualenv directory"
+ (haskell-session-set s 'haskell-sve-virthualenv v))
+
+;;;###autoload
+(defun haskell-session-virthualenv (s)
+ "Get the sessions virthualenv directory"
+ (haskell-session-get s 'haskell-sve-virthualenv))
+
+;;;###autoload
+(defun haskell-virthualenv-get-dir ()
+ "Get the .virthualenv dir for a new project. Various ways of figuring this out,
+ and indeed just prompting the user. Do them all."
+ (let* ((dir (haskell-sve-find-dir)))
+ (read-from-minibuffer
+ (format "directory containing virthualenv%s: " (if dir (format " (%s)" (file-relative-name dir)) ""))
+ (or dir default-directory))))
+
+;;;###autoload
+(defun haskell-virthualenv-activate ()
+ "Activate the virthualenv for this session"
+ (interactive)
+ (let* ((s (haskell-session))
+ (ve (haskell-session-virthualenv s)))
+ (if ve
+ (haskell-sve-activate ve))))
+
+;;;###autoload
+(defun haskell-virthualenv-prompt-prefix ()
+ "Get the name of the currently active virthualenv
+
+ If there isn't one active retruns empty string"
+ (if haskell-sve-virthualenv
+ (format "(%s) " (file-name-nondirectory (directory-file-name haskell-sve-virthualenv)))
+ ""))
+
+(provide 'haskell-session-virthualenv)
View
148 haskell-site-file.el
@@ -1,6 +1,6 @@
;;;### (autoloads (ghc-core-mode ghc-core-create-core) "ghc-core"
-;;;;;; "ghc-core.el" (20327 38141))
+;;;;;; "ghc-core.el" (20448 8432))
;;; Generated autoloads from ghc-core.el
(autoload 'ghc-core-create-core "ghc-core" "\
@@ -18,7 +18,7 @@ Major mode for GHC Core files.
;;;***
;;;### (autoloads (haskell-align-imports) "haskell-align-imports"
-;;;;;; "haskell-align-imports.el" (20341 28472))
+;;;;;; "haskell-align-imports.el" (20448 8432))
;;; Generated autoloads from haskell-align-imports.el
(autoload 'haskell-align-imports "haskell-align-imports" "\
@@ -28,8 +28,8 @@ Align all the imports in the buffer.
;;;***
-;;;### (autoloads (haskell-c-mode) "haskell-c" "haskell-c.el" (20327
-;;;;;; 38141))
+;;;### (autoloads (haskell-c-mode) "haskell-c" "haskell-c.el" (20448
+;;;;;; 8432))
;;; Generated autoloads from haskell-c.el
(add-to-list 'auto-mode-alist '("\\.hsc\\'" . haskell-c-mode))
@@ -42,17 +42,17 @@ Major mode for Haskell FFI files.
;;;***
;;;### (autoloads (haskell-cabal-get-dir haskell-cabal-mode) "haskell-cabal"
-;;;;;; "haskell-cabal.el" (20334 23077))
+;;;;;; "haskell-cabal.el" (20508 11604))
;;; Generated autoloads from haskell-cabal.el
-(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))
+(add-to-list (quote auto-mode-alist) (quote ("\\.cabal\\'" . haskell-cabal-mode)))
-(autoload 'haskell-cabal-mode "haskell-cabal" "\
+(autoload (quote haskell-cabal-mode) "haskell-cabal" "\
Major mode for Cabal package description files.
\(fn)" t nil)
-(autoload 'haskell-cabal-get-dir "haskell-cabal" "\
+(autoload (quote haskell-cabal-get-dir) "haskell-cabal" "\
Get the Cabal dir for a new project. Various ways of figuring this out,
and indeed just prompting the user. Do them all.
@@ -61,7 +61,7 @@ Get the Cabal dir for a new project. Various ways of figuring this out,
;;;***
;;;### (autoloads (haskell-decl-scan-mode) "haskell-decl-scan" "haskell-decl-scan.el"
-;;;;;; (20327 38141))
+;;;;;; (20448 8432))
;;; Generated autoloads from haskell-decl-scan.el
(autoload 'haskell-decl-scan-mode "haskell-decl-scan" "\
@@ -111,7 +111,7 @@ Invokes `haskell-decl-scan-mode-hook'.
;;;***
;;;### (autoloads (haskell-doc-show-type haskell-doc-mode) "haskell-doc"
-;;;;;; "haskell-doc.el" (20327 38141))
+;;;;;; "haskell-doc.el" (20567 13022))
;;; Generated autoloads from haskell-doc.el
(autoload 'haskell-doc-mode "haskell-doc" "\
@@ -134,7 +134,7 @@ current buffer.
;;;***
;;;### (autoloads (haskell-indent-mode) "haskell-indent" "haskell-indent.el"
-;;;;;; (20327 38141))
+;;;;;; (20448 8432))
;;; Generated autoloads from haskell-indent.el
(autoload 'haskell-indent-mode "haskell-indent" "\
@@ -166,7 +166,7 @@ Invokes `haskell-indent-hook' if not nil.
;;;***
;;;### (autoloads (haskell-indentation-mode) "haskell-indentation"
-;;;;;; "haskell-indentation.el" (20328 13471))
+;;;;;; "haskell-indentation.el" (20567 13022))
;;; Generated autoloads from haskell-indentation.el
(autoload 'haskell-indentation-mode "haskell-indentation" "\
@@ -181,7 +181,7 @@ autofill-mode.
;;;### (autoloads (haskell-interactive-mode-echo haskell-interactive-switch
;;;;;; haskell-interactive-bring haskell-interactive-mode) "haskell-interactive-mode"
-;;;;;; "haskell-interactive-mode.el" (20338 50718))
+;;;;;; "haskell-interactive-mode.el" (20568 37399))
;;; Generated autoloads from haskell-interactive-mode.el
(autoload 'haskell-interactive-mode "haskell-interactive-mode" "\
@@ -207,7 +207,7 @@ Echo a read only piece of text before the prompt.
;;;***
;;;### (autoloads (haskell-hayoo haskell-hoogle literate-haskell-mode
-;;;;;; haskell-mode) "haskell-mode" "haskell-mode.el" (20341 54213))
+;;;;;; haskell-mode) "haskell-mode" "haskell-mode.el" (20567 13022))
;;; Generated autoloads from haskell-mode.el
(add-to-list 'load-path (or (file-name-directory load-file-name) (car load-path)))
@@ -276,10 +276,10 @@ Do a Hayoo search for QUERY.
;;;***
;;;### (autoloads (haskell-move-nested) "haskell-move-nested" "haskell-move-nested.el"
-;;;;;; (20328 13471))
+;;;;;; (20508 11604))
;;; Generated autoloads from haskell-move-nested.el
-(autoload 'haskell-move-nested "haskell-move-nested" "\
+(autoload (quote haskell-move-nested) "haskell-move-nested" "\
Not documented
\(fn COLUMNS)" nil nil)
@@ -288,7 +288,7 @@ Not documented
;;;### (autoloads (haskell-navigate-imports-return haskell-navigate-imports-go
;;;;;; haskell-navigate-imports) "haskell-navigate-imports" "haskell-navigate-imports.el"
-;;;;;; (20328 13471))
+;;;;;; (20448 8432))
;;; Generated autoloads from haskell-navigate-imports.el
(autoload 'haskell-navigate-imports "haskell-navigate-imports" "\
@@ -310,8 +310,8 @@ Return to the non-import point we were at before going to the module list.
;;;***
;;;### (autoloads (haskell-process haskell-process-start haskell-process-cabal
-;;;;;; haskell-process-cabal-build haskell-process-load-file) "haskell-process"
-;;;;;; "haskell-process.el" (20340 57610))
+;;;;;; haskell-process-cabal-build haskell-process-reload-file haskell-process-load-file)
+;;;;;; "haskell-process" "haskell-process.el" (20568 11072))
;;; Generated autoloads from haskell-process.el
(autoload 'haskell-process-load-file "haskell-process" "\
@@ -319,6 +319,11 @@ Load the current buffer file.
\(fn)" t nil)
+(autoload 'haskell-process-reload-file "haskell-process" "\
+Load the current buffer file.
+
+\(fn)" t nil)
+
(autoload 'haskell-process-cabal-build "haskell-process" "\
Build the Cabal project.
@@ -342,23 +347,83 @@ Get the current process from the current session.
;;;***
;;;### (autoloads (haskell-session-process haskell-session) "haskell-session"
-;;;;;; "haskell-session.el" (20344 42487))
+;;;;;; "haskell-session.el" (20566 45512))
;;; Generated autoloads from haskell-session.el
-(autoload 'haskell-session "haskell-session" "\
+(autoload (quote haskell-session) "haskell-session" "\
Get the Haskell session, prompt if there isn't one or fail.
\(fn)" nil nil)
-(autoload 'haskell-session-process "haskell-session" "\
+(autoload (quote haskell-session-process) "haskell-session" "\
Get the session process.
\(fn S)" nil nil)
;;;***
+;;;### (autoloads (haskell-virthualenv-prompt-prefix haskell-virthualenv-activate
+;;;;;; haskell-virthualenv-get-dir haskell-session-virthualenv haskell-session-set-virthualenv)
+;;;;;; "haskell-session-virthualenv" "haskell-session-virthualenv.el"
+;;;;;; (20568 36956))
+;;; Generated autoloads from haskell-session-virthualenv.el
+
+(autoload 'haskell-session-set-virthualenv "haskell-session-virthualenv" "\
+Set the sessions virthualenv directory
+
+\(fn S V)" nil nil)
+
+(autoload 'haskell-session-virthualenv "haskell-session-virthualenv" "\
+Get the sessions virthualenv directory
+
+\(fn S)" nil nil)
+
+(autoload 'haskell-virthualenv-get-dir "haskell-session-virthualenv" "\
+Get the .virthualenv dir for a new project. Various ways of figuring this out,
+ and indeed just prompting the user. Do them all.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-virthualenv-activate "haskell-session-virthualenv" "\
+Activate the virthualenv for this session
+
+\(fn)" t nil)
+
+(autoload 'haskell-virthualenv-prompt-prefix "haskell-session-virthualenv" "\
+Get the name of the currently active virthualenv
+
+ If there isn't one active retruns empty string
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (haskell-show-parse haskell-show-parse-and-insert
+;;;;;; haskell-show-replace) "haskell-show" "haskell-show.el" (20508
+;;;;;; 11604))
+;;; Generated autoloads from haskell-show.el
+
+(autoload (quote haskell-show-replace) "haskell-show" "\
+Replace the given region containing a Show value with a pretty
+ printed collapsible version.
+
+\(fn START END)" nil nil)
+
+(autoload (quote haskell-show-parse-and-insert) "haskell-show" "\
+Parse a `string' containing a Show instance value and insert
+ it pretty printed into the current buffer.
+
+\(fn GIVEN)" nil nil)
+
+(autoload (quote haskell-show-parse) "haskell-show" "\
+Parse the given input into a tree.
+
+\(fn GIVEN)" nil nil)
+
+;;;***
+
;;;### (autoloads (haskell-sort-imports) "haskell-sort-imports" "haskell-sort-imports.el"
-;;;;;; (20328 13471))
+;;;;;; (20448 8432))
;;; Generated autoloads from haskell-sort-imports.el
(autoload 'haskell-sort-imports "haskell-sort-imports" "\
@@ -368,11 +433,32 @@ Sort the import list at the point.
;;;***
+;;;### (autoloads (haskell-is-prefix-of haskell-string-take haskell-trim)
+;;;;;; "haskell-string" "haskell-string.el" (20508 11604))
+;;; Generated autoloads from haskell-string.el
+
+(autoload (quote haskell-trim) "haskell-string" "\
+Not documented
+
+\(fn STRING)" nil nil)
+
+(autoload (quote haskell-string-take) "haskell-string" "\
+Take n chars from string.
+
+\(fn STRING N)" nil nil)
+
+(autoload (quote haskell-is-prefix-of) "haskell-string" "\
+Is x string a prefix of y string?
+
+\(fn X Y)" nil nil)
+
+;;;***
+
;;;### (autoloads (inferior-haskell-find-haddock inferior-haskell-find-definition
-;;;;;; inferior-haskell-info inferior-haskell-type inferior-haskell-send-decl
-;;;;;; inferior-haskell-load-and-run inferior-haskell-load-file
-;;;;;; switch-to-haskell) "inf-haskell" "inf-haskell.el" (20333
-;;;;;; 43796))
+;;;;;; inferior-haskell-info inferior-haskell-kind inferior-haskell-type
+;;;;;; inferior-haskell-send-decl inferior-haskell-load-and-run
+;;;;;; inferior-haskell-load-file switch-to-haskell) "inf-haskell"
+;;;;;; "inf-haskell.el" (20567 13022))
;;; Generated autoloads from inf-haskell.el
(defalias 'run-haskell 'switch-to-haskell)
@@ -406,6 +492,11 @@ The returned info is cached for reuse by `haskell-doc-mode'.
\(fn EXPR &optional INSERT-VALUE)" t nil)
+(autoload 'inferior-haskell-kind "inf-haskell" "\
+Query the haskell process for the kind of the given expression.
+
+\(fn TYPE)" t nil)
+
(autoload 'inferior-haskell-info "inf-haskell" "\
Query the haskell process for the info of the given expression.
@@ -437,8 +528,7 @@ we load it.
;;;### (autoloads nil nil ("haskell-checkers.el" "haskell-font-lock.el"
;;;;;; "haskell-ghci.el" "haskell-hugs.el" "haskell-package.el"
-;;;;;; "haskell-simple-indent.el" "haskell-string.el" "init.el")
-;;;;;; (20344 42495 885853))
+;;;;;; "haskell-simple-indent.el") (20568 38833 279214))
;;;***
Something went wrong with that request. Please try again.