(defvar company-elisp-parse-limit 30)
(defvar company-elisp-parse-depth 100)
-(defun company-elisp-parse-let ()
- (let (vars)
+(defvar company-elisp-binding-regexp
+ (concat "([ \t\n]*\\_<" (regexp-opt '("let" "defun" "defmacro" "defsubst"
+ "lambda" "lexical-let"))
+ "\\*?"))
+
+(defun company-elisp-parse-local (prefix vars)
+ (let ((regexp (concat "[ \t\n]*\\(" (regexp-quote prefix)
+ "\\(?:\\sw\\|\\s_\\)*\\_>\\)")))
(ignore-errors
(save-excursion
(dotimes (i company-elisp-parse-depth)
(up-list -1)
(save-excursion
- (when (looking-at "([ \t\n]*let")
+ (when (looking-at company-elisp-binding-regexp)
(down-list 2)
(ignore-errors
(dotimes (i company-elisp-parse-limit)
(save-excursion
- (down-list 1)
- (if (looking-at "[ \t\n]*\\(\\(?:\\sw\\|\\s_\\)+\\)")
+ (when (looking-at "[ \t\n]*(")
+ (down-list 1))
+ (if (looking-at regexp)
(add-to-list 'vars (match-string-no-properties 1))
(error)))
(forward-sexp))))))))
vars))
+(defun company-elisp-candidates (prefix)
+ (let* ((completion-ignore-case nil)
+ (candidates (all-completions prefix obarray 'company-elisp-predicate)))
+ (company-elisp-parse-local prefix candidates)))
+
(defun company-elisp-doc (symbol)
(let* ((symbol (intern symbol))
(doc (if (fboundp symbol)
(documentation symbol t)
(documentation-property symbol 'variable-documentation t))))
- (when (string-match ".*$" doc)
- (match-string 0 doc))))
+ (and (stringp doc)
+ (string-match ".*$" doc)
+ (match-string 0 doc))))
(defun company-elisp (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for `emacs-lisp-mode'."
(case command
- ('prefix (and (eq major-mode 'emacs-lisp-mode)
+ ('prefix (and (eq (derived-mode-p 'emacs-lisp-mode) 'emacs-lisp-mode)
(company-grab-lisp-symbol)))
- ('candidates (let ((completion-ignore-case nil))
- (append (all-completions arg (company-elisp-parse-let))
- (all-completions arg obarray
- 'company-elisp-predicate))))
+ ('candidates (company-elisp-candidates arg))
('meta (company-elisp-doc arg))
- ('doc-buffer (describe-function 'describe-function)
- (help-buffer))))
+ ('doc-buffer (let ((symbol (intern arg)))
+ (save-window-excursion
+ (when (or (ignore-errors (describe-function symbol))
+ (ignore-errors (describe-variable symbol)))
+ (help-buffer)))))))
(provide 'company-elisp)
;;; company-elisp.el ends here