]> code.delx.au - gnu-emacs-elpa/commitdiff
company-elisp-candidates: Recognize when inside varlist
authorDmitry Gutov <dgutov@yandex.ru>
Fri, 29 Mar 2013 05:09:41 +0000 (09:09 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Fri, 29 Mar 2013 05:38:46 +0000 (09:38 +0400)
* Extract -candidates-predicate and -globals.
* Add tests.
* Rename -parse-local to -locals, accept just one argument.

company-elisp.el
company-tests.el

index 986cd3d4b73b254f62c2f309096022ac2e0b4220..b6e5961336a47a29fc7841da00cc40f22f51a960 100644 (file)
@@ -64,10 +64,11 @@ Functions are offered for completion only after ' and \(."
   (concat "([ \t\n]*\\_<" (regexp-opt '("dolist" "dotimes")))
   "Regular expression matching sexps containing one variable binding.")
 
-(defun company-elisp-parse-local (prefix vars)
+(defun company-elisp-locals (prefix)
   (let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix)
                         "\\(?:\\sw\\|\\s_\\)*\\_>\\)"))
-        (pos (point)))
+        (pos (point))
+        res)
     (ignore-errors
       (save-excursion
         (dotimes (i company-elisp-parse-depth)
@@ -84,27 +85,39 @@ Functions are offered for completion only after ' and \(."
                     (and (looking-at regexp)
                          ;; Don't add incomplete text as candidate.
                          (not (eq (match-end 0) pos))
-                         (add-to-list 'vars (match-string-no-properties 1))))
+                         (push (match-string-no-properties 1) res)))
                   (forward-sexp))))
              ((looking-at company-elisp-binding-regexp-1)
               (down-list 2)
               (and (looking-at regexp)
                    ;; Don't add incomplete text as candidate.
                    (not (eq (match-end 0) pos))
-                   (add-to-list 'vars (match-string-no-properties 1)))))))))
-    vars))
+                   (pushnew (match-string-no-properties 1) res))))))))
+    res))
 
 (defun company-elisp-candidates (prefix)
+  (append (company-elisp-locals prefix)
+          (company-elisp-globals prefix
+                                 (company-elisp-candidates-predicate prefix))))
+
+(defun company-elisp-globals (prefix predicate)
+  (all-completions prefix obarray predicate))
+
+(defun company-elisp-candidates-predicate (prefix)
   (let* ((completion-ignore-case nil)
-         (before (char-before (- (point) (length prefix))))
-         (predicate (if (and company-elisp-detect-function-context
-                             (not (eq before ?')))
-                        (if (eq before ?\()
-                            'fboundp
-                          'boundp)
-                      'company-elisp-predicate))
-         (candidates (all-completions prefix obarray predicate)))
-    (company-elisp-parse-local prefix candidates)))
+         (before (char-before (- (point) (length prefix)))))
+    (if (and company-elisp-detect-function-context
+             (not (eq before ?')))
+        (if (and (eq before ?\()
+                 (not
+                  (save-excursion
+                    (ignore-errors
+                      (up-list -2)
+                      (forward-char 1)
+                      (looking-at " *(")))))
+            'fboundp
+          'boundp)
+      'company-elisp-predicate)))
 
 (defun company-elisp-doc (symbol)
   (let* ((symbol (intern symbol))
index 5d08c94c8438ff3d8db25714f1b6f6be14c2b98b..30d898bc556dc00b9587ec98985e9b85a585663b 100644 (file)
     (apply command args)
     (let ((this-command command))
       (run-hooks 'post-command-hook))))
+
+(defmacro company-elisp-with-buffer (contents &rest body)
+  (declare (indent 0))
+  `(with-temp-buffer
+     (insert ,contents)
+     (re-search-backward "|")
+     (replace-match "")
+     ,@body))
+
+(ert-deftest company-elisp-candidates-predicate ()
+  (company-elisp-with-buffer
+    "(foo ba|)"
+    (should (eq (let ((company-elisp-detect-function-context t))
+                  (company-elisp-candidates-predicate "ba"))
+                'boundp))
+    (should (eq (let (company-elisp-detect-function-context)
+                  (company-elisp-candidates-predicate "ba"))
+                'company-elisp-predicate)))
+  (company-elisp-with-buffer
+    "(foo| )"
+    (should (eq (let ((company-elisp-detect-function-context t))
+                  (company-elisp-candidates-predicate "foo"))
+                'fboundp))
+    (should (eq (let (company-elisp-detect-function-context)
+                  (company-elisp-candidates-predicate "foo"))
+                'company-elisp-predicate)))
+  (company-elisp-with-buffer
+    "(foo 'b|)"
+    (should (eq (let ((company-elisp-detect-function-context t))
+                  (company-elisp-candidates-predicate "b"))
+                'company-elisp-predicate))))
+
+;; Mix it up with an integration test.
+(ert-deftest company-elisp-candidates-recognizes-binding-form ()
+  (company-elisp-with-buffer
+    "(let ((foo 7) (wh| )))"
+    (let ((obarray [when what whelp])
+          (what 1)
+          (whelp 2)
+          (wisp 3))
+      (should (equal '("what" "whelp")
+                     (let ((company-elisp-detect-function-context t))
+                       (company-elisp-candidates "wh")))))))
+
+(ert-deftest company-elisp-finds-vars ()
+  (let ((obarray [boo bar baz backquote])
+        (boo t)
+        (bar t)
+        (baz t))
+    (should (equal '("bar" "baz")
+                   (company-elisp-globals "ba" 'boundp)))))
+
+(ert-deftest company-elisp-finds-functions ()
+  (let ((obarray [when what whelp])
+        (what t)
+        (whelp t))
+    (should (equal '("when")
+                   (company-elisp-globals "wh" 'fboundp)))))
+
+(ert-deftest company-elisp-finds-things ()
+  (let ((obarray [when what whelp])
+        (what t)
+        (whelp t))
+    (should (equal '("what" "whelp" "when")
+                   (sort (company-elisp-globals "wh" 'company-elisp-predicate)
+                         'string<)))))