From: Dmitry Gutov Date: Sun, 31 Mar 2013 18:52:39 +0000 (+0400) Subject: company-elisp: Don't complete defun name or arglist X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/8a23e481449111d0050e0250039ae8a0558807c0 company-elisp: Don't complete defun name or arglist --- diff --git a/NEWS.md b/NEWS.md index 6297652a2..4a46891c3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ # History of user-visible changes +## Next + +* `company-elisp` doesn't offer completions when typing the name and the + arguments of a new function or macro definition, allowing to fall back to + other back-ends like `company-dabbrev-code`. + ## 2013-03-30 (0.6.5) * Fixed keybindings when running in a terminal. diff --git a/company-elisp.el b/company-elisp.el index 53b48855c..faab0b0de 100644 --- a/company-elisp.el +++ b/company-elisp.el @@ -47,8 +47,9 @@ first in the candidates list." (defun company-elisp--prefix () (let ((prefix (company-grab-symbol))) (if prefix - (unless (and (company-in-string-or-comment) - (/= (char-before (- (point) (length prefix))) ?`)) + (when (if (company-in-string-or-comment) + (= (char-before (- (point) (length prefix))) ?`) + (company-elisp--should-complete)) prefix) 'stop))) @@ -58,23 +59,49 @@ first in the candidates list." (facep symbol) (featurep symbol))) +(defun company-elisp--fns-regexp (&rest names) + (concat "\\_<\\(?:cl-\\)?" (regexp-opt names) "\\*?\\_>")) + (defvar company-elisp-parse-limit 30) (defvar company-elisp-parse-depth 100) +(defvar company-elisp-defun-names '("defun" "defmacro" "defsubst")) + (defvar company-elisp-var-binding-regexp - (concat "\\_<\\(?:cl-\\)?" (regexp-opt '("let" "defun" "defmacro" "defsubst" - "lambda" "lexical-let")) - "\\*?\\_>") + (apply #'company-elisp--fns-regexp "let" "lambda" "lexical-let" + company-elisp-defun-names) "Regular expression matching head of a multiple variable bindings form.") (defvar company-elisp-var-binding-regexp-1 - (concat "\\_<\\(?:cl-\\)?" (regexp-opt '("dolist" "dotimes")) "\\_>") + (company-elisp--fns-regexp "dolist" "dotimes") "Regular expression matching head of a form with one variable binding.") (defvar company-elisp-fun-binding-regexp - (concat "\\_<\\(?:cl-\\)?" (regexp-opt '("flet" "labels")) "\\*?\\_>") + (company-elisp--fns-regexp "flet" "labels") "Regular expression matching head of a function bindings form.") +(defvar company-elisp-defuns-regexp + (concat "([ \t\n]*" + (apply #'company-elisp--fns-regexp company-elisp-defun-names))) + +(defun company-elisp--should-complete () + (let ((start (point)) + (depth (car (syntax-ppss)))) + (not + (when (> depth 0) + (save-excursion + (up-list (- depth)) + (when (looking-at company-elisp-defuns-regexp) + (forward-char) + (forward-sexp 1) + (unless (= (point) start) + (condition-case nil + (let ((args-end (scan-sexps (point) 2))) + (or (null args-end) + (> args-end start))) + (scan-error + t))))))))) + (defun company-elisp--locals (prefix functions-p) (let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix) "\\(?:\\sw\\|\\s_\\)*\\_>\\)")) diff --git a/company-tests.el b/company-tests.el index 011b67fb7..811e4cc2e 100644 --- a/company-tests.el +++ b/company-tests.el @@ -213,6 +213,7 @@ (declare (indent 0)) `(with-temp-buffer (insert ,contents) + (setq major-mode 'emacs-lisp-mode) (re-search-backward "|") (replace-match "") ,@body)) @@ -332,3 +333,29 @@ (let ((obarray [float-pi]) (company-elisp-show-locals-first t)) (should (equal '("float-pi") (company-elisp-candidates "f")))))) + +(ert-deftest company-elisp-shouldnt-complete-defun-name () + (company-elisp-with-buffer + "(defun foob|)" + (should (null (company-elisp 'prefix))))) + +(ert-deftest company-elisp-should-complete-def-call () + (company-elisp-with-buffer + "(defu|" + (should (equal "defu" (company-elisp 'prefix))))) + +(ert-deftest company-elisp-should-complete-in-defvar () + ;; It will also complete the var name, at least for now. + (company-elisp-with-buffer + "(defvar abc de|" + (should (equal "de" (company-elisp 'prefix))))) + +(ert-deftest company-elisp-shouldnt-complete-in-defun-arglist () + (company-elisp-with-buffer + "(defsubst foobar (ba|" + (should (null (company-elisp 'prefix))))) + +(ert-deftest company-elisp-prefix-in-defun-body () + (company-elisp-with-buffer + "(defun foob ()|)" + (should (equal "" (company-elisp 'prefix)))))