X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/ba603c98369e875b5b723b0b335a3c2b702af9c7..f10533854f4c7bb54247a11981191bf37b70cb36:/packages/company/company-yasnippet.el diff --git a/packages/company/company-yasnippet.el b/packages/company/company-yasnippet.el index f0a7c380d..5c880174e 100644 --- a/packages/company/company-yasnippet.el +++ b/packages/company/company-yasnippet.el @@ -1,6 +1,6 @@ -;;; company-yasnippet.el --- company-mode completion back-end for Yasnippet +;;; company-yasnippet.el --- company-mode completion backend for Yasnippet -;; Copyright (C) 2014 Free Software Foundation, Inc. +;; Copyright (C) 2014, 2015 Free Software Foundation, Inc. ;; Author: Dmitry Gutov @@ -33,8 +33,47 @@ (declare-function yas-expand-snippet "yasnippet") (declare-function yas--template-content "yasnippet") (declare-function yas--template-expand-env "yasnippet") +(declare-function yas--warning "yasnippet") + +(defun company-yasnippet--key-prefixes () + ;; Mostly copied from `yas--templates-for-key-at-point'. + (defvar yas-key-syntaxes) + (save-excursion + (let ((original (point)) + (methods yas-key-syntaxes) + prefixes + method) + (while methods + (unless (eq method (car methods)) + (goto-char original)) + (setq method (car methods)) + (cond ((stringp method) + (skip-syntax-backward method) + (setq methods (cdr methods))) + ((functionp method) + (unless (eq (funcall method original) + 'again) + (setq methods (cdr methods)))) + (t + (setq methods (cdr methods)) + (yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method))) + (let ((prefix (buffer-substring-no-properties (point) original))) + (unless (equal prefix (car prefixes)) + (push prefix prefixes)))) + prefixes))) (defun company-yasnippet--candidates (prefix) + ;; Process the prefixes in reverse: unlike Yasnippet, we look for prefix + ;; matches, so the longest prefix with any matches should be the most useful. + (cl-loop with tables = (yas--get-snippet-tables) + for key-prefix in (company-yasnippet--key-prefixes) + ;; Only consider keys at least as long as the symbol at point. + when (>= (length key-prefix) (length prefix)) + thereis (company-yasnippet--completions-for-prefix prefix + key-prefix + tables))) + +(defun company-yasnippet--completions-for-prefix (prefix key-prefix tables) (cl-mapcan (lambda (table) (let ((keyhash (yas--table-hash table)) @@ -43,42 +82,44 @@ (maphash (lambda (key value) (when (and (stringp key) - (string-prefix-p prefix key)) + (string-prefix-p key-prefix key)) (maphash (lambda (name template) (push (propertize key 'yas-annotation name - 'yas-template template) + 'yas-template template + 'yas-prefix-offset (- (length key-prefix) + (length prefix))) res)) value))) keyhash)) res)) - (yas--get-snippet-tables))) + tables)) ;;;###autoload (defun company-yasnippet (command &optional arg &rest ignore) - "`company-mode' back-end for `yasnippet'. + "`company-mode' backend for `yasnippet'. -This back-end should be used with care, because as long as there are -snippets defined for the current major mode, this back-end will always -shadow back-ends that come after it. Recommended usages: +This backend should be used with care, because as long as there are +snippets defined for the current major mode, this backend will always +shadow backends that come after it. Recommended usages: -* In a buffer-local value of `company-backends', grouped with a back-end or +* In a buffer-local value of `company-backends', grouped with a backend or several that provide actual text completions. - (add-hook 'js-mode-hook + (add-hook \\='js-mode-hook (lambda () - (set (make-local-variable 'company-backends) - '((company-dabbrev-code company-yasnippet))))) + (set (make-local-variable \\='company-backends) + \\='((company-dabbrev-code company-yasnippet))))) -* After keyword `:with', grouped with other back-ends. +* After keyword `:with', grouped with other backends. - (push '(company-semantic :with company-yasnippet) company-backends) + (push \\='(company-semantic :with company-yasnippet) company-backends) * Not in `company-backends', just bound to a key. - (global-set-key (kbd \"C-c y\") 'company-yasnippet) + (global-set-key (kbd \"C-c y\") \\='company-yasnippet) " (interactive (list 'interactive)) (cl-case command @@ -93,10 +134,12 @@ shadow back-ends that come after it. Recommended usages: (unless company-tooltip-align-annotations " -> ") (get-text-property 0 'yas-annotation arg))) (candidates (company-yasnippet--candidates arg)) + (no-cache t) (post-completion - (let ((template (get-text-property 0 'yas-template arg))) + (let ((template (get-text-property 0 'yas-template arg)) + (prefix-offset (get-text-property 0 'yas-prefix-offset arg))) (yas-expand-snippet (yas--template-content template) - (- (point) (length arg)) + (- (point) (length arg) prefix-offset) (point) (yas--template-expand-env template))))))