This repository has been archived by the owner on Mar 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clojure-mode-ext.el
141 lines (113 loc) · 4.81 KB
/
clojure-mode-ext.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
;;; Emacs clojure-mode extensions
;;; This file assumes that the clojure-mode, and slime packages are in
;;; the load-path, either added manually or via the packages
;;; system. For more info see:
;;;
;;; https://github.com/technomancy/clojure-mode/blob/master/README.md
;;;
;;; Basic initialization
(defun cljx/customize-indent-settings (indent-function settings)
"Apply the SETTINGS a-list as overrides to the specified
INDENT-FUNCTION. e.g.,
(cljx/customize-indent-settings 'clojure-indent-function '((are . let)))
will format `are` forms inside of a `deftest` similar to `let`.
"
(dolist (x settings)
(put (car x)
indent-function
(if (numberp (cdr x))
(cdr x)
(get (cdr x) indent-function)))))
(defun cljx/basic-init ()
(setq-default indent-tabs-mode nil ; no tabs, only spaces
;; Ensure all files end with a newline, works around github's
;; complaint about "No newline at end"
require-final-newline t))
(require 'cc-mode) ; load java-mode
;;; :::::::::::::::: SLIME setup
(require 'slime)
;;; Stop SLIME from pestering about version mismatches
(setq slime-protocol-version 'ignore)
(defcustom cljx/enable-slime-compile-hacks t
"Enable clear/reload behavior when recompiling Clojure
buffers."
:type 'boolean
:group 'cljx-settings)
(defun cljx/slime-compile-file (&optional arg)
"Replacement for the default slime-compile-and-load-file, which
accepts an optional prefix ARG, which when specified clears the
current Clojure namespace using (remove-ns ...) and forces a
recompile.
Keybinding to force a clear and recompile: C-u C-c C-k"
(interactive "P")
(let ((package (slime-current-package)))
(if (and package arg)
(slime-eval-async `(swank:interactive-eval
,(format "(remove-ns '%s)" package))
(lambda (result)
(slime-compile-and-load-file)))
(slime-compile-and-load-file))))
(defun cljx/subst-chars-in-string (str charmap)
(let ((re (concat "[" (mapconcat 'car charmap "") "]")))
(replace-regexp-in-string re (lambda (m) (cdr (assoc m charmap))) str)))
(defun cljx/lisp-symbol-to-java (symbol)
(cljx/subst-chars-in-string symbol '(("-" . "_") ("/" . "."))))
(defun cljx/slime-edit-definition (name &optional where)
"Replacement for default slime-edit-definition, which falls
back to find-tag if slime-edit-definition fails to find
anything (for example, a definition in a Java class)."
(interactive (list (slime-read-symbol-name "Edit Definition of: ")))
(let (r)
(unwind-protect
(setq r (slime-edit-definition name where))
(unless r
(let ((java-name (cljx/lisp-symbol-to-java name)))
(find-tag java-name))))))
;;; :::::::::::::::: Clojure mode setup
(require 'clojure-mode)
(require 'clojure-test-mode)
(require 'eldoc)
(defun cljx/customize-font-lock ()
;; The following is a template for setting up custom font-lock
;; (syntax highlight)
(setq clojure-font-lock-keywords (append
'(("\\(defn-cond\\)[ \r\n\t]*\\(\\sw+\\)?"
(1 font-lock-keyword-face)
(2 font-lock-function-name-face nil t)))
clojure-font-lock-keywords)))
(defun cljx/slime-mode-hook ()
(when cljx/enable-slime-compile-hacks
(define-key slime-mode-map "\C-c\C-k" 'cljx/slime-compile-file))
(define-key slime-mode-map "\C-\M-i" 'slime-complete-symbol)
(define-key slime-mode-map "\M-." 'cljx/slime-edit-definition)
(define-key slime-mode-map "\C-c." 'cljx/slime-edit-definition)
(define-key slime-mode-map "\C-c^" 'slime-pop-find-definition-stack))
(add-hook 'slime-mode-hook 'cljx/slime-mode-hook)
(defun cljx/clojure-mode-hook ()
;; configure special indentation rules for some keywords
(cljx/customize-indent-settings 'clojure-indent-function
'((are . let)))
(setq clojure-mode-use-backtracking-indent t
clojure-mode-font-lock-comment-sexp t)
(slime-mode 1)
(define-key java-mode-map "\C-c." 'cljx/slime-edit-definition)
(define-key java-mode-map "\C-c^" 'slime-pop-find-definition-stack)
(eldoc-mode)
(clojure-test-mode))
(add-hook 'clojure-mode-hook 'cljx/clojure-mode-hook)
;;; :::::::::::::::: Compilation mode setup
(require 'compile)
;;; Help compilation-mode track error locations for use with (C-x `)
(setq compilation-error-regexp-alist
(append
(list
;; works for jikes
'("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):\\([0-9]+\\):[0-9]+:[0-9]+:"
1 2 3)
;; works for javac
'("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):" 1 2)
;; clojure.test
'("^FAIL in (.*) (\\([^:]*\\):\\([0-9]+\\)" 1 2)
'("^ERROR in (.*) (\\([^:]*\\):\\([0-9]+\\)" 1 2))
compilation-error-regexp-alist))
(provide 'clojure-mode-ext)