├── Ensime.png
├── Movement.png
├── README.md
├── Scrolling.png
├── Spectacle.png
├── cheatsheet.pdf
├── emacs
├── emacs.d.zip
├── emacs2.png
├── emacsclient
├── emacsserver
└── init.el
/Ensime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/Ensime.png
--------------------------------------------------------------------------------
/Movement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/Movement.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | emacs-for-scala
2 | ===============
3 |
4 | My Emacs setup for Scala development, including a fully-configured Ensime.
5 |
6 | ![What does it look like?]
7 | (./emacs2.png)
8 |
9 | This latest version uses MELPA to download packages instead of installing them directly, and excludes a bunch of packages I've experimented with, but that didn't find their way into my day-to-day workflow.
10 |
11 | Intended for use with Emacs for OSX version 24.4 (but likely adapted for other combinations easily enough)
12 |
13 | To install additional packages not included by default on startup:
14 |
15 | Use M-x package-list-packages
16 | Select the package you want and select "install"
17 |
18 | Or edit the .emacs.d/init.el file to taste.
19 |
20 | The first time you run load Emacs, it will download the internet. No, it will only feel that way - it will download all package you don't already have installed from MELPA and install them: this only happens the first time.
21 |
22 | The .emacs.d contained in this repo has a specific set of keybindings set up for Emacs. Mostly these are the defaults from whatever included modules have been used, but in a few cases they've been customized to play well together.
23 |
24 | Please see here for a series of articles describing the Emacs config I've published here.
25 |
26 | By default, the "emacs" launch script here is set up to launch Emacs in GUI mode, using the Emacs for OSX, and not to use client-server mode. If you want to use character-mode, add the param "-nw" to the startup script. This is useful if you want to use Emacs on a remote system, or to use it with Tmux or Screen.
27 |
28 | For faster startup of Emacs, you can do two things: Compile the elisp, or use Emacs in client-server mode.
29 |
30 | For client-server mode, put the scripts 'emacsserver' and 'emacsclient' found in this repo in your path (before any other emacs), and then run "emacs ." - if the server is not running, it will start it, then subsequent launches of emacs will be very quick.
31 |
32 | The scripts are intended for OSX, but again could easily be adapted.
33 |
34 | Other apps
35 | ----------
36 | If your an Emacs user on OSX, you might also want to check out
37 | - the Emacsome add-on for Chrome
38 | - the Amethyst window manager
39 | - Spectacles (a simpler window manager)
40 | - Alfred
41 |
42 | With a bit of work, you can work mostly rodent-free. On OSX the keys map as follows:
43 |
44 | | Abbreviation | OSX Key | Notes |
45 | |--------------|---------|---------|
46 | | M | Option | Meta |
47 | | S | Command | Super |
48 | | C | Control | Control |
49 |
50 |
51 | # Movement Keys
52 |
53 | 
54 |
55 | # Files, Windows, Scrolling Keys
56 |
57 | 
58 |
59 | # Ensime
60 |
61 | 
62 |
63 | # Spectacle
64 |
65 | 
66 |
67 |
68 | -------
69 |
70 | Emacs.d Unplugged
71 | -----------------
72 | There is a file emacs.d.zip that contains a snapshot of a .emacs.d directory with all of the above installed
73 | and configured. In envronments where it is not possible for Emacs to contact melpa and download all the
74 | dependencies directly, you can unzip this file and be up and running immediately - no further downloads should be needed.
75 |
76 |
--------------------------------------------------------------------------------
/Scrolling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/Scrolling.png
--------------------------------------------------------------------------------
/Spectacle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/Spectacle.png
--------------------------------------------------------------------------------
/cheatsheet.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/cheatsheet.pdf
--------------------------------------------------------------------------------
/emacs:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
3 |
4 |
--------------------------------------------------------------------------------
/emacs.d.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/emacs.d.zip
--------------------------------------------------------------------------------
/emacs2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaelpnash/emacs-for-scala/7cd566335068a42eed197c6e0b9df57a84e108c4/emacs2.png
--------------------------------------------------------------------------------
/emacsclient:
--------------------------------------------------------------------------------
1 | SERVERS=`ps -fe | grep Emacs | grep Applications | wc -l`
2 | if [ $SERVERS == 0 ]; then
3 | echo "Server not running - starting up..."
4 | emacsserver
5 | fi
6 | /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -s ~/.emacs.d/server/server $*
7 |
--------------------------------------------------------------------------------
/emacsserver:
--------------------------------------------------------------------------------
1 | SERVERS=`ps -fe | grep Emacs | grep Applications | wc -l`
2 | if [ "$1" == "stop" ]; then
3 | echo "Stopping emacs server..."
4 | /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -nw -s ~/.emacs.d/server/server -e "(kill-emacs)"
5 | else
6 | if [ $SERVERS != 0 ]; then
7 | echo "Server already running"
8 | else
9 | echo "Starting emacs server..."
10 | /Applications/Emacs.app/Contents/MacOS/Emacs --daemon
11 | fi
12 | fi
13 |
--------------------------------------------------------------------------------
/init.el:
--------------------------------------------------------------------------------
1 | (x-focus-frame nil)
2 | (setq mac-command-modifier 'super)
3 |
4 | (global-unset-key (kbd "C-z"))
5 |
6 | ;; Org mode
7 | (require 'org)
8 | (define-key global-map "\C-cl" 'org-store-link)
9 | (define-key global-map "\C-ca" 'org-agenda)
10 | (setq org-log-done t)
11 |
12 | (require 'package)
13 | (add-to-list 'package-archives
14 | '("melpa" . "http://melpa.org/packages/") t)
15 | (when (< emacs-major-version 24)
16 | ;; For important compatibility libraries like cl-lib
17 | (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
18 |
19 | ;; Automatically close brackets/braces - I found this more annoying than helpful
20 | ;; (electric-pair-mode 1)
21 |
22 | ;; List the package we want
23 | (setq package-list '(ensime magit multiple-cursors find-file-in-repository ace-jump-mode yasnippet window-numbering expand-region neotree monokai-theme rainbow-delimiters markdown-mode slime yafolding ido-grid-mode dumb-jump ag))
24 |
25 | (autoload 'findr "findr" "Find file name." t)
26 | (define-key global-map [(meta control S)] 'findr)
27 |
28 | (autoload 'findr-search "findr" "Find text in files." t)
29 | (define-key global-map [(meta control s)] 'findr-search)
30 |
31 | (autoload 'findr-query-replace "findr" "Replace text in files." t)
32 | (define-key global-map [(meta control r)] 'findr-query-replace)
33 |
34 | (package-initialize)
35 |
36 | ;; Fetch list of packages available
37 | (unless package-archive-contents
38 | (package-refresh-contents))
39 |
40 | ;; install the packages that are missing, if any
41 | (dolist (package package-list)
42 | (unless (package-installed-p package)
43 | (package-install package)))
44 |
45 | (require 'ensime)
46 | ;; Start ensime mode whenever we open scala mode, e.g. open a .scala file
47 | (add-hook 'scala-mode-hook 'ensime-scala-mode-hook)
48 | ;; Start ensime with Super-e
49 | (global-set-key (kbd "C-c C-c c") 'ensime)
50 |
51 | ;; Don't show the magit instructions every time
52 | (setq magit-last-seen-setup-instructions "1.4.0")
53 |
54 | (require 'multiple-cursors)
55 | (require 'multiple-cursors)
56 | (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
57 | (global-set-key (kbd "C->") 'mc/mark-next-like-this)
58 | (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
59 | (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
60 |
61 | (custom-set-variables
62 | ;; custom-set-variables was added by Custom.
63 | ;; If you edit it by hand, you could mess it up, so be careful.
64 | ;; Your init file should contain only one such instance.
65 | ;; If there is more than one, they won't work right.
66 | '(custom-safe-themes
67 | (quote
68 | ("fc5fcb6f1f1c1bc01305694c59a1a861b008c534cae8d0e48e4d5e81ad718bc6" default)))
69 | '(org-agenda-files
70 | (quote
71 | ("~/Dropbox/org/business.org" "~/Dropbox/org/personal.org")))
72 | '(org-support-shift-select t)
73 | '(send-mail-function (quote smtpmail-send-it))
74 | '(tool-bar-mode nil))
75 | (custom-set-faces
76 | ;; custom-set-faces was added by Custom.
77 | ;; If you edit it by hand, you could mess it up, so be careful.
78 | ;; Your init file should contain only one such instance.
79 | ;; If there is more than one, they won't work right.
80 | '(default ((((class color) (min-colors 257)) (:foreground "#F8F8F2" :background "#272822")) (((class color) (min-colors 89)) (:foreground "#F5F5F5" :background "#1B1E1C")))))
81 |
82 | (set-face-attribute 'default nil :height 160)
83 |
84 | (setq ensime-sem-high-faces
85 | '(
86 | (implicitConversion nil)
87 | (var . (:foreground "#ff2222"))
88 | (val . (:foreground "#dddddd"))
89 | (varField . (:foreground "#ff3333"))
90 | (valField . (:foreground "#dddddd"))
91 | (functionCall . (:foreground "#dc9157"))
92 | (param . (:foreground "#ffffff"))
93 | (object . (:foreground "#D884E3"))
94 | (class . (:foreground "green"))
95 | (trait . (:foreground "#009933")) ;; "#084EA8"))
96 | (operator . (:foreground "#cc7832"))
97 | (object . (:foreground "#6897bb" :slant italic))
98 | (package . (:foreground "yellow"))
99 | (implicitConversion . (:underline (:style wave :color "blue")))
100 | (implicitParams . (:underline (:style wave :color "blue")))
101 | (deprecated . (:strike-through "#a9b7c6"))
102 | (implicitParams nil)
103 | )
104 | ;; ensime-completion-style 'company
105 | ;; ensime-sem-high-enabled-p nil ;; disable semantic highlighting
106 | ensime-tooltip-hints t ;; disable type-inspecting tooltips
107 | ensime-tooltip-type-hints t ;; disable typeinspecting tooltips
108 | )
109 |
110 | ;; Highlight current line - mostly useful for demos, etc
111 | ;;(set-face-background hl-line-face "gold")
112 |
113 | (require 'find-file-in-repository)
114 |
115 | (global-linum-mode 1)
116 | (global-set-key [f7] 'kill-whole-line)
117 | (global-set-key (kbd "M-s M-m") 'magit-status)
118 | (global-set-key (kbd "M-s M-/") 'comment-or-uncomment-region)
119 | (global-set-key (kbd "C-x C-M-f") 'find-file-in-repository)
120 | (global-set-key (kbd "C-c C-r r") 'ensime-refactor-rename)
121 | (global-set-key (kbd "C-c C-o i") 'ensime-refactor-organize-imports)
122 | (global-set-key (kbd "C-c C-i l") 'ensime-refactor-inline-local)
123 | (global-set-key (kbd "C-c C-t i") 'ensime-inspect-by-path)
124 | (put 'dired-find-alternate-file 'disabled nil)
125 |
126 | ;;Uncomment the below to hide the menu
127 | ;;(menu-bar-mode -1)
128 |
129 | ;; Uncomment below if you want to disable compile on save
130 | ;; (setq ensime-sbt-compile-on-save nil)
131 |
132 | ;; Some general-purpose key bindings
133 | (global-set-key [kp-subtract] 'undo) ; [Undo]
134 | (global-set-key (kbd "S-z") 'undo)
135 | (global-set-key [insert] 'overwrite-mode) ; [Ins]
136 | (global-set-key [kp-insert] 'overwrite-mode) ; [Ins]
137 | (global-set-key (kbd "M-g") 'goto-line) ; [Ctrl]-l]
138 | (global-set-key (kbd "C-L") 'recenter-top-bottom)
139 | (global-set-key [f2] 'split-window-vertically)
140 | (global-set-key [f1] 'remove-split)
141 |
142 | (setq ido-enable-flex-matching t)
143 | (setq ido-everywhere t)
144 | (ido-mode 1)
145 | (setq ido-use-filename-at-point 'guess)
146 | (setq ido-create-new-buffer 'always)
147 | (setq ido-file-extensions-order '(".scala" ".org" ".txt" ".py" ".emacs" ".xml" ".el" ".ini" ".cfg" ".cnf"))
148 |
149 | (require 'ace-jump-mode)
150 | (define-key global-map (kbd "C-c SPC") 'ace-jump-mode)
151 | (autoload
152 | 'ace-jump-mode
153 | "ace-jump-mode"
154 | "Emacs quick move minor mode"
155 | t)
156 | (autoload
157 | 'ace-jump-mode-pop-mark
158 | "ace-jump-mode"
159 | "Ace jump back:-)"
160 | t)
161 |
162 | (define-key global-map (kbd "RET") 'newline-and-indent)
163 |
164 | (defun search-to-brace ()
165 | "Jump to the next open brace"
166 | (interactive)
167 | (search-forward "{"))
168 | (define-key global-map (kbd "M-s {") 'search-to-brace)
169 |
170 | (defun search-to-prev-brace ()
171 | "Jump to the previous brace"
172 | (interactive)
173 | (search-backward "{"))
174 | (define-key global-map (kbd "M-S {") 'search-to-prev-brace)
175 |
176 | (defun search-to-close-brace ()
177 | "Jump to the next close brace"
178 | (interactive)
179 | (search-forward "}"))
180 | (define-key global-map (kbd "M-s }") 'search-to-close-brace)
181 |
182 | (defun search-to-prev-close-brace ()
183 | "Jump to the previous close brace"
184 | (interactive)
185 | (search-backward "}"))
186 | (define-key global-map (kbd "M-S }") 'search-to-prev-brace)
187 |
188 | (defun search-to-next-def ()
189 | "Jump to the next def"
190 | (interactive)
191 | (search-forward "def "))
192 | (define-key global-map (kbd "M-s d") 'search-to-next-def)
193 |
194 | (defun search-to-prev-def ()
195 | "Jump to the previous def"
196 | (interactive)
197 | (search-backward "def "))
198 | (define-key global-map (kbd "M-S d") 'search-to-prev-def)
199 |
200 | (setq-default indent-tabs-mode nil)
201 | (setq-default tab-width 2)
202 | (setq indent-line-function 'insert-tab)
203 |
204 | (define-key global-map (kbd "") 'scala-indent:indent-with-reluctant-strategy)
205 |
206 | ;; Solarized theme
207 | ;; (require 'color-theme)
208 | ;; (require 'color-theme-solarized)
209 | ;;(load-theme 'solarized t)
210 | ;; Use M-x customize-variable frame-background-mode to change
211 | ;;(color-theme-solarized)
212 |
213 | ;; Un-comment below lines for Monokai theme
214 | (require 'monokai-theme)
215 | (load-theme 'monokai t)
216 | (setq frame-background-mode 'dark)
217 |
218 |
219 | ;; Always pick up the most recent file from the filesystem
220 | (global-auto-revert-mode 1)
221 |
222 | (global-set-key (kbd "s-j") 'dired-jump)
223 |
224 | (setq server-socket-dir "~/.emacs.d/server")
225 |
226 | ;; window command shortcuts
227 | (global-set-key (kbd "s-|") 'split-window-horizontally)
228 | (global-set-key (kbd "C-x 9") 'split-window-horizontally)
229 | (global-set-key (kbd "s--") 'split-window-vertically)
230 | (global-set-key (kbd "s-+") 'remove-split)
231 | (global-set-key (kbd "s-") 'enlarge-window)
232 | (global-set-key (kbd "s-") 'shrink-window)
233 | (global-set-key (kbd "s-") 'enlarge-window-horizontally)
234 | (global-set-key (kbd "s-") 'shrink-window-horizontally)
235 | (global-set-key (kbd "M-k") 'kill-whole-line)
236 |
237 | (global-set-key (kbd "s-1") 'ace-jump-line-mode)
238 | (global-set-key (kbd "s-2") 'ace-jump-word-mode)
239 |
240 | (global-set-key (kbd "s-f") 'find-file-in-repository)
241 |
242 | ;; Put temporary and backup files elsewhere
243 | (setq auto-save-file-name-transforms
244 | `((".*" ,(concat user-emacs-directory "auto-save/") t)))
245 | (setq backup-directory-alist
246 | `(("." . ,(expand-file-name
247 | (concat user-emacs-directory "backups")))))
248 | (setq create-lockfiles nil)
249 |
250 | (require 'yasnippet)
251 | (yas-global-mode 1)
252 |
253 | (require 'window-numbering)
254 | (window-numbering-mode 1)
255 |
256 | (require 'expand-region)
257 | (global-set-key (kbd "C-=") 'er/expand-region)
258 |
259 | (defun save-all () (interactive) (save-some-buffers t))
260 | (global-set-key (kbd "S-s") 'save-all)
261 |
262 | (global-set-key (kbd "s-R") 'ensime-inf-eval-buffer)
263 | (global-set-key (kbd "s-r") 'ensime-inf-eval-region)
264 |
265 | (require 'neotree)
266 | (global-set-key (kbd "s-d") 'neotree-toggle)
267 | ;;uncomment to have a neotree window open initially
268 | ;;(neotree)
269 |
270 | (require 'whitespace)
271 | (setq whitespace-line-column 120)
272 | (setq whitespace-style '(face lines-tail))
273 | (global-whitespace-mode +1)
274 |
275 | (setq show-paren-delay 0)
276 | (setq blink-matching-paren 1)
277 | (show-paren-mode 1)
278 |
279 | (defun bf-pretty-print-xml-region (begin end)
280 | "Pretty format XML markup in region. You need to have nxml-mode
281 | http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
282 | this. The function inserts linebreaks to separate tags that have
283 | nothing but whitespace between them. It then indents the markup
284 | by using nxml's indentation rules."
285 | (interactive "r")
286 | (save-excursion
287 | (nxml-mode)
288 | (goto-char begin)
289 | (while (search-forward-regexp "\>[ \\t]*\<" nil t)
290 | (backward-char) (insert "\n"))
291 | (indent-region begin end))
292 | (message "Ah, much better!"))
293 |
294 | (require 'rainbow-delimiters)
295 | (add-hook 'scala-mode-hook #'rainbow-delimiters-mode)
296 | (add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode)
297 |
298 | ;; Save on focus-out
299 | (defun save-all ()
300 | (interactive)
301 | (save-some-buffers t))
302 | (add-hook 'focus-out-hook 'save-all)
303 |
304 | (set-frame-font "Source Code Pro-18" nil t)
305 |
306 | ;; Exit emacs w/o prompts
307 | (require 'cl)
308 | (defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
309 | (flet ((process-list ())) ad-do-it))
310 |
311 | (add-hook 'markdown-mode-hook (lambda () (electric-indent-local-mode -1)))
312 |
313 | ;; Control and mouse-wheel-up to increase font size in buffer, down to decrease
314 | (global-set-key [C-wheel-up] '(lambda () (interactive) (text-scale-increase 1)))
315 | (global-set-key [C-wheel-down] '(lambda () (interactive) (text-scale-decrease 1)))
316 |
317 | ;; Super wheel-up to increase font size in all buffers
318 | (defun change-font-height (delta)
319 | (set-face-attribute 'default
320 | (selected-frame)
321 | :height (+ (face-attribute 'default :height) delta)))
322 | (global-set-key [M-wheel-up] '(lambda () (interactive) (change-font-height +4)))
323 | (global-set-key [M-wheel-down] '(lambda () (interactive) (change-font-height -4)))
324 |
325 | (setq inferior-lisp-program "/usr/local/bin/sbcl")
326 |
327 | ;; Turn on yafolding-mode for scala files
328 | (add-hook 'prog-mode-hook
329 | (lambda () (yafolding-mode)))
330 | ;; Uncomment below to start with all elements folded
331 | ;; (add-hook 'scala-mode-hook
332 | ;; (lambda () (yafolding-mode) (yafolding-toggle-all)))
333 |
334 |
335 | (defun jump-to-test ()
336 | "Jump to correspnding test file"
337 | (interactive)
338 | (find-file-other-window (format "%s%sTest.scala" (replace-regexp-in-string "app\/" "test\/" (file-name-directory buffer-file-name)) (file-name-nondirectory (file-name-sans-extension buffer-file-name)))))
339 |
340 | (global-set-key (kbd "s-T") 'jump-to-test)
341 |
342 | (ido-grid-mode 1)
343 |
344 | (global-set-key (kbd "s-b") 'ido-display-buffer)
345 |
346 |
--------------------------------------------------------------------------------