Skip to content

Added nix-shell-ghci support. #350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 102 additions & 66 deletions haskell-process.el
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@
:group 'haskell-interactive
:type '(choice string (repeat string)))

(defcustom haskell-process-path-nix-shell
"nix-shell"
"The path for starting nix-shell."
:group 'haskell-interactive
:type '(choice string (repeat string)))

(defcustom haskell-process-args-nix-shell
'("shell.nix")
"Any arguments for starting nix-shell."
:group 'haskell-interactive
:type '(choice string (repeat string)))


(defcustom haskell-process-args-ghci
'("-ferror-spans")
"Any arguments for starting ghci."
Expand Down Expand Up @@ -106,7 +119,8 @@ See `haskell-process-do-cabal' for more details."
(defcustom haskell-process-type
'auto
"The inferior Haskell process type to use."
:type '(choice (const auto) (const ghci) (const cabal-repl) (const cabal-dev) (const cabal-ghci))
:type '(choice (const auto) (const ghci) (const cabal-repl) (const cabal-dev) (const cabal-ghci)
(const nix-shell-ghci) (const nix-shell-cabal-repl))
:group 'haskell-interactive)

(defcustom haskell-process-log
Expand Down Expand Up @@ -507,7 +521,9 @@ for various things, but is optional."
"Add <cabal-project-dir>/dist/build/autogen/ to the ghci search
path. This allows modules such as 'Path_...', generated by cabal,
to be loaded by ghci."
(unless (eq 'cabal-repl (haskell-process-type)) ;; redundant with "cabal repl"
(unless (or (eq 'cabal-repl haskell-process-type) ;; redundant with "cabal repl"
(eq 'nix-shell-ghci haskell-process-type)
(eq 'nix-shell-cabal-repl haskell-process-type))
(let*
((session (haskell-session))
(cabal-dir (haskell-session-cabal-dir session))
Expand All @@ -519,13 +535,17 @@ to be loaded by ghci."
(defun haskell-process-type ()
"Return `haskell-process-type', or a guess if that variable is 'auto."
(if (eq 'auto haskell-process-type)
(if (locate-dominating-file
default-directory
(lambda (d)
(or (file-directory-p (expand-file-name ".cabal-sandbox" d))
(cl-find-if (lambda (f) (string-match-p "\\.cabal\\'" f)) (directory-files d)))))
'cabal-repl
'ghci)
(let ((nix-shell-found (locate-dominating-file default-directory "shell.nix"))
(cabal-sandbox-found (locate-dominating-file
default-directory
(lambda (d)
(or (file-directory-p (expand-file-name ".cabal-sandbox" d))
(cl-find-if (lambda (f) (string-match-p "\\.cabal\\'" f))
(directory-files d)))))))
(cond ((and cabal-sandbox-found nix-shell-found) 'nix-shell-cabal-repl)
(cabal-sandbox-found 'cabal-repl)
(nix-shell-found 'nix-shell-ghci)
(t 'ghci)))
haskell-process-type))

(defun haskell-process-do-cabal (command)
Expand All @@ -542,13 +562,25 @@ to be loaded by ghci."
(cadr state)
(format haskell-process-do-cabal-format-string
(haskell-session-cabal-dir (car state))
(format "%s %s"
(cl-ecase (haskell-process-type)
(format "%s %s %s"
(cl-ecase haskell-process-type
('ghci haskell-process-path-cabal)
('cabal-repl haskell-process-path-cabal)
('cabal-ghci haskell-process-path-cabal)
('cabal-dev haskell-process-path-cabal-dev))
(cl-caddr state)))))
('cabal-dev haskell-process-path-cabal-dev)
('nix-shell-ghci (concat haskell-process-path-nix-shell
" "
haskell-process-args-nix-shell
" --command '"))
('nix-shell-cabal-repl (concat haskell-process-path-nix-shell
" "
haskell-process-args-nix-shell
" --command '")))
(cl-caddr state)
(cl-case haskell-process-type
('nix-shell-ghci "'")
('nix-shell-cabal-repl "'")
(t ""))))))

:live
(lambda (state buffer)
Expand Down Expand Up @@ -590,7 +622,9 @@ to be loaded by ghci."
('ghci haskell-process-path-cabal)
('cabal-repl haskell-process-path-cabal)
('cabal-ghci haskell-process-path-cabal)
('cabal-dev haskell-process-path-cabal-dev))
('cabal-dev haskell-process-path-cabal-dev)
('nix-shell-ghci haskell-process-path-nix-shell)
('nix-shell-cabal-repl haskell-process-path-nix-shell))
:app-icon haskell-process-logo
)))))))))

Expand Down Expand Up @@ -1017,58 +1051,60 @@ now."
(haskell-process-set-session process session)
(haskell-process-set-cmd process nil)
(haskell-process-set (haskell-session-process session) 'is-restarting nil)
(let ((default-directory (haskell-session-cabal-dir session)))
(haskell-session-pwd session)
(haskell-process-set-process
process
(cl-ecase (haskell-process-type)
('ghci
(haskell-process-log
(propertize (format "Starting inferior GHCi process %s ..."
haskell-process-path-ghci)
'face font-lock-comment-face))
(apply #'start-process
(append (list (haskell-session-name session)
nil
haskell-process-path-ghci)
haskell-process-args-ghci)))
('cabal-repl
(haskell-process-log
(propertize
(format "Starting inferior `cabal repl' process using %s ..."
haskell-process-path-cabal)
'face font-lock-comment-face))

(apply #'start-process
(append (list (haskell-session-name session)
nil
haskell-process-path-cabal)
'("repl") haskell-process-args-cabal-repl
(let ((target (haskell-session-target session)))
(if target (list target) nil)))))
('cabal-ghci
(haskell-process-log
(propertize
(format "Starting inferior cabal-ghci process using %s ..."
haskell-process-path-cabal-ghci)
'face font-lock-comment-face))
(start-process (haskell-session-name session)
nil
haskell-process-path-cabal-ghci))
('cabal-dev
(let ((dir (concat (haskell-session-cabal-dir session)
"/cabal-dev")))
(haskell-process-log
(propertize (format "Starting inferior cabal-dev process %s -s %s ..."
haskell-process-path-cabal-dev
dir)
'face font-lock-comment-face))
(start-process (haskell-session-name session)
nil
haskell-process-path-cabal-dev
"ghci"
"-s"
dir))))))
(let ((default-directory (haskell-session-cabal-dir session))
(targetl (let ((target (haskell-session-target session)))
(if target (list target) nil))))
(cl-flet* ((prog-args (prognm args)
(append (list (haskell-session-name session)
nil
prognm)
args))
(my-start-process (prognm args)
(apply #'start-process (prog-args prognm args)))
(my-log (s)
(haskell-process-log
(propertize s 'face font-lock-comment-face))))
(haskell-session-pwd session)
(haskell-process-set-process
process
(cl-ecase haskell-process-type
('ghci
(my-log (format "Starting inferior GHCi process %s ..."
haskell-process-path-ghci))
(my-start-process haskell-process-path-ghci haskell-process-args-ghci))
('cabal-repl
(my-log (format "Starting inferior `cabal repl' process using %s ..."
haskell-process-path-cabal))

(my-start-process haskell-process-path-cabal
(append '("repl") haskell-process-args-cabal-repl targetl)))
('cabal-ghci
(my-log (format "Starting inferior cabal-ghci process using %s ..."
haskell-process-path-cabal-ghci))
(my-start-process haskell-process-path-cabal-ghci nil))
('cabal-dev
(let ((dir (concat (haskell-session-cabal-dir session)
"/cabal-dev")))
(my-log (format "Starting inferior cabal-dev process %s -s %s ..."
haskell-process-path-cabal-dev
dir))
(my-start-process haskell-process-path-cabal-dev
(list "ghci" "-s" dir))))
('nix-shell-ghci
(let ((args (append haskell-process-args-nix-shell
'("--command")
(list haskell-process-path-ghci)
(let ((target (haskell-session-target session)))
(if target (list target) nil)))))
(my-log (format "Starting inferior nix-shell (ghci) process using %s..."
(mapconcat 'identity args "' '")))
(my-start-process haskell-process-path-nix-shell args)))
('nix-shell-cabal-repl
(let ((args (append haskell-process-args-nix-shell
'("--command" "cabal repl"))))
(my-log (format "Starting inferior nix-shell (cabal repl) process using %s..."
(mapconcat 'identity args "' '")))
(my-start-process haskell-process-path-nix-shell args)))))))
(progn (set-process-sentinel (haskell-process-process process) 'haskell-process-sentinel)
(set-process-filter (haskell-process-process process) 'haskell-process-filter))
(haskell-process-send-startup process)
Expand Down