The Emacs way of doing auto - completion is known as Hippie Expand which is a function that uses a variety of methods to try and expand an incomplete word near the point. Why it's called Hippie Expand I have no idea. The name is a bit misleading; for a long time I thought it was related to zippy or pinhead. Perhaps it's something to do with Emacs being used and written by hippies, who knows?
The nice thing about hippie expand is that like many things in Emacs, it can be customized and expanded, via the make-hippie-expand function. For instance, here is the hippie-expand function I use for c-mode
(make-hippie-expand-function
'(try-expand-dabbrev-visible
try-expand-dabbrev-from-kill
try-expand-dabbrev-all-buffers
try-complete-file-name-partially
try-complete-file-name)))))
This function first tries to expand the thing found at the point as a dynamic abbreviation, which is based on a scan of existing text for words or symbols with the same beginning as the one at the point. For instance, if "catalogue" is in the buffer, and you expand "cat", then "catalogue" will be one of the expansions offered, which is useful if "catalogue" is a variable name you use a lot.
The hippie expand function is bound to a key (I use M-/) and each press of that key will cycle through the possible completions for you. It's not Intellisense, but it does cut down on typing if you use descriptive variable names.
It's also fairly trivial to write your own hippie-expand function. Here is an example of a hippie expand function which does completion based on a list of current tags - which are sometimes more useful than dabbrevs.
;; This is a simple function to return the point at the beginning of the symbol to be completed
(defun he-tag-beg ()
(let ((p
(save-excursion
(backward-word 1)
(point))))
p))
;; The actual expansion function
(defun try-expand-tag (old)
;; old is true if we have already attempted an expansion
(unless old
;; he-init-string is used to capture the string we are trying to complete
(he-init-string (he-tag-beg) (point))
;; he-expand list is the list of possible expansions
(setq he-expand-list (sort
(all-completions he-search-string 'tags-complete-tag) 'string-lessp)))
;; now we go through the list, looking for an expansion that isn't in the table of previously
;; tried expansions
(while (and he-expand-list
(he-string-member (car he-expand-list) he-tried-table))
(setq he-expand-list (cdr he-expand-list)))
;; if we didn't have any expansions left, reset the expansion list
(if (null he-expand-list)
(progn
(when old (he-reset-string))
())
;; otherwise offer the expansion at the head of the list
(he-substitute-string (car he-expand-list))
;; and put that expansion into the tried expansions list
(setq he-expand-list (cdr he-expand-list))
t))
;; done, now we just use it as a clause in our make-hippie-expand-function (as above)
Hippie-expand isn't the only auto-completion gizmo I work with in Emacs; there is also slime-complete-symbol which does symbol completion for my while I am working in SLIME. This can be neatly integrated into hippie-expand, like so..
;; hippie expand slime symbol
(defun he-slime-symbol-beg ()
(let ((p
(slime-symbol-start-pos)))
p))
(defun try-expand-slime-symbol (old)
(unless old
(he-init-string (he-slime-symbol-beg) (point))
(setq he-expand-list (sort
(car (slime-contextual-completions (slime-symbol-start-pos) (slime-symbol-end-pos))) 'string-lessp)))
(while (and he-expand-list
(he-string-member (car he-expand-list) he-tried-table))
(setq he-expand-list (cdr he-expand-list)))
(if (null he-expand-list)
(progn
(when old (he-reset-string))
())
(he-substitute-string (car he-expand-list))
(setq he-expand-list (cdr he-expand-list))
t))
EDIT: With newer (CVS and 3.0) versions of SLIME the api for symbol completion
has changed and the hippie-expand function for slime symbol completion is..
;; hippie expand slime symbol
(defun he-slime-symbol-beg ()
(let ((p
(slime-symbol-start-pos)))
p))
(defun try-expand-slime-symbol (old)
(unless old
(he-init-string (he-slime-symbol-beg) (point))
(setq he-expand-list (sort
(car (slime-simple-completions
(buffer-substring-no-properties (slime-symbol-start-pos) (slime-symbol-end-pos))))
'string-lessp)))
(while (and he-expand-list
(he-string-member (car he-expand-list) he-tried-table))
(setq he-expand-list (cdr he-expand-list)))
(if (null he-expand-list)
(progn
(when old (he-reset-string))
())
(he-substitute-string (car he-expand-list))
(setq he-expand-list (cdr he-expand-list))
t))
No comments:
Post a Comment