-
Notifications
You must be signed in to change notification settings - Fork 69
/
scala-compile.el
120 lines (100 loc) · 4.61 KB
/
scala-compile.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
;;; scala-compile.el --- batch compile scala -*- lexical-binding: t -*-
;; Copyright (C) 2020 Sam Halliday
;; License: GPL 3 or any later version
;;; Commentary:
;;
;; An idiomatic `compilation-mode' batch compilation command that detects
;; warnings and errors, extracting line numbers, columns and ranges.
;;
;; Relies on a batch tool, such as the sbt thin client (`sbt --client`) which
;; can be compiled to native binary (`sbtn`) from their repo with `sbt
;; buildNativeThinClient` or mystery meat binaries downloaded from
;; https://github.com/sbt/sbtn-dist/releases/
;;
;;; Code:
(require 'compile)
(require 'ansi-color)
(require 'files)
(require 'subr-x)
(defcustom scala-compile-always-ask t
"`scala-compile' will always ask for confirmation before running a command unless: the universal argument is provided or it is called with a string argument or if this is set to nil (in which case the last command used in the buffer is used). To change the command, the user must provide a prefix argument."
:type 'booleanp
:group 'scala)
(defcustom scala-compile-suggestion nil
"Files can specify a suggested command to run, e.g. runMain and testOnly."
:type 'stringp
:group 'scala
:safe 'stringp
:local t)
(defcustom scala-compile-alt "sbtn clean && sbtn reload"
"`scala-compile' uses this command when called with the `-' prefix."
:type 'stringp
:group 'scala)
(defvar scala-compilation-error-regexp-alist
'(;; Sbt 1.0.x
("^\\[error][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\):" 1 2 3 2 1)
;; Sbt 0.13.x
("^\\[error][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):" 1 2 nil 2 1)
;; https://github.com/Duhemm/sbt-errors-summary
("^\\[error][[:space:]]\\[E[[:digit:]]+][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\):$" 1 2 3 2 1)
("^\\[warn][[:space:]]+\\[E[[:digit:]]+][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\):$" 1 2 3 1 1)
("^\\[warn][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):" 1 2 nil 1 1)
("^\\[info][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):" 1 2 nil 0 1)
;; failing scalatests
("^\\[info][[:space:]]+\\(.*\\) (\\([^:[:space:]]+\\):\\([[:digit:]]+\\))" 2 3 nil 2 1)
("^\\[warn][[:space:]][[:space:]]\\[[[:digit:]]+][[:space:]]\\([/[:word:]]:?[^:[:space:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\):" 1 2 3 1 1)
)
"The `compilation-error-regexp-alist' for `scala'.")
(defvar scala--compile-history
'("sbtn compile"
"sbtn test"
"sbtn testOnly "))
(defvar-local scala--compile-command nil)
(defvar scala--compile-project "build.sbt")
;;;###autoload
(defun scala-compile (&optional edit-command)
"`compile' specialised to Scala.
First use in a buffer or calling with a prefix will prompt for a
command, otherwise the last command is used.
The command history is global.
A universal argument will invoke `scala-compile-alt', which
will cause the subsequent call to prompt.
A prefix argument will ensure that the user is prompted to
confirm the selection.
A string argument will run the command (for scripting)."
(interactive "P")
(save-some-buffers (not compilation-ask-about-save)
compilation-save-buffers-predicate)
(when scala-compile-suggestion
(add-to-list 'scala--compile-history scala-compile-suggestion))
(let* ((last scala--compile-command)
(command (pcase edit-command
((and 'nil (guard last)) last)
('- scala-compile-alt)
((pred stringp) edit-command)
(_ (read-shell-command
"Compile command: "
(or last (car scala--compile-history))
'(scala--compile-history . 1))))))
(setq scala--compile-command
(unless (or
scala-compile-always-ask
(equal command scala-compile-alt))
command))
(let ((default-directory
(or
(locate-dominating-file default-directory scala--compile-project)
default-directory)))
(compilation-start
command
'scala-compilation-mode
(lambda (_)
(concat "*scala-compilation-" (file-name-nondirectory (directory-file-name default-directory)) "*"))
))))
(defun scala--compile-ansi-color ()
(ansi-color-apply-on-region compilation-filter-start (point-max)))
(define-compilation-mode scala-compilation-mode "scala-compilation"
(add-hook 'compilation-filter-hook
#'scala--compile-ansi-color nil t))
(provide 'scala-compile)
;;; scala-compile.el ends here