Skip to content

Commit d004bb8

Browse files
committed
Replaces customize var. haskell-compile-ignore-cabal by haskell-compiler-type,
which is similar to haskell-process-type. This makes haskell-compile choose build tools the same way haskell-interactive-mode does. Values are 'cabal, 'cabal-project, 'stack, or 'ghc to choose a build tool, or 'auto (default) to look for stack or cabal files. For haskell-process-type the corresponding values remain 'cabal-repl, 'cabal-new-repl, 'stack-repl, 'ghci. In fact 'cabal-new-repl is obsolete and is accepted as a setting of the defcustom, with a warning, but the accessor function (haskell-process-type) returns 'cabal-repl instead. Factors out logic that deals with value 'auto for both of these, as (haskell-build-type). Also removes a bit of duplicated code from (haskell-process-do-cabal) in haskell-load.el.
1 parent e688ed4 commit d004bb8

File tree

7 files changed

+216
-219
lines changed

7 files changed

+216
-219
lines changed

doc/haskell-mode.texi

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ provided compared to Emacs' basic Compilation mode are:
10791079
@itemize
10801080
@item
10811081
DWIM-style auto-detection of compile command (including support for
1082-
CABAL projects)
1082+
stack and cabal projects)
10831083
@item
10841084
Support for GHC's compile messages and recognizing error, warning and
10851085
info source locations (including @option{-ferror-spans} syntax)
@@ -1106,40 +1106,56 @@ initialization to bind @code{haskell-compile} to @kbd{C-c C-c}.
11061106
The following description assumes that @code{haskell-compile} has been
11071107
bound to @kbd{C-c C-c}.
11081108

1109-
@vindex haskell-compile-cabal-build-command
1110-
@vindex haskell-compile-cabal-build-command-alt
1111-
@vindex haskell-compile-command
1109+
When invoked, @code{haskell-compile} decides what build tool to run by
1110+
consulting the value of @code{haskell-compiler-type}.
11121111

1113-
When invoked, @code{haskell-compile} tries to guess how to compile the
1114-
Haskell program your currently visited buffer belongs to, by searching
1115-
for a @file{.cabal} file in the current of enclosing parent folders. If
1116-
a @file{.cabal} file was found, the command defined in the
1117-
@code{haskell-compile-cabal-build-command} option is used. Note that to
1118-
compile a @code{stack} based project you will need to set this variable to
1119-
@code{stack build}. As usual you can do it using @code{M-x customize-variable}
1120-
or with:
1112+
@itemize
11211113

1122-
@lisp
1123-
(setq haskell-compile-cabal-build-command "stack build")
1124-
@end lisp
1114+
@item
1115+
If this is the symbol @code{cabal}, then @code{cabal} is run, using the
1116+
command defined by @code{haskell-compile-cabal-build-command}.
1117+
@code{haskell-compile} looks for a @file{.cabal} file in the current directory
1118+
or its closet ancestor.
1119+
1120+
@item
1121+
If @code{haskell-compiler-type} is the symbol @code{stack}, then @code{stack}
1122+
is run, using the command @code{haskell-compile-stack-build-command}, and
1123+
looking for the closest @file{stack.yaml} file.
1124+
1125+
@item
1126+
If @code{haskell-compiler-type} is the symbol @code{ghc}, then @code{ghc} is
1127+
run, using the command @code{haskell-compile-command}.
11251128

1126-
Moreover, when requesting to compile a @file{.cabal}-file is detected and
1127-
a negative prefix argument (e.g. @kbd{C-- C-c C-c}) was given, the
1128-
alternative @code{haskell-compile-cabal-build-command-alt} is
1129-
invoked. By default, @code{haskell-compile-cabal-build-command-alt}
1130-
contains a @samp{cabal clean -s} command in order to force a full
1131-
rebuild.
1129+
@item
1130+
But if @code{haskell-compiler-type} is the symbol @code{auto} (the default),
1131+
then emacs tries to choose which build tool to use by looking for the closest
1132+
@file{stack.yaml} or @file{.cabal} file. (This is similar to the way
1133+
@code{haskell-interactive-mode} uses the variable
1134+
@code{haskell-process-type}.)
1135+
@end itemize
1136+
1137+
Moreover, when a negative prefix argument is supplied (e.g. @kbd{C-- C-c C-c}),
1138+
the alternative build command is used, that is,
1139+
@code{haskell-compile-cabal-build-command-alt} or
1140+
@code{haskell-compile-stack-build-command-alt}.
1141+
By default, the alternative build commands force a full rebuild.
1142+
(Note this does not affect @code{haskell-compile-command}.)
11321143

1133-
Otherwise if no @file{.cabal} could be found, a single-module
1134-
compilation is assumed and @code{haskell-compile-command} is used
1135-
(@emph{if} the currently visited buffer contains Haskell source code).
1144+
As usual you can change any of these variables using @code{M-x customize-variable}.
11361145

11371146
You can also inspect and modify the compile command to be invoked
11381147
temporarily by invoking @code{haskell-compile} with a prefix argument
11391148
(e.g. @kbd{C-u C-c C-c}). If later-on you want to recompile using the
11401149
same customized compile command, invoke @code{recompile} (bound to
11411150
@kbd{g}) inside the @samp{*haskell-compilation*} buffer.
11421151

1152+
@vindex haskell-compiler-type
1153+
@vindex haskell-compile-command
1154+
@vindex haskell-compile-stack-build-command
1155+
@vindex haskell-compile-cabal-build-command
1156+
@vindex haskell-compile-stack-build-alt-command
1157+
@vindex haskell-compile-cabal-build-alt-command
1158+
11431159
@section Keybindings
11441160

11451161
@multitable 0.3 0.7
@@ -1275,24 +1291,27 @@ for the current GHCi session.
12751291

12761292
@cindex customizing
12771293
What kind of Haskell REPL @code{haskell-interactive-mode} will start up
1278-
depends on the value of @code{haskell-process-type}. This can be one of the
1279-
symbols @code{auto}, @code{ghci}, @code{cabal-repl}, @code{cabal-new-repl}, or
1280-
@code{stack-ghci}. If it's @code{auto}, the directory contents and available
1281-
programs will be used to make a best guess at the process type. The actual
1282-
process type will then determine which variables
1283-
@code{haskell-interactive-mode} will access to determine the program to start
1284-
and its arguments:
1294+
depends on the value of @code{haskell-process-type}. This can be one of
1295+
the symbols @code{auto}, @code{ghci}, @code{stack-ghci},
1296+
@code{cabal-repl}, or @code{cabal-new-repl}.
1297+
1298+
(@code{cabal-new-repl} is allowed but obsolete, like the cabal command
1299+
@code{new-build} that it selected. Emacs actually runs the equivalent
1300+
cabal command @code{build}.)
1301+
1302+
If it's @code{auto}, the directory contents and available programs will
1303+
be used to make a best guess at the process type. The actual process
1304+
type will then determine which variables @code{haskell-interactive-mode}
1305+
will access to determine the program to start and its arguments:
12851306

12861307
@itemize
12871308
@item
12881309
If it's @code{ghci}, @code{haskell-process-path-ghci} and
12891310
@code{haskell-process-args-ghci} will be used.
12901311
@item
1291-
If it's @code{cabal-repl}, @code{haskell-process-path-cabal} and
1292-
@code{haskell-process-args-cabal-repl}.
1293-
@item
1294-
If it's @code{cabal-new-repl}, @code{haskell-process-path-cabal} and
1295-
@code{haskell-process-args-cabal-new-repl}.
1312+
If it's @code{cabal-repl} or @code{cabal-new-repl},
1313+
@code{haskell-process-path-cabal} and
1314+
@code{haskell-process-args-cabal-repl} are used.
12961315
@item
12971316
If it's @code{stack-ghci}, @code{haskell-process-path-stack} and
12981317
@code{haskell-process-args-stack-ghci} will be used.
@@ -1310,7 +1329,6 @@ strings specifying (further) command-line arguments.
13101329
@vindex haskell-process-path-stack
13111330
@vindex haskell-process-args-ghci
13121331
@vindex haskell-process-args-cabal-repl
1313-
@vindex haskell-process-args-cabal-new-repl
13141332
@vindex haskell-process-args-stack-ghci
13151333

13161334
@section Haskell Interactive Mode Setup
@@ -1398,8 +1416,6 @@ Here is a list of available process types:
13981416
@item ghci
13991417
@item cabal-repl
14001418
@item cabal-new-repl
1401-
@item cabal-dev
1402-
@item cabal-ghci
14031419
@item stack-ghci
14041420
@end itemize
14051421

@@ -2774,14 +2790,14 @@ if the @code{haskell-process-type} is @code{'auto}, the directories are searched
27742790
@code{cabal.sandbox.config} or @code{stack.yaml} or @code{*.cabal} file.
27752791
If the file is present, then appropriate process is started.
27762792

2777-
When @code{cabal.sandbox.config} is found @code{haskell-process-type} is @code{'cabal-repl}.
2793+
When @code{cabal.project} or @code{cabal.sandbox.config} is found,
2794+
@code{haskell-process-type} is @code{'cabal-repl}.
27782795
Similarly, when @code{stack.yaml} is found @code{haskell-process-type} is @code{'stack-ghci}.
27792796
Similarly, when @code{xyz.cabal} is found @code{haskell-process-type} is @code{'cabal-repl}.
27802797
When nothing is found @code{haskell-process-type} is @code{'ghci}. When more than one
27812798
file such as @code{cabal.sandbox.config} and @code{stack.yaml} are found the following
2782-
preference is followed.
2783-
2784-
@code{cabal.sandbox.config} > @code{stack.yaml} > @code{*.cabal}
2799+
preference is followed:
2800+
@code{cabal.project} > @code{stack.yaml} > @code{*.cabal}
27852801

27862802
@node Collapsing Haskell code
27872803
@chapter Collapsing Haskell code

haskell-commands.el

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ You can create new session using function `haskell-session-make'."
9090
(haskell-process-send-startup process)
9191
(unless (memq (haskell-process-type)
9292
;; These all set the proper CWD.
93-
(list 'cabal-repl 'cabal-new-repl 'stack-ghci))
93+
(list 'cabal-repl 'stack-ghci))
9494
(haskell-process-change-dir session
9595
process
9696
(haskell-session-current-dir session)))
@@ -736,8 +736,7 @@ function `xref-find-definitions' after new table was generated."
736736
Add <cabal-project-dir>/dist/build/autogen/ to GHCi seatch path.
737737
This allows modules such as 'Path_...', generated by cabal, to be
738738
loaded by GHCi."
739-
(unless (or (eq 'cabal-repl (haskell-process-type))
740-
(eq 'cabal-new-repl (haskell-process-type))) ;; redundant with "cabal repl"
739+
(unless (eq 'cabal-repl (haskell-process-type))
741740
(let*
742741
((session (haskell-interactive-session))
743742
(cabal-dir (haskell-session-cabal-dir session))

haskell-compile.el

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
;;; haskell-compile.el --- Haskell/GHC compilation sub-mode -*- lexical-binding: t -*-
22

33
;; Copyright (C) 2013 Herbert Valerio Riedel
4+
;; 2020 Marc Berkowitz <[email protected]>
45

56
;; Author: Herbert Valerio Riedel <[email protected]>
67

@@ -28,6 +29,7 @@
2829

2930
(require 'compile)
3031
(require 'haskell-cabal)
32+
(require 'haskell-customize)
3133
(require 'ansi-color)
3234
(eval-when-compile (require 'subr-x))
3335

@@ -67,7 +69,7 @@ For legacy compat, `%s' is replaced by the stack package top folder."
6769

6870
(defcustom haskell-compile-command
6971
"ghc -Wall -ferror-spans -fforce-recomp -c %s"
70-
"Default build command to use for `haskell-cabal-build' when no cabal file is detected.
72+
"Default build command to use for `haskell-cabal-build' when no cabal or stack file is detected.
7173
The `%s' placeholder is replaced by the current buffer's filename."
7274
:group 'haskell-compile
7375
:type 'string)
@@ -78,12 +80,14 @@ The `%s' placeholder is replaced by the current buffer's filename."
7880
:group 'haskell-compile
7981
:type 'boolean)
8082

81-
(defcustom haskell-compile-ignore-cabal nil
82-
"Ignore cabal build definitions files for this buffer when detecting the build tool."
83-
:group 'haskell-compile
84-
:type 'boolean)
85-
(make-variable-buffer-local 'haskell-compile-ignore-cabal)
86-
(put 'haskell-compile-ignore-cabal 'safe-local-variable #'booleanp)
83+
(defcustom haskell-compiler-type
84+
'auto
85+
"Controls whether to use cabal, stack, or ghc to compile.
86+
Auto (the default) means infer from the presence of a cabal or stack spec file,
87+
following same rules as haskell-process-type."
88+
:type '(choice (const auto) (const ghc) (const stack) (const cabal))
89+
:group 'haskell-compile)
90+
(make-variable-buffer-local 'haskell-compiler-type)
8791

8892
(defconst haskell-compilation-error-regexp-alist
8993
`((,(concat
@@ -144,10 +148,7 @@ messages pointing to additional source locations."
144148
;;;###autoload
145149
(defun haskell-compile (&optional edit-command)
146150
"Run a compile command for the current Haskell buffer.
147-
148-
Locates stack or cabal definitions and, if found, invokes the
149-
default build command for that build tool. Cabal is preferred
150-
but may be ignored with `haskell-compile-ignore-cabal'.
151+
Obeys haskell-compiler-type to choose the appropriate build command.
151152
152153
If prefix argument EDIT-COMMAND is non-nil (and not a negative
153154
prefix `-'), prompt for a custom compile command.
@@ -169,28 +170,44 @@ base directory for build tools, or the current buffer for
169170
(interactive "P")
170171
(save-some-buffers (not compilation-ask-about-save)
171172
compilation-save-buffers-predicate)
172-
(let ((cabaldir (and
173-
(not haskell-compile-ignore-cabal)
174-
(or (haskell-cabal-find-dir)
175-
(locate-dominating-file default-directory "cabal.project")
176-
(locate-dominating-file default-directory "cabal.project.local")))))
177-
(if cabaldir
178-
(haskell--compile cabaldir edit-command
179-
'haskell--compile-cabal-last
180-
haskell-compile-cabal-build-command
181-
haskell-compile-cabal-build-alt-command)
182-
(let ((stackdir (and haskell-compile-ignore-cabal
183-
(locate-dominating-file default-directory "stack.yaml"))))
184-
(if stackdir
185-
(haskell--compile stackdir edit-command
186-
'haskell--compile-stack-last
187-
haskell-compile-stack-build-command
188-
haskell-compile-stack-build-alt-command)
189-
(let ((srcfile (buffer-file-name)))
190-
(haskell--compile srcfile edit-command
191-
'haskell--compile-ghc-last
192-
haskell-compile-command
193-
haskell-compile-command)))))))
173+
(let (htype dir)
174+
;;test haskell-compiler-type to set htype and dir
175+
(cond
176+
((eq haskell-compiler-type 'cabal)
177+
(setq htype 'cabal)
178+
(setq dir (haskell-cabal-find-dir)))
179+
((eq haskell-compiler-type 'stack)
180+
(setq htype 'stack)
181+
(setq dir (locate-dominating-file default-directory "stack.yaml")))
182+
((eq haskell-compiler-type 'ghc)
183+
(setq htype 'ghc)
184+
(setq dir (buffer-file-name)))
185+
((eq haskell-compiler-type 'auto)
186+
(let ((r (haskell-build-type)))
187+
(setq htype (car r))
188+
(setq dir (cdr r))))
189+
(t (error "Invalid haskell-compiler-type")))
190+
;; now test htype and compile
191+
(cond
192+
((or (eq htype 'cabal) (eq htype 'cabal-project)) ; run cabal
193+
(let ((command haskell-compile-cabal-build-command)
194+
(alt-command haskell-compile-cabal-build-alt-command))
195+
(when (eq htype 'cabal-project) ;no default target
196+
(setq command (concat command " all")
197+
alt-command (concat alt-command " all")))
198+
(haskell--compile dir edit-command
199+
'haskell--compile-cabal-last
200+
command alt-command)))
201+
((eq htype 'stack)
202+
(haskell--compile dir edit-command
203+
'haskell--compile-stack-last
204+
haskell-compile-stack-build-command
205+
haskell-compile-stack-build-alt-command))
206+
((eq htype 'ghc)
207+
(haskell--compile dir edit-command
208+
'haskell--compile-ghc-last
209+
haskell-compile-command
210+
haskell-compile-command)))))
194211

195212
(defvar haskell--compile-stack-last nil)
196213
(defvar haskell--compile-cabal-last nil)

0 commit comments

Comments
 (0)