views:

871

answers:

5

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))
+5  A: 

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.

Travis B. Hartwell
I saw that, but couldn't figure out how to display tooltips and docs with it. All it offers is vim like autocompletion, which is not what I want.
Dev er dev
Looks like in automplete mode, ac-select-candidate function is used to show the current selection of candidate, you can define an advice for that function to show the desc in minibuffer
+1  A: 

The ido-completing-read from ido.el is another way to do it.

An useful feature of it is that you can use regular expressions to filter out the candidates, and you can toggle this feature on and off on the fly. See ido.el for more details.

+1  A: 

ido package has convenient completion functionality called 'ido-completing-read'. For example, here's a simple tweak to make it show lists in a line-by-line basis:

(defun x-ido-completing-read
  (prompt choices &optional predicate require-match initial-input hist def)
  (let* ((indent (concat "\n" (make-string (length prompt) ? )))
         (ido-decorations
         `("" "" ,indent ,(concat indent "...")
           "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]")))
    (ido-completing-read prompt choices predicate require-match initial-input hist def)))
Jay
+1  A: 

Inside the yasnippet code, available from google code, they use 'dropdown-list.el' by Jaeyoun Chung to display the possible snippets that could be used at point. This gives a popup (tooltip-like) menu at the cursor position you can select with the arrow keys and enter or you can select by number.

http://www.emacswiki.org/emacs/dropdown-list.el

twopoint718
Great, if only it would be possible to get rid of selid on the right side :)
Dev er dev
+1  A: 

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

Richard Riley
This is the way to go. I don't know why I missed company-mode and wasted time with clearly inferior autocomplete-mode. Perhaps the ugly name ;)
Dev er dev
The only issue is the documentation for company-mode. Its far from clear how to use it and I have received many emails from people asking for my company-setup. It can be seen in the config files linked to here:http://richardriley.net/projects/emacs/dotemacs
Richard Riley