Skip to content

Commit 3f6e21d

Browse files
committed
Towards a customizable haskell-mode
From: haskell#350 (comment)
1 parent 1aa06b2 commit 3f6e21d

File tree

1 file changed

+117
-49
lines changed

1 file changed

+117
-49
lines changed

haskell-process.el

Lines changed: 117 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -119,32 +119,62 @@ Docker users may want to use something like \"run-my-docker\"."
119119
:group 'haskell-interactive
120120
:type '(choice string (repeat string)))
121121

122-
(defun haskell-process-wrapper-command (cmd)
122+
(defun haskell-process--stringify-cmd (cmd &optional args)
123+
"Stringify the CMD with optional ARGS."
124+
(format "%s" (s-join " " (cons cmd args))))
125+
126+
(require 'ert)
127+
(ert-deftest haskell-process-stringify-cmd-no-arg ()
128+
"No wrapper, return directly the command (between string quote)."
129+
(should (equal "\"run\""
130+
(let ((haskell-process-wrapper nil))
131+
(haskell-process--stringify-cmd "run")))))
132+
(ert-deftest haskell-process-stringify-cmd-with-args ()
133+
"No wrapper, return directly the command."
134+
(should (equal "\"run -a b -c d\""
135+
(let ((haskell-process-wrapper nil))
136+
(haskell-process--stringify-cmd "run" '("-a" "b" "-c" "d"))))))
137+
138+
(defun haskell-process-wrapper-command (cmd &optional cmd-args)
123139
"Compute the haskell command to execute to launch the haskell-process type.
124-
if haskell-process-wrapper is set, return a wrapper of the CMD.
125-
Otherwise, return CMD."
140+
if haskell-process-wrapper is set, return a wrapper of the CMD as list.
141+
Otherwise, return CMD as list.
142+
Deal with optional CMD-ARGS for the CMD."
126143
(require 's)
127144
(if haskell-process-wrapper
128-
(if (stringp haskell-process-wrapper)
129-
(format "%s \"%s\"" haskell-process-wrapper (shell-quote-argument cmd))
130-
(s-join " " (append haskell-process-wrapper (list (format "\"%s\"" (shell-quote-argument cmd))))))
131-
cmd))
145+
(let ((wrapped-cmd (haskell-process--stringify-cmd cmd cmd-args)))
146+
(if (stringp haskell-process-wrapper)
147+
(list haskell-process-wrapper wrapped-cmd)
148+
(append haskell-process-wrapper (list wrapped-cmd))))
149+
(cons cmd cmd-args)))
132150

133-
(require 'ert)
134151
(ert-deftest haskell-process-wrapper-command-nil ()
135152
"No wrapper, return directly the command."
136-
(custom-set-variables '(haskell-process-wrapper nil))
137-
(should (equal "ghci" (haskell-process-wrapper-command "ghci"))))
153+
(should (equal '("ghci")
154+
(let ((haskell-process-wrapper nil))
155+
(haskell-process-wrapper-command "ghci")))))
138156
(ert-deftest haskell-process-wrapper-command-with-string ()
139157
"Wrapper as a string, return the wrapping command as a string."
140-
(custom-set-variables '(haskell-process-wrapper "nix-shell shell.nix --command"))
141-
(should (equal "nix-shell shell.nix --command \"cabal\\ run\"" (haskell-process-wrapper-command "cabal run"))))
158+
(should (equal '("nix-shell" "\"cabal run\"")
159+
(let ((haskell-process-wrapper "nix-shell"))
160+
(haskell-process-wrapper-command "cabal run")))))
161+
(ert-deftest haskell-process-wrapper-command-with-string-2 ()
162+
"Wrapper as a string, return the wrapping command as a string."
163+
(should (equal '("nix-shell" "\"cabal run\"")
164+
(let ((haskell-process-wrapper "nix-shell"))
165+
(haskell-process-wrapper-command "cabal" '("run"))))))
142166
(ert-deftest haskell-process-wrapper-command-with-repeat-string ()
143167
"Wrapper as a list of string, return the wrapping command as a string."
144-
(custom-set-variables '(haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
145-
(should (equal "nix-shell default.nix --command \"cabal\\ build\"" (haskell-process-wrapper-command "cabal build"))))
168+
(should (equal '("nix-shell" "default.nix" "--command" "\"cabal build\"")
169+
(let ((haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
170+
(haskell-process-wrapper-command "cabal" '("build"))))))
146171

147-
(custom-set-variables '(haskell-process-wrapper '("nix-shell" "haskell-lab.nix" "--command")))
172+
;; (custom-set-variables '(haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
173+
;; (custom-set-variables '(haskell-process-wrapper nil))
174+
;; (custom-set-variables '(haskell-process-type 'cabal-repl))
175+
;; (custom-set-variables '(haskell-process-type 'cabal-ghci))
176+
;; (custom-set-variables '(haskell-process-type 'ghci))
177+
;; (custom-set-variables '(haskell-process-type 'cabal-dev))
148178

149179
(defcustom haskell-process-log
150180
nil
@@ -1049,68 +1079,104 @@ from `module-buffer'."
10491079
"Compute the log and process to start command for the SESSION from the HPTYPE.
10501080
Do not actually start any process.
10511081
HPTYPE is the result of calling `'haskell-process-type`' function."
1052-
(cl-ecase hptype
1053-
('ghci
1054-
(cons (format "Starting inferior GHCi process %s ..." haskell-process-path-ghci)
1055-
(append (list (haskell-session-name session)
1056-
nil
1057-
haskell-process-path-ghci)
1058-
haskell-process-args-ghci)))
1059-
('cabal-repl
1060-
(cons (format "Starting inferior `cabal repl' process using %s ..." haskell-process-path-cabal)
1061-
(append (list (haskell-session-name session)
1062-
nil
1063-
haskell-process-path-cabal)
1064-
'("repl") haskell-process-args-cabal-repl
1065-
(let ((target (haskell-session-target session)))
1066-
(if target (list target) nil)))))
1067-
('cabal-ghci
1068-
(list (format "Starting inferior cabal-ghci process using %s ..." haskell-process-path-cabal-ghci)
1069-
(haskell-session-name session)
1070-
nil
1071-
haskell-process-path-cabal-ghci))
1072-
('cabal-dev
1073-
(let ((dir (concat (haskell-session-cabal-dir session) "/cabal-dev")))
1074-
(list (format "Starting inferior cabal-dev process %s -s %s ..." haskell-process-path-cabal-dev dir)
1075-
(haskell-session-name session)
1076-
nil
1077-
haskell-process-path-cabal-dev
1078-
"ghci"
1079-
"-s"
1080-
dir)))))
1082+
(let ((session-name (haskell-session-name session)))
1083+
(cl-ecase hptype
1084+
('ghci
1085+
(append (list (format "Starting inferior GHCi process %s ..." haskell-process-path-ghci)
1086+
session-name
1087+
nil)
1088+
(haskell-process-wrapper-command haskell-process-path-ghci haskell-process-args-ghci)))
1089+
('cabal-repl
1090+
(append (list (format "Starting inferior `cabal repl' process using %s ..." haskell-process-path-cabal)
1091+
session-name
1092+
nil)
1093+
(haskell-process-wrapper-command haskell-process-path-cabal (cons "repl" haskell-process-args-cabal-repl))
1094+
(let ((target (haskell-session-target session)))
1095+
(if target (list target) nil))))
1096+
('cabal-ghci
1097+
(append (list (format "Starting inferior cabal-ghci process using %s ..." haskell-process-path-cabal-ghci)
1098+
session-name
1099+
nil)
1100+
(haskell-process-wrapper-command haskell-process-path-cabal-ghci)))
1101+
('cabal-dev
1102+
(let ((dir (concat (haskell-session-cabal-dir session) "/cabal-dev")))
1103+
(append (list (format "Starting inferior cabal-dev process %s -s %s ..." haskell-process-path-cabal-dev dir)
1104+
session-name
1105+
nil)
1106+
(haskell-process-wrapper-command haskell-process-path-cabal-dev (list "ghci" "-s" dir))))))))
10811107

10821108
(require 'ert)
10831109
(require 'el-mock)
10841110

10851111
(ert-deftest test-haskell-process--compute-process-log-and-command-ghci ()
10861112
(should (equal '("Starting inferior GHCi process ghci ..." "dumses1" nil "ghci" "-ferror-spans")
10871113
(let ((haskell-process-path-ghci "ghci")
1088-
(haskell-process-args-ghci '("-ferror-spans")))
1114+
(haskell-process-args-ghci '("-ferror-spans"))
1115+
(haskell-process-wrapper nil))
1116+
(with-mock
1117+
(mock (haskell-session-name "dummy-session") => "dumses1")
1118+
(haskell-process--compute-process-log-and-command "dummy-session" 'ghci))))))
1119+
1120+
(ert-deftest test-haskell-process--with-wrapper-compute-process-log-and-command-ghci ()
1121+
(should (equal '("Starting inferior GHCi process ghci ..." "dumses1" nil "nix-shell" "default.nix" "--command" "\"ghci -ferror-spans\"")
1122+
(let ((haskell-process-path-ghci "ghci")
1123+
(haskell-process-args-ghci '("-ferror-spans"))
1124+
(haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
10891125
(with-mock
10901126
(mock (haskell-session-name "dummy-session") => "dumses1")
10911127
(haskell-process--compute-process-log-and-command "dummy-session" 'ghci))))))
10921128

10931129
(ert-deftest test-haskell-process--compute-process-log-and-command-cabal-repl ()
10941130
(should (equal '("Starting inferior `cabal repl' process using cabal ..." "dumses2" nil "cabal" "repl" "--ghc-option=-ferror-spans" "dumdum-session")
10951131
(let ((haskell-process-path-cabal "cabal")
1096-
(haskell-process-args-cabal-repl '("--ghc-option=-ferror-spans")))
1132+
(haskell-process-args-cabal-repl '("--ghc-option=-ferror-spans"))
1133+
(haskell-process-wrapper nil))
1134+
(with-mock
1135+
(mock (haskell-session-name "dummy-session2") => "dumses2")
1136+
(mock (haskell-session-target "dummy-session2") => "dumdum-session")
1137+
(haskell-process--compute-process-log-and-command "dummy-session2" 'cabal-repl))))))
1138+
1139+
(ert-deftest test-haskell-process--with-wrapper-compute-process-log-and-command-cabal-repl ()
1140+
(should (equal '("Starting inferior `cabal repl' process using cabal ..." "dumses2" nil "nix-shell" "default.nix" "--command" "\"cabal repl --ghc-option=-ferror-spans\"" "dumdum-session")
1141+
(let ((haskell-process-path-cabal "cabal")
1142+
(haskell-process-args-cabal-repl '("--ghc-option=-ferror-spans"))
1143+
(haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
10971144
(with-mock
10981145
(mock (haskell-session-name "dummy-session2") => "dumses2")
10991146
(mock (haskell-session-target "dummy-session2") => "dumdum-session")
11001147
(haskell-process--compute-process-log-and-command "dummy-session2" 'cabal-repl))))))
11011148

11021149
(ert-deftest test-haskell-process--compute-process-log-and-command-cabal-ghci ()
11031150
(should (equal '("Starting inferior cabal-ghci process using cabal-ghci ..." "dumses3" nil "cabal-ghci")
1104-
(let ((haskell-process-path-ghci "ghci"))
1151+
(let ((haskell-process-path-ghci "ghci")
1152+
(haskell-process-wrapper nil))
1153+
(with-mock
1154+
(mock (haskell-session-name "dummy-session3") => "dumses3")
1155+
(haskell-process--compute-process-log-and-command "dummy-session3" 'cabal-ghci))))))
1156+
1157+
(ert-deftest test-haskell-process--with-wrapper-compute-process-log-and-command-cabal-ghci ()
1158+
(should (equal '("Starting inferior cabal-ghci process using cabal-ghci ..." "dumses3" nil "nix-shell" "default.nix" "--command" "\"cabal-ghci\"")
1159+
(let ((haskell-process-path-ghci "ghci")
1160+
(haskell-process-wrapper '("nix-shell" "default.nix" "--command")))
11051161
(with-mock
11061162
(mock (haskell-session-name "dummy-session3") => "dumses3")
11071163
(haskell-process--compute-process-log-and-command "dummy-session3" 'cabal-ghci))))))
11081164

11091165
(ert-deftest test-haskell-process--compute-process-log-and-command-cabal-dev ()
11101166
(should (equal '("Starting inferior cabal-dev process cabal-dev -s directory/cabal-dev ..." "dumses4" nil "cabal-dev" "ghci" "-s" "directory/cabal-dev")
1111-
(let ((haskell-process-path-cabal-dev "cabal-dev"))
1167+
(let ((haskell-process-path-cabal-dev "cabal-dev")
1168+
(haskell-process-wrapper nil))
1169+
(with-mock
1170+
(mock (haskell-session-name "dummy-session4") => "dumses4")
1171+
(mock (haskell-session-cabal-dir "dummy-session4") => "directory")
1172+
(haskell-process--compute-process-log-and-command "dummy-session4" 'cabal-dev))))))
1173+
1174+
(ert-deftest test-haskell-process--with-wrapper-compute-process-log-and-command-cabal-dev ()
1175+
(should (equal '("Starting inferior cabal-dev process cabal-dev -s directory/cabal-dev ..." "dumses4" nil "run-with-docker" "\"cabal-dev ghci -s directory/cabal-dev\"")
1176+
(let ((haskell-process-path-cabal-dev "cabal-dev")
1177+
(haskell-process-wrapper "run-with-docker"))
11121178
(with-mock
1113-
(mock (haskell-session-name "dummy-session4") => "dumses4")
1179+
(mock (haskell-session-name "dummy-session4") => "dumses4")
11141180
(mock (haskell-session-cabal-dir "dummy-session4") => "directory")
11151181
(haskell-process--compute-process-log-and-command "dummy-session4" 'cabal-dev))))))
11161182

@@ -1130,6 +1196,8 @@ HPTYPE is the result of calling `'haskell-process-type`' function."
11301196
(haskell-process-set-session process session)
11311197
(haskell-process-set-cmd process nil)
11321198
(haskell-process-set (haskell-session-process session) 'is-restarting nil)
1199+
;; (when haskell-process-wrapper
1200+
;; (setq default-directory (haskell-session-current-dir session)))
11331201
(let ((default-directory (haskell-session-cabal-dir session))
11341202
(log-and-process-to-start (haskell-process--compute-process-log-and-command session (haskell-process-type))))
11351203
(haskell-session-pwd session)

0 commit comments

Comments
 (0)