Friday, March 14

Emacs Selectors

One of the nicer things that comes with slime is the slime-selector: it's just a little buffer switching thing, that lets you press r to switch to the repl buffer, d to switch to the debugger buffer, s to switch to the scratch buffer and so forth. Bound to a function key, it's an extraordinarily convenient way of switching to a specific buffer.

Of course, it's geared to SLIME and Lisp, but when coding C++ on the day job I often find myself switching between code, the debugger, shell and compilation buffer, so without further ado, here is the C equivalent, which is easily hacked up to include other buffers, too: actually, I'm beginning to think something like this functionality should be in emacs by default, as it eliminates a lot of keyboard gymnastics.

;; slime selector clone for c ----------------------------------

(defvar c-selector-methods nil)

(defun c-selector ()
(message "Select [%s]: "
(apply #'string (mapcar #'car c-selector-methods)))
(let* ((ch (save-window-excursion
(select-window (minibuffer-window))
(method (find ch c-selector-methods :key #'car)))
(cond ((null method)
(message (format "No method for charachter: %s" ch))
(sleep-for 1)
(funcall (third method))))))

(defmacro def-c-selector-method (key description &rest body)
`(setq c-selector-methods
(sort* (cons (list ,key ,description
(lambda ()
(let ((buffer (progn ,@body)))
(cond ((get-buffer buffer)
(switch-to-buffer buffer))
(message "No such buffer")
(remove* ,key c-selector-methods :key #'car))
#'< :key #'car)))

(def-c-selector-method ?d "GDB debugger buffer"

(def-c-selector-method ?g "Grep buffer"

(def-c-selector-method ?l "Buffer List"
(let ((result (get-buffer "*buffer-selection*")))
(if result
(get-buffer "*buffer-selection*")))))

(def-c-selector-method ?c "Compilation buffer"
(let ((result (get-buffer "*compilation*")))
(if result

(def-c-selector-method ?s "Shell buffer"
(get-buffer "*shell*"))

1 comment:

Anonymous said...

btw, (bs-show) was giving me trouble as it expects a prefix parameter. I changed it to (bs-show "") and works correct.