I’ve been writing a lot of lisp recently, both to extend my Emacs environment for OWL (http://www.russet.org.uk/blog/2161), and with my Clojure OWL library (http://www.russet.org.uk/blog/2254). I have been trying out two new modes to support this. The first is paredit.el which I have managed to miss despite knocking out Lisp for years; it’s a work of insane genius; fantastic when it does the right thing, but sometimes I find myself stuck in a rut. This will probably improve over time, but is only going to work when I am writing a lot of lisp.

My initial solution to this problem was to use the paredit cheat sheet. This is good but unfortunately does not scale as it is only available as an image. I was a bit surprised to find that this cheat sheet is actually build on information that is embedded in the paredit source. Paredit uses this for generating help strings. This also makes it possible to generate a menu with examples as tooltips, which I have now done with paredit-menu.el. Code is available on http://code.google.com/p/phillord-emacs-packages/

My second problem was with show-paren mode. This is very useful for lisp, but I find it irritating in other modes. This is particularly the case because of my own pabbrev.el. This offers abbreviation expansions using sq[uare] brackets; even though this are transitory show-paren highlights which produces a rather annoying flickering on screen. Unfortunately, there is no way of blocking this — adding an overlay which blocks show-paren would be the ideal solution. Worse, show-paren, even though it is a minor mode is global; once it is on, it is on in every buffer. Really, it needs rewriting so that it can be switched on and off on a per-module basis.

My solution to this is to switch the minor mode on and off depending on the current mode. This isn’t worth turning into a package (since it’s a hack), but I put it up here in case anyone finds it useful.

;; show-paren-mode is a minor mode, but it's automatically global. Annoying.
(defun phil-show-paren-mode-check()
  ;; it isn't and it should be
  (when (and (phil-paren-mode-should-be-active-p)
             (not show-paren-mode))
    (show-paren-mode 1))
  ;; it is and it shouldn't be
  (when (and (not (phil-paren-mode-should-be-active-p))
             show-paren-mode)
    (show-paren-mode 0)))

(add-hook 'post-command-hook
          'phil-show-paren-mode-check)

(defun phil-paren-mode-should-be-active-p()
  (memq major-mode phil-paren-mode-active))

(defvar phil-paren-mode-active
  '(clojure-mode emacs-lisp-mode))

Bibliography

Leave a Reply