TextMate: Erlang code-completion (PART 1)

I have been working towards building full-fledged code-completion features for Erlang in TextMate. The result will be a set of Erlang modules that will be generally capable of this in isolation of TextMate. However, certain features of TextMate — such as scopes and scriptability — make it an ideal candidate for testing the concept. It also doesn't hurt that I really like TextMate and that it is my editor of choice. It is my express intention to eschew any approach that would bar the incorporation of these modules into code-completion for open source IDEs like Emacs, Eclipse, or NetBeans. If I complete this project I will be more than happy to assist in such efforts.

At the endpoint it is intended that the modules will support the following:

  • type-ahead module name completion
  • type-ahead local and imported function name completion
  • type-ahead external function name completion (based on module-prefix)
  • type-ahead variable name completion

Erlang Command Server

I quickly discovered that launching Erlang upon each code-completion invocation was a non-starter. The VM takes a substantial amount of time to start. This actually turned out to be a good thing because it opened my eyes to some very interesting possibilities. By running an Erlang VM in the background with a TCP command server process I could run the completions extremely quickly by using Python to send the commands and forward StdIn. This background server also makes it possible to track state between invocations.

Variable Name Completion

I use the meta.function.erlang scope because it contains all the text needed for determining variable completion. It limits the amount of text I have to send to the command. This is intended to keep the completion time relatively constant even for very large source files.

Module Name Completion

There would be a process per unique directory in the set of loadpaths that have been seen. Their responsibility would be to index the modules and update the MNesia database as necessary. The entries would be tagged with their directory name. Module Name completion would be done by querying based on membership in a given load path.

Function Name Completion

This is relatively easy to achieve. This is because all modules inherently have a module_info/1. Calling Module:module_info(exports) yields a list of exported functions and their arities. Unfortunately, imported functions are a bit trickier to complete because module_info(imports) appears to return an empty list even when the module does, in fact, import things.

More to come in the forthcoming TextMate: Erlang code-completion (PART 1)...