Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display autocomplete choices in emacs?

I'm working on autocompletion implementation in emacs for haxe programming language.

I already figured out how to obtain list of autocompletions which I wants to present. The list is in format:

'((name1 type1 desc1)
  (name2 type2 desc2) ...

I want to display to user list containing text in format "name1 type1" after cursor position (like in autocomplete-mode) and desc for currently selected item in minibuffer. User should be able to select completion or give up like in auto-complete mode.

When user select something, name1 should be inserted at cursor position.

What is the best/easiest way to do this? Is there some standard emacs way to do this, or I should code something on my own?

EDIT: I have functions to get the list of autocomplete candidates based on buffer. Now I'm struggling how to integrate that to autocomplete-mode. Since get-completes is heavy operation, I would like to trigger it only if cursor is on "." character.

Here's the code I have.

(defun get-completes-from-haxe (hxml-file file pos)
  (let* ((completion-buffer (get-buffer-create "*haxe-completions*"))
         (cmd (concat "cd " (file-name-directory hxml-file)  "; haxe " hxml-file " --display " file "@" (number-to-string pos))))
    (ignore-errors
      (shell-command cmd completion-buffer)
      (let ((clist (xml-parse-region 1 (buffer-size completion-buffer) completion-buffer))
            (completes nil))
        (dolist (s (cddar clist))
          (when (listp s)
            (let* ((item (cdr s))
                   (name (cdaar item))
                   (type (car (cddadr item)))
                   (desc (cdddr item)))
              (setf completes (cons name completes)))))
        completes))))

(defun file-find-upwards (buffer file-name)
  ;; Chase links in the source file and search in the dir where it  points.
  (setq dir-name (or (and (buffer-file-name buffer)
                          (file-name-directory (file-chase-links
                                                (buffer-file-name buffer))))
                     default-directory))
  ;; Chase links before visiting the file.  This makes it easier to
  ;; use a single file for several related directories.
  (setq dir-name (file-chase-links dir-name))
  (setq dir-name (expand-file-name dir-name))
  ;; Move up in the dir hierarchy till we find a change log file.
  (let ((file1 (concat dir-name file-name))
        parent-dir)
    (while (and (not (file-exists-p file1))
                (progn (setq parent-dir
                             (file-name-directory
                              (directory-file-name
                               (file-name-directory file1))))
                       ;; Give up if we are already at the root dir.
                       (not (string= (file-name-directory file1)
                                     parent-dir))))
      ;; Move up to the parent dir and try again.
      (setq file1 (expand-file-name file-name parent-dir)))
    ;; If we found the file in a parent dir, use that.  Otherwise,
    ;; return nil
    (if (or (get-file-buffer file1) (file-exists-p file1))
        file1
      nil)))


(defun get-candidate-list (buffer pos)
  (get-completes-from-haxe 
   (file-find-upwards buffer "compile.hxml") 
   (buffer-file-name buffer) 
   pos))
like image 330
Marko Avatar asked Jul 17 '09 16:07

Marko


2 Answers

I'd suggest the excellent package AutoComplete: http://www.emacswiki.org/emacs/AutoComplete

You can define custom sources for autocomplete and it seems fairly straight forward.

like image 179
Travis B. Hartwell Avatar answered Sep 20 '22 23:09

Travis B. Hartwell


Why keep reinventing wheels? company-mode has support for a few languages

like image 28
RichieHH Avatar answered Sep 22 '22 23:09

RichieHH