I've been using Clojure for over 4 years at this point, but it's generally been on projects that are mostly Java with a few small components in Clojure. Given that context my teammates preferred that we stick with IntelliJ; however, things have recently changed and the emacs journey has begun.
Taking emacs from 'factory settings' to 'impressive' for me was as easy as getting started with emacs-live.
Emacs Live can be summarized as:Indeed, Emacs Live does structure your config nicely; however, in it's own words: Emacs Live is also an opinionated set of defaults. I like all of the defaults... except one: rainbow-delimiters
a nice structured approach to organising your Emacs config
modular in that functionality is organised by discrete packs
I get that people like rainbow-delimeters, and I would never try to convince you not to use them - they're just not for me, and I needed to find out how to get rid of them.
Emacs Live adds rainbow-delimiters in two different ways. The following code shows how Emacs Live uses add-hook to enable rainbow delimiters for scheme, emacs-lisp, & lisp.
(dolist (x '(scheme emacs-lisp lisp)) (add-hook (intern (concat (symbol-name x) "-mode-hook")) 'rainbow-delimiters-mode))The code required to remove rainbow-delimiters from scheme, emacs-lisp, & lisp is very straightforward, and can be found below.
(dolist (x '(scheme emacs-lisp lisp)) (remove-hook (intern (concat (symbol-name x) "-mode-hook")) 'rainbow-delimiters-mode))As you can see, replacing add-hook with remove-hook will remove the hook that Emacs Live added for me. Since Emacs Live loads my personal settings last, my remove should successfully work every time. It's a best practice that you create hooks that can be run in any order - and this change is obviously order specific; however, I can't think of a way to follow the hook best practice without hacking the emacs-live checkout. Therefore, it seems like this solution is the most pragmatic.
The next snippet of code is how Emacs Live adds rainbow delimiters (& a few other things) to clojure-mode.
(add-hook 'clojure-mode-hook (lambda () (enable-paredit-mode) (rainbow-delimiters-mode) (add-to-list 'ac-sources 'ac-source-yasnippet) (setq buffer-save-without-query t)))The previous hook was easy to remove, since I knew exactly what function I needed to remove. This hook is more of a problem, since it's anonymous. Additionally, this function is defined within Emacs Live code, so simply changing it to a named function isn't an option (since I don't want to modify the emacs-live checkout).
Finding a solution wasn't very hard. The first thing I did was try to get a list of the functions that will be fired by the hook. This is as simple as printing, as the following code shows.
(print clojure-mode-hook)I put that simple print statement in my .emacs-live.el, restarted emacs, went to the *Messages* buffer, and found the following line printed out.
((lambda nil (enable-paredit-mode) (rainbow-delimiters-mode) (add-to-list (quote ac-sources) (quote ac-source-yasnippet)) (setq buffer-save-without-query t)))As you can see, clojure-mode-hook has a list of the functions that have been added via add-hook. With this information, I added the following code, which first removes the existing hook and then adds a new anonymous function with everything previously specified - sans rainbow-delimiters.
(remove-hook 'clojure-mode-hook (first clojure-mode-hook)) (add-hook 'clojure-mode-hook (lambda () (enable-paredit-mode) (add-to-list 'ac-sources 'ac-source-yasnippet) (setq buffer-save-without-query t)))The above snippet removes my unwanted lambda hook and adds a new hook with everything I do want.
Is this fragile? You bet. If things change in Emacs Live, I'll need to mirror those changes in my .emacs-live.el - which is why it's recommended that you don't rely on ordering when adding and removing hooks. However, given the situation, this seems like a pragmatic solution.
Feedback definitely welcome.