2009-03-06

How To Implement Keyword Completion in Emacs

Perm url: http://xahlee.org/emacs/elisp_keyword_completion.html

How To Implement Keyword Completion in Emacs

Xah Lee, 2009-03-06

This page shows you how to implement computer language keyword completion in emacs. You should know the basics of writing a major mode. If not, see: How To Write A Emacs Major Mode For Syntax Coloring.

The Problem

You are writing a emacs major mode for your own language. You want to have a keyword completion feature, so that user can press a key and have the word under cursor automatically expanded to the possible keywords of the language.

xlsl-keyword completion

Keyword completion in emacs.

Solution

The basic concept of keyword completion is pretty simple. You begin with a list of keywords, and you are given a string that you want to complete. You match the string against the keywords, find the maximal match, then replace the current word with tha max match. However, you will also need to popup a list of possible completions for the user to choose, and allow user some user interface conveniences such as clicking on one of the choices.

Suppose your language xyz has the following list of keywords.

;; this is your lang's keywords
(setq xyz-kwdList '
      ("touch"
       "touch_start"
       "touch_end"
       "for"
       "foreach"
       "forall"
       ))

The following is the code that does the completion.

(defun xyz-complete-symbol ()
  "Perform completion on word under cursor."
  (interactive)
  (let* (
         (cusorPoint (point))
         (meat (thing-at-point 'symbol))
         (maxMatchResult (try-completion meat xyz-kwdList))
         )
    (when meat
      (cond ((eq maxMatchResult t))
            ((null maxMatchResult)
             (message "Can't find completion for “%s”" meat)
             (ding))
            ((not (string= meat maxMatchResult))
             (delete-region (- cusorPoint (length meat)) cusorPoint)
             (insert maxMatchResult))
            (t (message "Making completion list...")
               (with-output-to-temp-buffer "*Completions*"
                 (display-completion-list
                  (all-completions meat xyz-kwdList)
                  meat))
               (message "Making completion list...%s" "done"))))
    ))

The above code is very easy to understand. First, you grab the word before cursor, save it as “meat”. Then, you find the maximal match, save it as maxMatchResult. Then, we have a few cases:

  • (1) If the max match is the same as the word under cursor, then do nothing, because the word is already complete.
  • (2) If the max match is empty, then tell user there is no completion.
  • (3) If not the above two cases, then expand the current word to max match.
  • (4) Otherwise, pop up a dialog to list possible completions.

Lucky for us, emacs does most of the tedious job. The core functions that do the job is “try-completion”, “all-completions”, “display-completion-list”.

  • The “try-completion” returns the maximal match.
  • The “all-completions” returns all possible completions.
  • The “display-completion-list” takes care of the user interface for displaying the possible completions, and making them clickable.

Set a keyboard shortcut for your completion function, so that you can easily test it. e.g. “(global-set-key (kbd "<f1>") 'xyz-complete-symbol)”.

In the above, we used a simple list for our keywords, and fed them to emacs's completion functions. Emacs's completion functions can also take keyword argument in the form of a alist or hashtable. A alist looks like this:

(setq xyz-kwdList
 '(("touch" . nil)
   ("touch_start" . nil)
   ("touch_end" . nil)))

For hash, see: Elisp Lesson: Hash Table.

(info "(elisp)Completion")

Emacs is beautiful.

2009-03-04

What Is Your Favorite Lisp

Perm url: http://xahlee.org/UnixResource_dir/writ/whats_your_fav_lisp.html

What Is Your Favorite Lisp

Xah Lee, 2009-03-04

Javier wrote: “What open source implementation of Lisp do you prefer and why?”

My fav is Emacs Lisp.

Because it is practical. More or less the most widely used lisp today.

Considered as a tool, it has probably some 10 times more users than either Common Lisp or Scheme Lisp.

For example, i consider emacs lisp, more powerful than Perl, as a text processing language, for 2 major reasons: (1) It has buffer datatype and associated datatypes such as point, marker, region, etc.. Which is more powerful than treating text as inert chars and lines, which Perl, Python, Ruby, etc do. (2) elisp's integrated nature with emacs. This means, for odd text manipulation jobs that happen daily in every software coding, i can write text processing programs that interact with me while i edit. (See also: Text Processing: Elisp vs Perl.)

The above paragraph, details why i love emacs lisp. However, it is not so much caused by lisp language's nature. I find nothing in particular of lisp lang's features of emacs lisp that made me love emacs lisp, other than it being a functional language. It is not difficult to have another language, or a new editor with a embedded lang that functions similar to emacs. However, emacs just happens to be almost the only one, or the most prominent one. (i am a expert in Microsoft Word in early 1990s, and although i haven't ventured into its Visual Basic, but i know it can do scripting. I'm sure, now after almost 20 years, and with Microsoft's “.NET”, it possibly might compete with emacs with its elisp, but i know nothing about it to comment further. (i'd very much welcome any comment from someone who are a expert of scripting Microsoft Word with Visual Basic; on how it compares to emacs, if at all. (if you don't have say 1 year of full-time experience in this, please spare me your drivel)))

As to the reason i am not a fan of the 2 other major lisps: Common Lisp and Scheme Lisp. These 2, are little used in the industry. Common Lisp is a moribund dinosaur. Scheme Lisp is little used and is confined to Academia. There is nothing in these 2 langs that i consider elegant or powerful today. I would, in a blink of a eye, consider Mathematica, OCaml, Haskell, more elegant or powerful.

I would like to see Common Lisp and or Scheme Lisp die a miserable, horrid, deaths, due to fanaticism as exhibited by Common Lisp and Scheme Lisp regulars in newsgroups. I consider these 2 langs not only impractical and inelegant, but their people are the hog of any possible progress of lisp in general. (See also: Language, Purity, Cult, and Deception.)

I do consider lisp, or the lisp way, a lang with lisp characteristics, can be the most beautiful, elegant language. (in fact, i consider Mathematica being one such example) However, given the social milieu of the 3 major lisp communities: Common Lisp, Scheme Lisp, Emacs Lisp, it might happen when pigs fly.


Of the existing lisps, especially new ones, i support NewLisp, and i also support Clojure. Personally, i'm not likely to invest time in them in the next 5 years, if ever. Second to these, i mildly support Qi.

I am a avid fan of functional programing, and was a big fan of lisp too. Lisp, even just 10 years ago, was still a great language, almost the only one that are much better than all others, in both practical industry use and also academic theoretical considerations. But due to the rapid development of software technologies and vast number of lang today that happened in the past decade, including a profusion of quality functional langs, i see little point in lisp.

(See also: Proliferation of Computing Languages.)

Emacs xlsl-mode for Linden Scripting Language

A new version: Emacs xlsl-mode for Linden Scripting Language. This version suppports keyword completion. (computing)