Archive for June, 2010

SLIME hints #4 – slime-who-calls

Wednesday, June 9th, 2010

This is part of the series on SLIME functions. See the introduction for information on what SLIME is.

Just a short post today.

The slime-who-calls function (default binding “C-c C-w c”) lists every function that calls the given function (default argument is the symbol under the cursor). You can press ENTER on that list to go to the listed definition. Beats using M-x rgrep for convenience, but – at least with Clojure code – it doesn’t catch every call; second-order function calls aren’t caught.

For those readers using Clojure, you need a pretty recent version of swank-clojure for this to work – and it seems to also list function definitions with the same name as the argument, which I think isn’t correct.

SLIME hints #3b – lexical completions, also: a correction

Friday, June 4th, 2010

New code!

As I noted in yesterday’s post, slime-complete-symbol normally doesn’t complete locally bound “variables” (that is, function arguments and let bindings).

I’ve created a SLIME extension that does a pretty rough scan of the current top-level form and adds all the matching symbols in the form into the list of suggested completions. If you want to check it out, slime-complete-locals is available on github.

A correction

Also, if you missed the update on yesterday’s post, make sure you add the right forms to smart-tab-completion-functions-alist – the key in that alist should be the MAJOR mode. So using slime-mode (like I did yesterday) will not work. It must be clojure-mode or whatever the major mode for your lisp editing is.

SLIME hints #3 – interactive completions and smart tabs

Thursday, June 3rd, 2010

This is part of the series on SLIME functions. See the introduction for information on what SLIME is.

Today I want to address auto-completion. There are many different Emacs extensions for doing completions, but the basic functionality in SLIME is provided by the function slime-complete-symbol, which takes the symbol under the cursor and expands it, using whatever symbols are reachable at that point in the code1]. The way I have it set up is a bit tricky, though, so here’s how it works:

I really prefer expansions to be bound to the TAB key. But the TAB key is also used to indent code. It’s possible to have it “do what I mean”, and the easiest method I found for that is to use Smart Tabs (see also the github repo).

Smart tab determines the expansion function to use based on the major mode of the current buffer*. So I’ve got the following in my configuration:

(require 'smart-tab) ;; make sure smart-tab.el is reachable in your load-path first
(global-smart-tab-mode 1) ;; switch on smart-tab everywhere

(setq smart-tab-completion-functions-alist 
      '((emacs-lisp-mode . lisp-complete-symbol) 
        (text-mode . dabbrev-completion) ;; this is the "default" emacs expansion function
        (clojure-mode . slime-complete-symbol))) ;; see update below

Now, whenever I press TAB and the cursor is at the end of a symbol, it gets expanded. If I press TAB on any other place, that indents that line.

There’s a lot of stuff you can customize with expansions and auto completion, but this will give you the basics quickly and without too much hassle.

1] For Clojure code, at least, this boils down to; every symbol that is defined (or imported etc) in the current name space. This has two consequences:

  • It only applies to code that has already been loaded into the program, so you will want to compile stuff pretty much immediately once you’ve written or modified it.
  • It does not expand let bindings or function arguments, since those are lexically scoped and cannot be retrieved from the name space. There is probably a way to fix this, but I haven’t looked into the problem that far.

* Update: the smart tab configuration must be keyed off the MAJOR mode. So slime-mode . slime-complete-symbol will not work, since slime-mode isn’t a major mode. I replaced it here with clojure-mode.