]> code.delx.au - gnu-emacs-elpa/blobdiff - company-eclim.el
New transformer: company-sort-prefer-same-case-prefix
[gnu-emacs-elpa] / company-eclim.el
index b9ac24207f173d8bf731aa7ce332d721accd1528..208daf51402cfacb36a7ec3d2dc1bcfd0301c6cf 100644 (file)
@@ -1,6 +1,6 @@
-;;; company-eclim.el --- A company-mode completion back-end for eclim.
+;;; company-eclim.el --- company-mode completion backend for Eclim
 
 
-;; Copyright (C) 2009, 2011, 2013  Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011, 2013, 2015  Free Software Foundation, Inc.
 
 ;; Author: Nikolaj Schumacher
 
 
 ;; Author: Nikolaj Schumacher
 
 
 ;;; Commentary:
 ;;
 
 ;;; Commentary:
 ;;
-;; Using `emacs-eclim' together with (or instead of) this back-end is
+;; Using `emacs-eclim' together with (or instead of) this backend is
 ;; recommended, as it allows you to use other Eclim features.
 ;;
 ;; recommended, as it allows you to use other Eclim features.
 ;;
-;; The alternative back-end provided by `emacs-eclim' uses `yasnippet'
+;; The alternative backend provided by `emacs-eclim' uses `yasnippet'
 ;; instead of `company-template' to expand function calls, and it supports
 ;; some languages other than Java.
 
 ;; instead of `company-template' to expand function calls, and it supports
 ;; some languages other than Java.
 
 
 (require 'company)
 (require 'company-template)
 
 (require 'company)
 (require 'company-template)
-(eval-when-compile (require 'cl))
+(require 'cl-lib)
+
+(defgroup company-eclim nil
+  "Completion backend for Eclim."
+  :group 'company)
 
 (defun company-eclim-executable-find ()
   (let (file)
 
 (defun company-eclim-executable-find ()
   (let (file)
-    (dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
+    (cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
                             "/usr/local/lib/eclipse"))
       (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
            (setq file (car (last (directory-files file t "^org.eclim_"))))
            (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
                             "/usr/local/lib/eclipse"))
       (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
            (setq file (car (last (directory-files file t "^org.eclim_"))))
            (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
-           (return file)))))
+           (cl-return file)))))
 
 (defcustom company-eclim-executable
 
 (defcustom company-eclim-executable
-  (or (executable-find "eclim") (company-eclim-executable-find))
+  (or (bound-and-true-p eclim-executable)
+      (executable-find "eclim")
+      (company-eclim-executable-find))
   "Location of eclim executable."
   "Location of eclim executable."
-  :group 'company
   :type 'file)
 
 (defcustom company-eclim-auto-save t
   "Determines whether to save the buffer when retrieving completions.
 eclim can only complete correctly when the buffer has been saved."
   :type 'file)
 
 (defcustom company-eclim-auto-save t
   "Determines whether to save the buffer when retrieving completions.
 eclim can only complete correctly when the buffer has been saved."
-  :group 'company
   :type '(choice (const :tag "Off" nil)
                  (const :tag "On" t)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
   :type '(choice (const :tag "Off" nil)
                  (const :tag "On" t)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defvar company-eclim--project-dir 'unknown)
-(make-variable-buffer-local 'company-eclim--project-dir)
+(defvar-local company-eclim--project-dir 'unknown)
 
 
-(defvar company-eclim--project-name nil)
-(make-variable-buffer-local 'company-eclim--project-name)
+(defvar-local company-eclim--project-name nil)
 
 
-(defvar company-eclim--doc nil)
-(make-variable-buffer-local 'company-eclim--doc)
+(declare-function json-read "json")
+(defvar json-array-type)
 
 (defun company-eclim--call-process (&rest args)
   (let ((coding-system-for-read 'utf-8)
 
 (defun company-eclim--call-process (&rest args)
   (let ((coding-system-for-read 'utf-8)
@@ -90,7 +92,7 @@ eclim can only complete correctly when the buffer has been saved."
       (setq company-eclim--project-dir
             (directory-file-name
              (expand-file-name
       (setq company-eclim--project-dir
             (directory-file-name
              (expand-file-name
-              (company-locate-dominating-file buffer-file-name ".project"))))
+              (locate-dominating-file buffer-file-name ".project"))))
     company-eclim--project-dir))
 
 (defun company-eclim--project-name ()
     company-eclim--project-dir))
 
 (defun company-eclim--project-name ()
@@ -98,15 +100,15 @@ eclim can only complete correctly when the buffer has been saved."
       (let ((dir (company-eclim--project-dir)))
         (when dir
           (setq company-eclim--project-name
       (let ((dir (company-eclim--project-dir)))
         (when dir
           (setq company-eclim--project-name
-                (loop for project in (company-eclim--project-list)
-                      when (equal (cdr (assoc 'path project)) dir)
-                      return (cdr (assoc 'name project))))))))
+                (cl-loop for project in (company-eclim--project-list)
+                         when (equal (cdr (assoc 'path project)) dir)
+                         return (cdr (assoc 'name project))))))))
 
 (defun company-eclim--candidates (prefix)
   (interactive "d")
   (let ((project-file (file-relative-name buffer-file-name
                                           (company-eclim--project-dir)))
 
 (defun company-eclim--candidates (prefix)
   (interactive "d")
   (let ((project-file (file-relative-name buffer-file-name
                                           (company-eclim--project-dir)))
-        (project-name (company-eclim--project-name)))
+        completions)
     (when company-eclim-auto-save
       (when (buffer-modified-p)
         (basic-save-buffer))
     (when company-eclim-auto-save
       (when (buffer-modified-p)
         (basic-save-buffer))
@@ -114,8 +116,6 @@ eclim can only complete correctly when the buffer has been saved."
       (company-eclim--call-process "java_src_update"
                                    "-p" (company-eclim--project-name)
                                    "-f" project-file))
       (company-eclim--call-process "java_src_update"
                                    "-p" (company-eclim--project-name)
                                    "-f" project-file))
-    (setq company-eclim--doc
-          (make-hash-table :test 'equal))
     (dolist (item (cdr (assoc 'completions
                               (company-eclim--call-process
                                "java_complete" "-p" (company-eclim--project-name)
     (dolist (item (cdr (assoc 'completions
                               (company-eclim--call-process
                                "java_complete" "-p" (company-eclim--project-name)
@@ -126,35 +126,36 @@ eclim can only complete correctly when the buffer has been saved."
                                "-l" "standard"))))
       (let* ((meta (cdr (assoc 'info item)))
              (completion meta))
                                "-l" "standard"))))
       (let* ((meta (cdr (assoc 'info item)))
              (completion meta))
-        (when (string-match " [:-]" completion)
+        (when (string-match " ?[(:-]" completion)
           (setq completion (substring completion 0 (match-beginning 0))))
           (setq completion (substring completion 0 (match-beginning 0))))
-        (puthash completion meta company-eclim--doc))))
-  (let ((completion-ignore-case nil))
-    (all-completions prefix company-eclim--doc)))
+        (put-text-property 0 1 'meta meta completion)
+        (push completion completions)))
+    (let ((completion-ignore-case nil))
+      (all-completions prefix completions))))
 
 (defun company-eclim--search-point (prefix)
 
 (defun company-eclim--search-point (prefix)
-  (if (or (plusp (length prefix)) (eq (char-before) ?.))
+  (if (or (cl-plusp (length prefix)) (eq (char-before) ?.))
       (1- (point))
     (point)))
 
 (defun company-eclim--meta (candidate)
       (1- (point))
     (point)))
 
 (defun company-eclim--meta (candidate)
-  (gethash candidate company-eclim--doc))
-
-(defun company-eclim--templatify (call)
-  (let* ((end (point))
-         (beg (- (point) (length call)))
-         (templ (company-template-declare-template beg end)))
-    (save-excursion
-      (goto-char beg)
-      (while (re-search-forward "\\([(,] ?\\)\\([^ ]+ \\)\\([^ ,)]*\\)" end t)
-        (let ((name (match-string 3)))
-          (replace-match "\\1" t)
-          (decf end (length (match-string 2)))
-          (company-template-add-field templ (point) name))))
-    (company-template-move-to-first templ)))
+  (get-text-property 0 'meta candidate))
+
+(defun company-eclim--annotation (candidate)
+  (let ((meta (company-eclim--meta candidate)))
+    (when (string-match "\\(([^-]*\\) -" meta)
+      (substring meta (match-beginning 1) (match-end 1)))))
+
+(defun company-eclim--prefix ()
+  (let ((prefix (company-grab-symbol)))
+    (when prefix
+      ;; Completion candidates for annotations don't include '@'.
+      (when (eq ?@ (string-to-char prefix))
+        (setq prefix (substring prefix 1)))
+      prefix)))
 
 (defun company-eclim (command &optional arg &rest ignored)
 
 (defun company-eclim (command &optional arg &rest ignored)
-  "A `company-mode' completion back-end for Eclim.
+  "`company-mode' completion backend for Eclim.
 Eclim provides access to Eclipse Java IDE features for other editors.
 
 Eclim version 1.7.13 or newer (?) is required.
 Eclim provides access to Eclipse Java IDE features for other editors.
 
 Eclim version 1.7.13 or newer (?) is required.
@@ -162,22 +163,23 @@ Eclim version 1.7.13 or newer (?) is required.
 Completions only work correctly when the buffer has been saved.
 `company-eclim-auto-save' determines whether to do this automatically."
   (interactive (list 'interactive))
 Completions only work correctly when the buffer has been saved.
 `company-eclim-auto-save' determines whether to do this automatically."
   (interactive (list 'interactive))
-  (case command
+  (cl-case command
     (interactive (company-begin-backend 'company-eclim))
     (prefix (and (derived-mode-p 'java-mode 'jde-mode)
                  buffer-file-name
                  company-eclim-executable
                  (company-eclim--project-name)
                  (not (company-in-string-or-comment))
     (interactive (company-begin-backend 'company-eclim))
     (prefix (and (derived-mode-p 'java-mode 'jde-mode)
                  buffer-file-name
                  company-eclim-executable
                  (company-eclim--project-name)
                  (not (company-in-string-or-comment))
-                 (or (company-grab-symbol) 'stop)))
+                 (or (company-eclim--prefix) 'stop)))
     (candidates (company-eclim--candidates arg))
     (meta (company-eclim--meta arg))
     ;; because "" doesn't return everything
     (no-cache (equal arg ""))
     (candidates (company-eclim--candidates arg))
     (meta (company-eclim--meta arg))
     ;; because "" doesn't return everything
     (no-cache (equal arg ""))
-    (crop (when (string-match "(" arg)
-            (substring arg 0 (match-beginning 0))))
-    (post-completion (when (string-match "([^)]" arg)
-                       (company-eclim--templatify arg)))))
+    (annotation (company-eclim--annotation arg))
+    (post-completion (let ((anno (company-eclim--annotation arg)))
+                       (when anno
+                         (insert anno)
+                         (company-template-c-like-templatify anno))))))
 
 (provide 'company-eclim)
 ;;; company-eclim.el ends here
 
 (provide 'company-eclim)
 ;;; company-eclim.el ends here