From: Dmitry Gutov Date: Fri, 29 Mar 2013 05:09:41 +0000 (+0400) Subject: company-elisp-candidates: Recognize when inside varlist X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/8427b8f1edd77234349930f440b2f03bf519221b?ds=sidebyside company-elisp-candidates: Recognize when inside varlist * Extract -candidates-predicate and -globals. * Add tests. * Rename -parse-local to -locals, accept just one argument. --- diff --git a/company-elisp.el b/company-elisp.el index 986cd3d4b..b6e596133 100644 --- a/company-elisp.el +++ b/company-elisp.el @@ -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)) diff --git a/company-tests.el b/company-tests.el index 5d08c94c8..30d898bc5 100644 --- a/company-tests.el +++ b/company-tests.el @@ -208,3 +208,69 @@ (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<)))))