| @ -0,0 +1,50 @@ | |||
| ;;; company-abbrev.el --- company-mode completion backend for abbrev | |||
| ;; Copyright (C) 2009-2011, 2015 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (require 'abbrev) | |||
| (defun company-abbrev-insert (match) | |||
| "Replace MATCH with the expanded abbrev." | |||
| (expand-abbrev)) | |||
| ;;;###autoload | |||
| (defun company-abbrev (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for abbrev." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-abbrev | |||
| 'company-abbrev-insert)) | |||
| (prefix (company-grab-symbol)) | |||
| (candidates (nconc | |||
| (delete "" (all-completions arg global-abbrev-table)) | |||
| (delete "" (all-completions arg local-abbrev-table)))) | |||
| (meta (abbrev-expansion arg)))) | |||
| (provide 'company-abbrev) | |||
| ;;; company-abbrev.el ends here | |||
| @ -0,0 +1,284 @@ | |||
| ;;; company-autoloads.el --- automatically extracted autoloads | |||
| ;; | |||
| ;;; Code: | |||
| (add-to-list 'load-path (or (file-name-directory #$) (car load-path))) | |||
| ;;;### (autoloads nil "company" "company.el" (22223 33912 0 0)) | |||
| ;;; Generated autoloads from company.el | |||
| (autoload 'company-mode "company" "\ | |||
| \"complete anything\"; is an in-buffer completion framework. | |||
| Completion starts automatically, depending on the values | |||
| `company-idle-delay' and `company-minimum-prefix-length'. | |||
| Completion can be controlled with the commands: | |||
| `company-complete-common', `company-complete-selection', `company-complete', | |||
| `company-select-next', `company-select-previous'. If these commands are | |||
| called before `company-idle-delay', completion will also start. | |||
| Completions can be searched with `company-search-candidates' or | |||
| `company-filter-candidates'. These can be used while completion is | |||
| inactive, as well. | |||
| The completion data is retrieved using `company-backends' and displayed | |||
| using `company-frontends'. If you want to start a specific backend, call | |||
| it interactively or use `company-begin-backend'. | |||
| By default, the completions list is sorted alphabetically, unless the | |||
| backend chooses otherwise, or `company-transformers' changes it later. | |||
| regular keymap (`company-mode-map'): | |||
| \\{company-mode-map} | |||
| keymap during active completions (`company-active-map'): | |||
| \\{company-active-map} | |||
| \(fn &optional ARG)" t nil) | |||
| (defvar global-company-mode nil "\ | |||
| Non-nil if Global-Company mode is enabled. | |||
| See the command `global-company-mode' for a description of this minor mode. | |||
| Setting this variable directly does not take effect; | |||
| either customize it (see the info node `Easy Customization') | |||
| or call the function `global-company-mode'.") | |||
| (custom-autoload 'global-company-mode "company" nil) | |||
| (autoload 'global-company-mode "company" "\ | |||
| Toggle Company mode in all buffers. | |||
| With prefix ARG, enable Global-Company mode if ARG is positive; | |||
| otherwise, disable it. If called from Lisp, enable the mode if | |||
| ARG is omitted or nil. | |||
| Company mode is enabled in all buffers where | |||
| `company-mode-on' would do it. | |||
| See `company-mode' for more information on Company mode. | |||
| \(fn &optional ARG)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-abbrev" "company-abbrev.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-abbrev.el | |||
| (autoload 'company-abbrev "company-abbrev" "\ | |||
| `company-mode' completion backend for abbrev. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-bbdb" "company-bbdb.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-bbdb.el | |||
| (autoload 'company-bbdb "company-bbdb" "\ | |||
| `company-mode' completion backend for BBDB. | |||
| \(fn COMMAND &optional ARG &rest IGNORE)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-css" "company-css.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-css.el | |||
| (autoload 'company-css "company-css" "\ | |||
| `company-mode' completion backend for `css-mode'. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-dabbrev" "company-dabbrev.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-dabbrev.el | |||
| (autoload 'company-dabbrev "company-dabbrev" "\ | |||
| dabbrev-like `company-mode' completion backend. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-dabbrev-code" "company-dabbrev-code.el" | |||
| ;;;;;; (22223 33912 0 0)) | |||
| ;;; Generated autoloads from company-dabbrev-code.el | |||
| (autoload 'company-dabbrev-code "company-dabbrev-code" "\ | |||
| dabbrev-like `company-mode' backend for code. | |||
| The backend looks for all symbols in the current buffer that aren't in | |||
| comments or strings. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-elisp" "company-elisp.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-elisp.el | |||
| (autoload 'company-elisp "company-elisp" "\ | |||
| `company-mode' completion backend for Emacs Lisp. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-etags" "company-etags.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-etags.el | |||
| (autoload 'company-etags "company-etags" "\ | |||
| `company-mode' completion backend for etags. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-files" "company-files.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-files.el | |||
| (autoload 'company-files "company-files" "\ | |||
| `company-mode' completion backend existing file names. | |||
| Completions works for proper absolute and relative files paths. | |||
| File paths with spaces are only supported inside strings. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-gtags" "company-gtags.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-gtags.el | |||
| (autoload 'company-gtags "company-gtags" "\ | |||
| `company-mode' completion backend for GNU Global. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-ispell" "company-ispell.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-ispell.el | |||
| (autoload 'company-ispell "company-ispell" "\ | |||
| `company-mode' completion backend using Ispell. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-keywords" "company-keywords.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-keywords.el | |||
| (autoload 'company-keywords "company-keywords" "\ | |||
| `company-mode' backend for programming language keywords. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-nxml" "company-nxml.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-nxml.el | |||
| (autoload 'company-nxml "company-nxml" "\ | |||
| `company-mode' completion backend for `nxml-mode'. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-oddmuse" "company-oddmuse.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-oddmuse.el | |||
| (autoload 'company-oddmuse "company-oddmuse" "\ | |||
| `company-mode' completion backend for `oddmuse-mode'. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-semantic" "company-semantic.el" (22223 | |||
| ;;;;;; 33912 0 0)) | |||
| ;;; Generated autoloads from company-semantic.el | |||
| (autoload 'company-semantic "company-semantic" "\ | |||
| `company-mode' completion backend using CEDET Semantic. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-tempo" "company-tempo.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-tempo.el | |||
| (autoload 'company-tempo "company-tempo" "\ | |||
| `company-mode' completion backend for tempo. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-xcode" "company-xcode.el" (22223 33912 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from company-xcode.el | |||
| (autoload 'company-xcode "company-xcode" "\ | |||
| `company-mode' completion backend for Xcode projects. | |||
| \(fn COMMAND &optional ARG &rest IGNORED)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil "company-yasnippet" "company-yasnippet.el" | |||
| ;;;;;; (22223 33912 0 0)) | |||
| ;;; Generated autoloads from company-yasnippet.el | |||
| (autoload 'company-yasnippet "company-yasnippet" "\ | |||
| `company-mode' backend for `yasnippet'. | |||
| 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 backend or | |||
| several that provide actual text completions. | |||
| (add-hook 'js-mode-hook | |||
| (lambda () | |||
| (set (make-local-variable 'company-backends) | |||
| '((company-dabbrev-code company-yasnippet))))) | |||
| * After keyword `:with', grouped with other 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) | |||
| \(fn COMMAND &optional ARG &rest IGNORE)" t nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil nil ("company-capf.el" "company-clang.el" "company-cmake.el" | |||
| ;;;;;; "company-eclim.el" "company-pkg.el" "company-template.el") | |||
| ;;;;;; (22223 33913 41216 0)) | |||
| ;;;*** | |||
| ;; Local Variables: | |||
| ;; version-control: never | |||
| ;; no-byte-compile: t | |||
| ;; no-update-autoloads: t | |||
| ;; End: | |||
| ;;; company-autoloads.el ends here | |||
| @ -0,0 +1,61 @@ | |||
| ;;; company-bbdb.el --- company-mode completion backend for BBDB in message-mode | |||
| ;; Copyright (C) 2013-2014, 2016 Free Software Foundation, Inc. | |||
| ;; Author: Jan Tatarik <jan.tatarik@gmail.com> | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (declare-function bbdb-record-get-field "bbdb") | |||
| (declare-function bbdb-records "bbdb") | |||
| (declare-function bbdb-dwim-mail "bbdb-com") | |||
| (declare-function bbdb-search "bbdb-com") | |||
| (defgroup company-bbdb nil | |||
| "Completion backend for BBDB." | |||
| :group 'company) | |||
| (defcustom company-bbdb-modes '(message-mode) | |||
| "Major modes in which `company-bbdb' may complete." | |||
| :type '(repeat (symbol :tag "Major mode")) | |||
| :package-version '(company . "0.8.8")) | |||
| (defun company-bbdb--candidates (arg) | |||
| (cl-mapcan (lambda (record) | |||
| (mapcar (lambda (mail) (bbdb-dwim-mail record mail)) | |||
| (bbdb-record-get-field record 'mail))) | |||
| (eval '(bbdb-search (bbdb-records) arg nil arg)))) | |||
| ;;;###autoload | |||
| (defun company-bbdb (command &optional arg &rest ignore) | |||
| "`company-mode' completion backend for BBDB." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-bbdb)) | |||
| (prefix (and (memq major-mode company-bbdb-modes) | |||
| (featurep 'bbdb-com) | |||
| (looking-back "^\\(To\\|Cc\\|Bcc\\): *.*?\\([^,; ]*\\)" | |||
| (line-beginning-position)) | |||
| (match-string-no-properties 2))) | |||
| (candidates (company-bbdb--candidates arg)) | |||
| (sorted t) | |||
| (no-cache t))) | |||
| (provide 'company-bbdb) | |||
| ;;; company-bbdb.el ends here | |||
| @ -0,0 +1,167 @@ | |||
| ;;; company-capf.el --- company-mode completion-at-point-functions backend -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2013-2016 Free Software Foundation, Inc. | |||
| ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defvar company--capf-cache nil) | |||
| (defun company--capf-data () | |||
| (let ((cache company--capf-cache)) | |||
| (if (and (equal (current-buffer) (car cache)) | |||
| (equal (point) (car (setq cache (cdr cache)))) | |||
| (equal (buffer-chars-modified-tick) (car (setq cache (cdr cache))))) | |||
| (cadr cache) | |||
| (let ((data (company--capf-data-real))) | |||
| (setq company--capf-cache | |||
| (list (current-buffer) (point) (buffer-chars-modified-tick) data)) | |||
| data)))) | |||
| (defun company--capf-data-real () | |||
| (cl-letf* (((default-value 'completion-at-point-functions) | |||
| ;; Ignore tags-completion-at-point-function because it subverts | |||
| ;; company-etags in the default value of company-backends, where | |||
| ;; the latter comes later. | |||
| (remove 'tags-completion-at-point-function | |||
| (default-value 'completion-at-point-functions))) | |||
| (completion-at-point-functions (company--capf-workaround)) | |||
| (data (run-hook-wrapped 'completion-at-point-functions | |||
| ;; Ignore misbehaving functions. | |||
| #'completion--capf-wrapper 'optimist))) | |||
| (when (and (consp (cdr data)) (integer-or-marker-p (nth 1 data))) data))) | |||
| (declare-function python-shell-get-process "python") | |||
| (defun company--capf-workaround () | |||
| ;; For http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18067 | |||
| (if (or (not (listp completion-at-point-functions)) | |||
| (not (memq 'python-completion-complete-at-point completion-at-point-functions)) | |||
| (python-shell-get-process)) | |||
| completion-at-point-functions | |||
| (remq 'python-completion-complete-at-point completion-at-point-functions))) | |||
| (defun company-capf (command &optional arg &rest _args) | |||
| "`company-mode' backend using `completion-at-point-functions'." | |||
| (interactive (list 'interactive)) | |||
| (pcase command | |||
| (`interactive (company-begin-backend 'company-capf)) | |||
| (`prefix | |||
| (let ((res (company--capf-data))) | |||
| (when res | |||
| (let ((length (plist-get (nthcdr 4 res) :company-prefix-length)) | |||
| (prefix (buffer-substring-no-properties (nth 1 res) (point)))) | |||
| (cond | |||
| ((> (nth 2 res) (point)) 'stop) | |||
| (length (cons prefix length)) | |||
| (t prefix)))))) | |||
| (`candidates | |||
| (let ((res (company--capf-data))) | |||
| (when res | |||
| (let* ((table (nth 3 res)) | |||
| (pred (plist-get (nthcdr 4 res) :predicate)) | |||
| (meta (completion-metadata | |||
| (buffer-substring (nth 1 res) (nth 2 res)) | |||
| table pred)) | |||
| (sortfun (cdr (assq 'display-sort-function meta))) | |||
| (candidates (completion-all-completions arg table pred (length arg))) | |||
| (last (last candidates)) | |||
| (base-size (and (numberp (cdr last)) (cdr last)))) | |||
| (when base-size | |||
| (setcdr last nil)) | |||
| (when sortfun | |||
| (setq candidates (funcall sortfun candidates))) | |||
| (if (not (zerop (or base-size 0))) | |||
| (let ((before (substring arg 0 base-size))) | |||
| (mapcar (lambda (candidate) | |||
| (concat before candidate)) | |||
| candidates)) | |||
| candidates))))) | |||
| (`sorted | |||
| (let ((res (company--capf-data))) | |||
| (when res | |||
| (let ((meta (completion-metadata | |||
| (buffer-substring (nth 1 res) (nth 2 res)) | |||
| (nth 3 res) (plist-get (nthcdr 4 res) :predicate)))) | |||
| (cdr (assq 'display-sort-function meta)))))) | |||
| (`match | |||
| ;; Can't just use 0 when base-size (see above) is non-zero. | |||
| (let ((start (if (get-text-property 0 'font-lock-face arg) | |||
| 0 | |||
| (next-single-property-change 0 'font-lock-face arg)))) | |||
| (when start | |||
| ;; completions-common-part comes first, but we can't just look for this | |||
| ;; value because it can be in a list. | |||
| (or | |||
| (let ((value (get-text-property start 'font-lock-face arg))) | |||
| (text-property-not-all start (length arg) | |||
| 'font-lock-face value arg)) | |||
| (length arg))))) | |||
| (`duplicates t) | |||
| (`no-cache t) ;Not much can be done here, as long as we handle | |||
| ;non-prefix matches. | |||
| (`meta | |||
| (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-docsig))) | |||
| (when f (funcall f arg)))) | |||
| (`doc-buffer | |||
| (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-doc-buffer))) | |||
| (when f (funcall f arg)))) | |||
| (`location | |||
| (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-location))) | |||
| (when f (funcall f arg)))) | |||
| (`annotation | |||
| (save-excursion | |||
| ;; FIXME: `company-begin' sets `company-point' after calling | |||
| ;; `company--begin-new'. We shouldn't rely on `company-point' here, | |||
| ;; better to cache the capf-data value instead. However: we can't just | |||
| ;; save the last capf-data value in `prefix', because that command can | |||
| ;; get called more often than `candidates', and at any point in the | |||
| ;; buffer (https://github.com/company-mode/company-mode/issues/153). | |||
| ;; We could try propertizing the returned prefix string, but it's not | |||
| ;; passed to `annotation', and `company-prefix' is set only after | |||
| ;; `company--strip-duplicates' is called. | |||
| (when company-point | |||
| (goto-char company-point)) | |||
| (let ((f (plist-get (nthcdr 4 (company--capf-data)) :annotation-function))) | |||
| (when f (funcall f arg))))) | |||
| (`require-match | |||
| (plist-get (nthcdr 4 (company--capf-data)) :company-require-match)) | |||
| (`init nil) ;Don't bother: plenty of other ways to initialize the code. | |||
| (`post-completion | |||
| (let* ((res (company--capf-data)) | |||
| (exit-function (plist-get (nthcdr 4 res) :exit-function)) | |||
| (table (nth 3 res)) | |||
| (pred (plist-get (nthcdr 4 res) :predicate))) | |||
| (if exit-function | |||
| ;; Follow the example of `completion--done'. | |||
| (funcall exit-function arg | |||
| (if (eq (try-completion arg table pred) t) | |||
| 'finished 'sole))))) | |||
| )) | |||
| (provide 'company-capf) | |||
| ;;; company-capf.el ends here | |||
| @ -0,0 +1,331 @@ | |||
| ;;; company-clang.el --- company-mode completion backend for Clang -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2009, 2011, 2013-2016 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'company-template) | |||
| (require 'cl-lib) | |||
| (defgroup company-clang nil | |||
| "Completion backend for Clang." | |||
| :group 'company) | |||
| (defcustom company-clang-executable | |||
| (executable-find "clang") | |||
| "Location of clang executable." | |||
| :type 'file) | |||
| (defcustom company-clang-begin-after-member-access t | |||
| "When non-nil, automatic completion will start whenever the current | |||
| symbol is preceded by \".\", \"->\" or \"::\", ignoring | |||
| `company-minimum-prefix-length'. | |||
| If `company-begin-commands' is a list, it should include `c-electric-lt-gt' | |||
| and `c-electric-colon', for automatic completion right after \">\" and | |||
| \":\".") | |||
| (defcustom company-clang-arguments nil | |||
| "Additional arguments to pass to clang when completing. | |||
| Prefix files (-include ...) can be selected with `company-clang-set-prefix' | |||
| or automatically through a custom `company-clang-prefix-guesser'." | |||
| :type '(repeat (string :tag "Argument"))) | |||
| (defcustom company-clang-prefix-guesser 'company-clang-guess-prefix | |||
| "A function to determine the prefix file for the current buffer." | |||
| :type '(function :tag "Guesser function" nil)) | |||
| (defvar company-clang-modes '(c-mode c++-mode objc-mode) | |||
| "Major modes which clang may complete.") | |||
| (defcustom company-clang-insert-arguments t | |||
| "When non-nil, insert function arguments as a template after completion." | |||
| :type 'boolean | |||
| :package-version '(company . "0.8.0")) | |||
| ;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defvar company-clang--prefix nil) | |||
| (defsubst company-clang--guess-pch-file (file) | |||
| (let ((dir (directory-file-name (file-name-directory file)))) | |||
| (when (equal (file-name-nondirectory dir) "Classes") | |||
| (setq dir (file-name-directory dir))) | |||
| (car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t)))) | |||
| (defsubst company-clang--file-substring (file beg end) | |||
| (with-temp-buffer | |||
| (insert-file-contents-literally file nil beg end) | |||
| (buffer-string))) | |||
| (defun company-clang-guess-prefix () | |||
| "Try to guess the prefix file for the current buffer." | |||
| ;; Prefixes seem to be called .pch. Pre-compiled headers do, too. | |||
| ;; So we look at the magic number to rule them out. | |||
| (let* ((file (company-clang--guess-pch-file buffer-file-name)) | |||
| (magic-number (and file (company-clang--file-substring file 0 4)))) | |||
| (unless (member magic-number '("CPCH" "gpch")) | |||
| file))) | |||
| (defun company-clang-set-prefix (&optional prefix) | |||
| "Use PREFIX as a prefix (-include ...) file for clang completion." | |||
| (interactive (let ((def (funcall company-clang-prefix-guesser))) | |||
| (unless (stringp def) | |||
| (setq def default-directory)) | |||
| (list (read-file-name "Prefix file: " | |||
| (when def (file-name-directory def)) | |||
| def t (when def (file-name-nondirectory def)))))) | |||
| ;; TODO: pre-compile? | |||
| (setq company-clang--prefix (and (stringp prefix) | |||
| (file-regular-p prefix) | |||
| prefix))) | |||
| ;; Clean-up on exit. | |||
| (add-hook 'kill-emacs-hook 'company-clang-set-prefix) | |||
| ;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| ;; TODO: Handle Pattern (syntactic hints would be neat). | |||
| ;; Do we ever see OVERLOAD (or OVERRIDE)? | |||
| (defconst company-clang--completion-pattern | |||
| "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$") | |||
| (defconst company-clang--error-buffer-name "*clang-error*") | |||
| (defun company-clang--lang-option () | |||
| (if (eq major-mode 'objc-mode) | |||
| (if (string= "m" (file-name-extension buffer-file-name)) | |||
| "objective-c" "objective-c++") | |||
| (substring (symbol-name major-mode) 0 -5))) | |||
| (defun company-clang--parse-output (prefix _objc) | |||
| (goto-char (point-min)) | |||
| (let ((pattern (format company-clang--completion-pattern | |||
| (regexp-quote prefix))) | |||
| (case-fold-search nil) | |||
| lines match) | |||
| (while (re-search-forward pattern nil t) | |||
| (setq match (match-string-no-properties 1)) | |||
| (unless (equal match "Pattern") | |||
| (save-match-data | |||
| (when (string-match ":" match) | |||
| (setq match (substring match 0 (match-beginning 0))))) | |||
| (let ((meta (match-string-no-properties 2))) | |||
| (when (and meta (not (string= match meta))) | |||
| (put-text-property 0 1 'meta | |||
| (company-clang--strip-formatting meta) | |||
| match))) | |||
| (push match lines))) | |||
| lines)) | |||
| (defun company-clang--meta (candidate) | |||
| (get-text-property 0 'meta candidate)) | |||
| (defun company-clang--annotation (candidate) | |||
| (let ((ann (company-clang--annotation-1 candidate))) | |||
| (if (not (and ann (string-prefix-p "(*)" ann))) | |||
| ann | |||
| (with-temp-buffer | |||
| (insert ann) | |||
| (search-backward ")") | |||
| (let ((pt (1+ (point)))) | |||
| (re-search-forward ".\\_>" nil t) | |||
| (delete-region pt (point))) | |||
| (buffer-string))))) | |||
| (defun company-clang--annotation-1 (candidate) | |||
| (let ((meta (company-clang--meta candidate))) | |||
| (cond | |||
| ((null meta) nil) | |||
| ((string-match "[^:]:[^:]" meta) | |||
| (substring meta (1+ (match-beginning 0)))) | |||
| ((string-match "\\((.*)[ a-z]*\\'\\)" meta) | |||
| (let ((paren (match-beginning 1))) | |||
| (if (not (eq (aref meta (1- paren)) ?>)) | |||
| (match-string 1 meta) | |||
| (with-temp-buffer | |||
| (insert meta) | |||
| (goto-char paren) | |||
| (substring meta (1- (search-backward "<")))))))))) | |||
| (defun company-clang--strip-formatting (text) | |||
| (replace-regexp-in-string | |||
| "#]" " " | |||
| (replace-regexp-in-string "[<{[]#\\|#[>}]" "" text t) | |||
| t)) | |||
| (defun company-clang--handle-error (res args) | |||
| (goto-char (point-min)) | |||
| (let* ((buf (get-buffer-create company-clang--error-buffer-name)) | |||
| (cmd (concat company-clang-executable " " (mapconcat 'identity args " "))) | |||
| (pattern (format company-clang--completion-pattern "")) | |||
| (err (if (re-search-forward pattern nil t) | |||
| (buffer-substring-no-properties (point-min) | |||
| (1- (match-beginning 0))) | |||
| ;; Warn the user more aggressively if no match was found. | |||
| (message "clang failed with error %d:\n%s" res cmd) | |||
| (buffer-string)))) | |||
| (with-current-buffer buf | |||
| (let ((inhibit-read-only t)) | |||
| (erase-buffer) | |||
| (insert (current-time-string) | |||
| (format "\nclang failed with error %d:\n" res) | |||
| cmd "\n\n") | |||
| (insert err) | |||
| (setq buffer-read-only t) | |||
| (goto-char (point-min)))))) | |||
| (defun company-clang--start-process (prefix callback &rest args) | |||
| (let ((objc (derived-mode-p 'objc-mode)) | |||
| (buf (get-buffer-create "*clang-output*")) | |||
| ;; Looks unnecessary in Emacs 25.1 and later. | |||
| (process-adaptive-read-buffering nil)) | |||
| (if (get-buffer-process buf) | |||
| (funcall callback nil) | |||
| (with-current-buffer buf | |||
| (erase-buffer) | |||
| (setq buffer-undo-list t)) | |||
| (let ((process (apply #'start-process "company-clang" buf | |||
| company-clang-executable args))) | |||
| (set-process-sentinel | |||
| process | |||
| (lambda (proc status) | |||
| (unless (string-match-p "hangup" status) | |||
| (funcall | |||
| callback | |||
| (let ((res (process-exit-status proc))) | |||
| (with-current-buffer buf | |||
| (unless (eq 0 res) | |||
| (company-clang--handle-error res args)) | |||
| ;; Still try to get any useful input. | |||
| (company-clang--parse-output prefix objc))))))) | |||
| (unless (company-clang--auto-save-p) | |||
| (send-region process (point-min) (point-max)) | |||
| (send-string process "\n") | |||
| (process-send-eof process)))))) | |||
| (defsubst company-clang--build-location (pos) | |||
| (save-excursion | |||
| (goto-char pos) | |||
| (format "%s:%d:%d" | |||
| (if (company-clang--auto-save-p) buffer-file-name "-") | |||
| (line-number-at-pos) | |||
| (1+ (length | |||
| (encode-coding-region | |||
| (line-beginning-position) | |||
| (point) | |||
| 'utf-8 | |||
| t)))))) | |||
| (defsubst company-clang--build-complete-args (pos) | |||
| (append '("-fsyntax-only" "-Xclang" "-code-completion-macros") | |||
| (unless (company-clang--auto-save-p) | |||
| (list "-x" (company-clang--lang-option))) | |||
| company-clang-arguments | |||
| (when (stringp company-clang--prefix) | |||
| (list "-include" (expand-file-name company-clang--prefix))) | |||
| (list "-Xclang" (format "-code-completion-at=%s" | |||
| (company-clang--build-location pos))) | |||
| (list (if (company-clang--auto-save-p) buffer-file-name "-")))) | |||
| (defun company-clang--candidates (prefix callback) | |||
| (and (company-clang--auto-save-p) | |||
| (buffer-modified-p) | |||
| (basic-save-buffer)) | |||
| (when (null company-clang--prefix) | |||
| (company-clang-set-prefix (or (funcall company-clang-prefix-guesser) | |||
| 'none))) | |||
| (apply 'company-clang--start-process | |||
| prefix | |||
| callback | |||
| (company-clang--build-complete-args (- (point) (length prefix))))) | |||
| (defun company-clang--prefix () | |||
| (if company-clang-begin-after-member-access | |||
| (company-grab-symbol-cons "\\.\\|->\\|::" 2) | |||
| (company-grab-symbol))) | |||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defconst company-clang-required-version 1.1) | |||
| (defvar company-clang--version nil) | |||
| (defun company-clang--auto-save-p () | |||
| (< company-clang--version 2.9)) | |||
| (defsubst company-clang-version () | |||
| "Return the version of `company-clang-executable'." | |||
| (with-temp-buffer | |||
| (call-process company-clang-executable nil t nil "--version") | |||
| (goto-char (point-min)) | |||
| (if (re-search-forward "clang\\(?: version \\|-\\)\\([0-9.]+\\)" nil t) | |||
| (let ((ver (string-to-number (match-string-no-properties 1)))) | |||
| (if (> ver 100) | |||
| (/ ver 100) | |||
| ver)) | |||
| 0))) | |||
| (defun company-clang (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for Clang. | |||
| Clang is a parser for C and ObjC. Clang version 1.1 or newer is required. | |||
| Additional command line arguments can be specified in | |||
| `company-clang-arguments'. Prefix files (-include ...) can be selected | |||
| with `company-clang-set-prefix' or automatically through a custom | |||
| `company-clang-prefix-guesser'. | |||
| With Clang versions before 2.9, we have to save the buffer before | |||
| performing completion. With Clang 2.9 and later, buffer contents are | |||
| passed via standard input." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-clang)) | |||
| (init (when (memq major-mode company-clang-modes) | |||
| (unless company-clang-executable | |||
| (error "Company found no clang executable")) | |||
| (setq company-clang--version (company-clang-version)) | |||
| (when (< company-clang--version company-clang-required-version) | |||
| (error "Company requires clang version 1.1")))) | |||
| (prefix (and (memq major-mode company-clang-modes) | |||
| buffer-file-name | |||
| company-clang-executable | |||
| (not (company-in-string-or-comment)) | |||
| (or (company-clang--prefix) 'stop))) | |||
| (candidates (cons :async | |||
| (lambda (cb) (company-clang--candidates arg cb)))) | |||
| (meta (company-clang--meta arg)) | |||
| (annotation (company-clang--annotation arg)) | |||
| (post-completion (let ((anno (company-clang--annotation arg))) | |||
| (when (and company-clang-insert-arguments anno) | |||
| (insert anno) | |||
| (if (string-match "\\`:[^:]" anno) | |||
| (company-template-objc-templatify anno) | |||
| (company-template-c-like-templatify | |||
| (concat arg anno)))))))) | |||
| (provide 'company-clang) | |||
| ;;; company-clang.el ends here | |||
| @ -0,0 +1,198 @@ | |||
| ;;; company-cmake.el --- company-mode completion backend for CMake | |||
| ;; Copyright (C) 2013-2014 Free Software Foundation, Inc. | |||
| ;; Author: Chen Bin <chenbin DOT sh AT gmail> | |||
| ;; Version: 0.2 | |||
| ;; This program is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;; company-cmake offers completions for module names, variable names and | |||
| ;; commands used by CMake. And their descriptions. | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defgroup company-cmake nil | |||
| "Completion backend for CMake." | |||
| :group 'company) | |||
| (defcustom company-cmake-executable | |||
| (executable-find "cmake") | |||
| "Location of cmake executable." | |||
| :type 'file) | |||
| (defvar company-cmake-executable-arguments | |||
| '("--help-command-list" | |||
| "--help-module-list" | |||
| "--help-variable-list") | |||
| "The arguments we pass to cmake, separately. | |||
| They affect which types of symbols we get completion candidates for.") | |||
| (defvar company-cmake--completion-pattern | |||
| "^\\(%s[a-zA-Z0-9_<>]%s\\)$" | |||
| "Regexp to match the candidates.") | |||
| (defvar company-cmake-modes '(cmake-mode) | |||
| "Major modes in which cmake may complete.") | |||
| (defvar company-cmake--candidates-cache nil | |||
| "Cache for the raw candidates.") | |||
| (defvar company-cmake--meta-command-cache nil | |||
| "Cache for command arguments to retrieve descriptions for the candidates.") | |||
| (defun company-cmake--replace-tags (rlt) | |||
| (setq rlt (replace-regexp-in-string | |||
| "\\(.*?\\(IS_GNU\\)?\\)<LANG>\\(.*\\)" | |||
| (lambda (_match) | |||
| (mapconcat 'identity | |||
| (if (match-beginning 2) | |||
| '("\\1CXX\\3" "\\1C\\3" "\\1G77\\3") | |||
| '("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3")) | |||
| "\n")) | |||
| rlt t)) | |||
| (setq rlt (replace-regexp-in-string | |||
| "\\(.*\\)<CONFIG>\\(.*\\)" | |||
| (mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2" | |||
| "\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2") | |||
| "\n") | |||
| rlt)) | |||
| rlt) | |||
| (defun company-cmake--fill-candidates-cache (arg) | |||
| "Fill candidates cache if needed." | |||
| (let (rlt) | |||
| (unless company-cmake--candidates-cache | |||
| (setq company-cmake--candidates-cache (make-hash-table :test 'equal))) | |||
| ;; If hash is empty, fill it. | |||
| (unless (gethash arg company-cmake--candidates-cache) | |||
| (with-temp-buffer | |||
| (let ((res (call-process company-cmake-executable nil t nil arg))) | |||
| (unless (zerop res) | |||
| (message "cmake executable exited with error=%d" res))) | |||
| (setq rlt (buffer-string))) | |||
| (setq rlt (company-cmake--replace-tags rlt)) | |||
| (puthash arg rlt company-cmake--candidates-cache)) | |||
| )) | |||
| (defun company-cmake--parse (prefix content cmd) | |||
| (let ((start 0) | |||
| (pattern (format company-cmake--completion-pattern | |||
| (regexp-quote prefix) | |||
| (if (zerop (length prefix)) "+" "*"))) | |||
| (lines (split-string content "\n")) | |||
| match | |||
| rlt) | |||
| (dolist (line lines) | |||
| (when (string-match pattern line) | |||
| (let ((match (match-string 1 line))) | |||
| (when match | |||
| (puthash match cmd company-cmake--meta-command-cache) | |||
| (push match rlt))))) | |||
| rlt)) | |||
| (defun company-cmake--candidates (prefix) | |||
| (let (results | |||
| cmd-opts | |||
| str) | |||
| (unless company-cmake--meta-command-cache | |||
| (setq company-cmake--meta-command-cache (make-hash-table :test 'equal))) | |||
| (dolist (arg company-cmake-executable-arguments) | |||
| (company-cmake--fill-candidates-cache arg) | |||
| (setq cmd-opts (replace-regexp-in-string "-list$" "" arg) ) | |||
| (setq str (gethash arg company-cmake--candidates-cache)) | |||
| (when str | |||
| (setq results (nconc results | |||
| (company-cmake--parse prefix str cmd-opts))))) | |||
| results)) | |||
| (defun company-cmake--unexpand-candidate (candidate) | |||
| (cond | |||
| ((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate) | |||
| (setq candidate (concat "CMAKE_<LANG>" (match-string 2 candidate)))) | |||
| ;; C flags | |||
| ((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate) | |||
| (setq candidate (concat (match-string 1 candidate) "IS_GNU<LANG>"))) | |||
| ;; C flags | |||
| ((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate) | |||
| (setq candidate (concat (match-string 1 candidate) "OVERRIDE_<LANG>"))) | |||
| ((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate) | |||
| (setq candidate (concat (match-string 1 candidate) | |||
| "_<CONFIG>" | |||
| (match-string 3 candidate))))) | |||
| candidate) | |||
| (defun company-cmake--meta (candidate) | |||
| (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)) | |||
| result) | |||
| (setq candidate (company-cmake--unexpand-candidate candidate)) | |||
| ;; Don't cache the documentation of every candidate (command) | |||
| ;; Cache in this case will cost too much memory. | |||
| (with-temp-buffer | |||
| (call-process company-cmake-executable nil t nil cmd-opts candidate) | |||
| ;; Go to the third line, trim it and return the result. | |||
| ;; Tested with cmake 2.8.9. | |||
| (goto-char (point-min)) | |||
| (forward-line 2) | |||
| (setq result (buffer-substring-no-properties (line-beginning-position) | |||
| (line-end-position))) | |||
| (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result)) | |||
| result))) | |||
| (defun company-cmake--doc-buffer (candidate) | |||
| (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))) | |||
| (setq candidate (company-cmake--unexpand-candidate candidate)) | |||
| (with-temp-buffer | |||
| (call-process company-cmake-executable nil t nil cmd-opts candidate) | |||
| ;; Go to the third line, trim it and return the doc buffer. | |||
| ;; Tested with cmake 2.8.9. | |||
| (goto-char (point-min)) | |||
| (forward-line 2) | |||
| (company-doc-buffer | |||
| (buffer-substring-no-properties (line-beginning-position) | |||
| (point-max)))))) | |||
| (defun company-cmake (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for CMake. | |||
| CMake is a cross-platform, open-source make system." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-cmake)) | |||
| (init (when (memq major-mode company-cmake-modes) | |||
| (unless company-cmake-executable | |||
| (error "Company found no cmake executable")))) | |||
| (prefix (and (memq major-mode company-cmake-modes) | |||
| (not (company-in-string-or-comment)) | |||
| (company-grab-symbol))) | |||
| (candidates (company-cmake--candidates arg)) | |||
| (meta (company-cmake--meta arg)) | |||
| (doc-buffer (company-cmake--doc-buffer arg)) | |||
| )) | |||
| (provide 'company-cmake) | |||
| ;;; company-cmake.el ends here | |||
| @ -0,0 +1,442 @@ | |||
| ;;; company-css.el --- company-mode completion backend for css-mode -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (declare-function web-mode-language-at-pos "web-mode" (&optional pos)) | |||
| (defconst company-css-property-alist | |||
| ;; see http://www.w3.org/TR/CSS21/propidx.html | |||
| '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center" | |||
| "center-right" "right" "far-right" "right-side" "behind" "leftwards" | |||
| "rightwards") | |||
| ("background" background-color background-image background-repeat | |||
| background-attachment background-position | |||
| background-clip background-origin background-size) | |||
| ("background-attachment" "scroll" "fixed") | |||
| ("background-color" color "transparent") | |||
| ("background-image" uri "none") | |||
| ("background-position" percentage length "left" "center" "right" percentage | |||
| length "top" "center" "bottom" "left" "center" "right" "top" "center" | |||
| "bottom") | |||
| ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat") | |||
| ("border" border-width border-style border-color) | |||
| ("border-bottom" border) | |||
| ("border-bottom-color" border-color) | |||
| ("border-bottom-style" border-style) | |||
| ("border-bottom-width" border-width) | |||
| ("border-collapse" "collapse" "separate") | |||
| ("border-color" color "transparent") | |||
| ("border-left" border) | |||
| ("border-left-color" border-color) | |||
| ("border-left-style" border-style) | |||
| ("border-left-width" border-width) | |||
| ("border-right" border) | |||
| ("border-right-color" border-color) | |||
| ("border-right-style" border-style) | |||
| ("border-right-width" border-width) | |||
| ("border-spacing" length length) | |||
| ("border-style" border-style) | |||
| ("border-top" border) | |||
| ("border-top-color" border-color) | |||
| ("border-top-style" border-style) | |||
| ("border-top-width" border-width) | |||
| ("border-width" border-width) | |||
| ("bottom" length percentage "auto") | |||
| ("caption-side" "top" "bottom") | |||
| ("clear" "none" "left" "right" "both") | |||
| ("clip" shape "auto") | |||
| ("color" color) | |||
| ("content" "normal" "none" string uri counter "attr()" "open-quote" | |||
| "close-quote" "no-open-quote" "no-close-quote") | |||
| ("counter-increment" identifier integer "none") | |||
| ("counter-reset" identifier integer "none") | |||
| ("cue" cue-before cue-after) | |||
| ("cue-after" uri "none") | |||
| ("cue-before" uri "none") | |||
| ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize" | |||
| "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize" | |||
| "w-resize" "text" "wait" "help" "progress") | |||
| ("direction" "ltr" "rtl") | |||
| ("display" "inline" "block" "list-item" "run-in" "inline-block" "table" | |||
| "inline-table" "table-row-group" "table-header-group" "table-footer-group" | |||
| "table-row" "table-column-group" "table-column" "table-cell" | |||
| "table-caption" "none") | |||
| ("elevation" angle "below" "level" "above" "higher" "lower") | |||
| ("empty-cells" "show" "hide") | |||
| ("float" "left" "right" "none") | |||
| ("font" font-style font-weight font-size "/" line-height | |||
| font-family "caption" "icon" "menu" "message-box" "small-caption" | |||
| "status-bar" "normal" "small-caps" | |||
| ;; CSS3 | |||
| font-stretch) | |||
| ("font-family" family-name generic-family) | |||
| ("font-size" absolute-size relative-size length percentage) | |||
| ("font-style" "normal" "italic" "oblique") | |||
| ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400" | |||
| "500" "600" "700" "800" "900") | |||
| ("height" length percentage "auto") | |||
| ("left" length percentage "auto") | |||
| ("letter-spacing" "normal" length) | |||
| ("line-height" "normal" number length percentage) | |||
| ("list-style" list-style-type list-style-position list-style-image) | |||
| ("list-style-image" uri "none") | |||
| ("list-style-position" "inside" "outside") | |||
| ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero" | |||
| "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin" | |||
| "armenian" "georgian" "lower-alpha" "upper-alpha" "none") | |||
| ("margin" margin-width) | |||
| ("margin-bottom" margin-width) | |||
| ("margin-left" margin-width) | |||
| ("margin-right" margin-width) | |||
| ("margin-top" margin-width) | |||
| ("max-height" length percentage "none") | |||
| ("max-width" length percentage "none") | |||
| ("min-height" length percentage) | |||
| ("min-width" length percentage) | |||
| ("orphans" integer) | |||
| ("outline" outline-color outline-style outline-width) | |||
| ("outline-color" color "invert") | |||
| ("outline-style" border-style) | |||
| ("outline-width" border-width) | |||
| ("overflow" "visible" "hidden" "scroll" "auto" | |||
| ;; CSS3: | |||
| "no-display" "no-content") | |||
| ("padding" padding-width) | |||
| ("padding-bottom" padding-width) | |||
| ("padding-left" padding-width) | |||
| ("padding-right" padding-width) | |||
| ("padding-top" padding-width) | |||
| ("page-break-after" "auto" "always" "avoid" "left" "right") | |||
| ("page-break-before" "auto" "always" "avoid" "left" "right") | |||
| ("page-break-inside" "avoid" "auto") | |||
| ("pause" time percentage) | |||
| ("pause-after" time percentage) | |||
| ("pause-before" time percentage) | |||
| ("pitch" frequency "x-low" "low" "medium" "high" "x-high") | |||
| ("pitch-range" number) | |||
| ("play-during" uri "mix" "repeat" "auto" "none") | |||
| ("position" "static" "relative" "absolute" "fixed") | |||
| ("quotes" string string "none") | |||
| ("richness" number) | |||
| ("right" length percentage "auto") | |||
| ("speak" "normal" "none" "spell-out") | |||
| ("speak-header" "once" "always") | |||
| ("speak-numeral" "digits" "continuous") | |||
| ("speak-punctuation" "code" "none") | |||
| ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster" | |||
| "slower") | |||
| ("stress" number) | |||
| ("table-layout" "auto" "fixed") | |||
| ("text-align" "left" "right" "center" "justify") | |||
| ("text-indent" length percentage) | |||
| ("text-transform" "capitalize" "uppercase" "lowercase" "none") | |||
| ("top" length percentage "auto") | |||
| ("unicode-bidi" "normal" "embed" "bidi-override") | |||
| ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle" | |||
| "bottom" "text-bottom" percentage length) | |||
| ("visibility" "visible" "hidden" "collapse") | |||
| ("voice-family" specific-voice generic-voice "*" specific-voice | |||
| generic-voice) | |||
| ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud" | |||
| "x-loud") | |||
| ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line") | |||
| ("widows" integer) | |||
| ("width" length percentage "auto") | |||
| ("word-spacing" "normal" length) | |||
| ("z-index" "auto" integer) | |||
| ;; CSS3 | |||
| ("align-content" align-stretch "space-between" "space-around") | |||
| ("align-items" align-stretch "baseline") | |||
| ("align-self" align-items "auto") | |||
| ("animation" animation-name animation-duration animation-timing-function | |||
| animation-delay animation-iteration-count animation-direction | |||
| animation-fill-mode) | |||
| ("animation-delay" time) | |||
| ("animation-direction" "normal" "reverse" "alternate" "alternate-reverse") | |||
| ("animation-duration" time) | |||
| ("animation-fill-mode" "none" "forwards" "backwards" "both") | |||
| ("animation-iteration-count" integer "infinite") | |||
| ("animation-name" "none") | |||
| ("animation-play-state" "paused" "running") | |||
| ("animation-timing-function" transition-timing-function | |||
| "step-start" "step-end" "steps(,)") | |||
| ("backface-visibility" "visible" "hidden") | |||
| ("background-clip" background-origin) | |||
| ("background-origin" "border-box" "padding-box" "content-box") | |||
| ("background-size" length percentage "auto" "cover" "contain") | |||
| ("border-image" border-image-outset border-image-repeat border-image-source | |||
| border-image-slice border-image-width) | |||
| ("border-image-outset" length) | |||
| ("border-image-repeat" "stretch" "repeat" "round" "space") | |||
| ("border-image-source" uri "none") | |||
| ("border-image-slice" length) | |||
| ("border-image-width" length percentage) | |||
| ("border-radius" length) | |||
| ("border-top-left-radius" length) | |||
| ("border-top-right-radius" length) | |||
| ("border-bottom-left-radius" length) | |||
| ("border-bottom-right-radius" length) | |||
| ("box-decoration-break" "slice" "clone") | |||
| ("box-shadow" length color) | |||
| ("box-sizing" "content-box" "border-box") | |||
| ("break-after" "auto" "always" "avoid" "left" "right" "page" "column" | |||
| "avoid-page" "avoid-column") | |||
| ("break-before" break-after) | |||
| ("break-inside" "avoid" "auto") | |||
| ("columns" column-width column-count) | |||
| ("column-count" integer) | |||
| ("column-fill" "auto" "balance") | |||
| ("column-gap" length "normal") | |||
| ("column-rule" column-rule-width column-rule-style column-rule-color) | |||
| ("column-rule-color" color) | |||
| ("column-rule-style" border-style) | |||
| ("column-rule-width" border-width) | |||
| ("column-span" "all" "none") | |||
| ("column-width" length "auto") | |||
| ("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()" | |||
| "grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()") | |||
| ("flex" flex-grow flex-shrink flex-basis) | |||
| ("flex-basis" percentage length "auto") | |||
| ("flex-direction" "row" "row-reverse" "column" "column-reverse") | |||
| ("flex-flow" flex-direction flex-wrap) | |||
| ("flex-grow" number) | |||
| ("flex-shrink" number) | |||
| ("flex-wrap" "nowrap" "wrap" "wrap-reverse") | |||
| ("font-feature-setting" normal string number) | |||
| ("font-kerning" "auto" "normal" "none") | |||
| ("font-language-override" "normal" string) | |||
| ("font-size-adjust" "none" number) | |||
| ("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed" | |||
| "semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded") | |||
| ("font-synthesis" "none" "weight" "style") | |||
| ("font-variant" font-variant-alternates font-variant-caps | |||
| font-variant-east-asian font-variant-ligatures font-variant-numeric | |||
| font-variant-position) | |||
| ("font-variant-alternates" "normal" "historical-forms" "stylistic()" | |||
| "styleset()" "character-variant()" "swash()" "ornaments()" "annotation()") | |||
| ("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps" | |||
| "all-petite-caps" "unicase" "titling-caps") | |||
| ("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified" | |||
| "traditional" "full-width" "proportional-width" "ruby") | |||
| ("font-variant-ligatures" "normal" "none" "common-ligatures" | |||
| "no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures" | |||
| "historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual") | |||
| ("font-variant-numeric" "normal" "ordinal" "slashed-zero" | |||
| "lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums" | |||
| "diagonal-fractions" "stacked-fractions") | |||
| ("font-variant-position" "normal" "sub" "super") | |||
| ("hyphens" "none" "manual" "auto") | |||
| ("justify-content" align-common "space-between" "space-around") | |||
| ("line-break" "auto" "loose" "normal" "strict") | |||
| ("marquee-direction" "forward" "reverse") | |||
| ("marquee-play-count" integer "infinite") | |||
| ("marquee-speed" "slow" "normal" "fast") | |||
| ("marquee-style" "scroll" "slide" "alternate") | |||
| ("opacity" number) | |||
| ("order" number) | |||
| ("outline-offset" length) | |||
| ("overflow-x" overflow) | |||
| ("overflow-y" overflow) | |||
| ("overflow-style" "auto" "marquee-line" "marquee-block") | |||
| ("overflow-wrap" "normal" "break-word") | |||
| ("perspective" "none" length) | |||
| ("perspective-origin" percentage length "left" "center" "right" "top" "bottom") | |||
| ("resize" "none" "both" "horizontal" "vertical") | |||
| ("tab-size" integer length) | |||
| ("text-align-last" "auto" "start" "end" "left" "right" "center" "justify") | |||
| ("text-decoration" text-decoration-color text-decoration-line text-decoration-style) | |||
| ("text-decoration-color" color) | |||
| ("text-decoration-line" "none" "underline" "overline" "line-through" "blink") | |||
| ("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy") | |||
| ("text-overflow" "clip" "ellipsis") | |||
| ("text-shadow" color length) | |||
| ("text-underline-position" "auto" "under" "left" "right") | |||
| ("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()" | |||
| "scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none") | |||
| ("transform-origin" perspective-origin) | |||
| ("transform-style" "flat" "preserve-3d") | |||
| ("transition" transition-property transition-duration | |||
| transition-timing-function transition-delay) | |||
| ("transition-delay" time) | |||
| ("transition-duration" time) | |||
| ("transition-timing-function" | |||
| "ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)") | |||
| ("transition-property" "none" "all" identifier) | |||
| ("word-wrap" overflow-wrap) | |||
| ("word-break" "normal" "break-all" "keep-all")) | |||
| "A list of CSS properties and their possible values.") | |||
| (defconst company-css-value-classes | |||
| '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large" | |||
| "xx-large") | |||
| (align-common "flex-start" "flex-end" "center") | |||
| (align-stretch align-common "stretch") | |||
| (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove" | |||
| "ridge" "inset" "outset") | |||
| (border-width "thick" "medium" "thin") | |||
| (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy" | |||
| "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow") | |||
| (counter "counter(,)") | |||
| (family-name "Courier" "Helvetica" "Times") | |||
| (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace") | |||
| (generic-voice "male" "female" "child") | |||
| (margin-width "auto") ;; length percentage | |||
| (relative-size "larger" "smaller") | |||
| (shape "rect(,,,)") | |||
| (uri "url()")) | |||
| "A list of CSS property value classes and their contents.") | |||
| ;; missing, because not completable | |||
| ;; <angle><frequency><identifier><integer><length><number><padding-width> | |||
| ;; <percentage><specific-voice><string><time><uri> | |||
| (defconst company-css-html-tags | |||
| '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo" | |||
| "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code" | |||
| "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset" | |||
| "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr" | |||
| "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend" | |||
| "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol" | |||
| "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select" | |||
| "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td" | |||
| "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var" | |||
| ;; HTML5 | |||
| "section" "article" "aside" "header" "footer" "nav" "figure" "figcaption" | |||
| "time" "mark" "main") | |||
| "A list of HTML tags for use in CSS completion.") | |||
| (defconst company-css-pseudo-classes | |||
| '("active" "after" "before" "first" "first-child" "first-letter" "first-line" | |||
| "focus" "hover" "lang" "left" "link" "right" "visited") | |||
| "Identifiers for CSS pseudo-elements and pseudo-classes.") | |||
| (defconst company-css-property-cache (make-hash-table :size 115 :test 'equal)) | |||
| (defun company-css-property-values (attribute) | |||
| "Access the `company-css-property-alist' cached and flattened." | |||
| (or (gethash attribute company-css-property-cache) | |||
| (let (results) | |||
| (dolist (value (cdr (assoc attribute company-css-property-alist))) | |||
| (if (symbolp value) | |||
| (dolist (child (or (cdr (assoc value company-css-value-classes)) | |||
| (company-css-property-values | |||
| (symbol-name value)))) | |||
| (push child results)) | |||
| (push value results))) | |||
| (setq results (sort results 'string<)) | |||
| (puthash attribute | |||
| (if (fboundp 'delete-consecutive-dups) | |||
| (delete-consecutive-dups results) | |||
| (delete-dups results)) | |||
| company-css-property-cache) | |||
| results))) | |||
| ;;; bracket detection | |||
| (defconst company-css-braces-syntax-table | |||
| (let ((table (make-syntax-table))) | |||
| (setf (aref table ?{) '(4 . 125)) | |||
| (setf (aref table ?}) '(5 . 123)) | |||
| table) | |||
| "A syntax table giving { and } paren syntax.") | |||
| (defun company-css-inside-braces-p () | |||
| "Return non-nil, if point is within matched { and }." | |||
| (ignore-errors | |||
| (with-syntax-table company-css-braces-syntax-table | |||
| (let ((parse-sexp-ignore-comments t)) | |||
| (scan-lists (point) -1 1))))) | |||
| ;;; tags | |||
| (defconst company-css-tag-regexp | |||
| (concat "\\(?:\\`\\|}\\)[[:space:]]*" | |||
| ;; multiple | |||
| "\\(?:" | |||
| ;; previous tags: | |||
| "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?" | |||
| ;; space or selectors | |||
| "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)" | |||
| "\\)*" | |||
| "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)" | |||
| "\\=") | |||
| "A regular expression matching CSS tags.") | |||
| ;;; pseudo id | |||
| (defconst company-css-pseudo-regexp | |||
| (concat "\\(?:\\`\\|}\\)[[:space:]]*" | |||
| ;; multiple | |||
| "\\(?:" | |||
| ;; previous tags: | |||
| "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?" | |||
| ;; space or delimiters | |||
| "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)" | |||
| "\\)*" | |||
| "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):" | |||
| "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=") | |||
| "A regular expression matching CSS pseudo classes.") | |||
| ;;; properties | |||
| (defun company-css-grab-property () | |||
| "Return the CSS property before point, if any. | |||
| Returns \"\" if no property found, but feasible at this position." | |||
| (when (company-css-inside-braces-p) | |||
| (company-grab-symbol))) | |||
| ;;; values | |||
| (defconst company-css-property-value-regexp | |||
| "\\_<\\([[:alpha:]-]+\\):\\(?:[^{};]*[[:space:]]+\\)?\\([^{};]*\\_>\\|\\)\\=" | |||
| "A regular expression matching CSS tags.") | |||
| ;;;###autoload | |||
| (defun company-css (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for `css-mode'." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-css)) | |||
| (prefix (and (or (derived-mode-p 'css-mode) | |||
| (and (derived-mode-p 'web-mode) | |||
| (string= (web-mode-language-at-pos) "css"))) | |||
| (or (company-grab company-css-tag-regexp 1) | |||
| (company-grab company-css-pseudo-regexp 1) | |||
| (company-grab company-css-property-value-regexp 2) | |||
| (company-css-grab-property)))) | |||
| (candidates | |||
| (cond | |||
| ((company-grab company-css-tag-regexp 1) | |||
| (all-completions arg company-css-html-tags)) | |||
| ((company-grab company-css-pseudo-regexp 1) | |||
| (all-completions arg company-css-pseudo-classes)) | |||
| ((company-grab company-css-property-value-regexp 2) | |||
| (all-completions arg | |||
| (company-css-property-values | |||
| (company-grab company-css-property-value-regexp 1)))) | |||
| ((company-css-grab-property) | |||
| (all-completions arg company-css-property-alist)))) | |||
| (sorted t))) | |||
| (provide 'company-css) | |||
| ;;; company-css.el ends here | |||
| @ -0,0 +1,104 @@ | |||
| ;;; company-dabbrev-code.el --- dabbrev-like company-mode backend for code -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'company-dabbrev) | |||
| (require 'cl-lib) | |||
| (defgroup company-dabbrev-code nil | |||
| "dabbrev-like completion backend for code." | |||
| :group 'company) | |||
| (defcustom company-dabbrev-code-modes | |||
| '(prog-mode | |||
| batch-file-mode csharp-mode css-mode erlang-mode haskell-mode jde-mode | |||
| lua-mode python-mode) | |||
| "Modes that use `company-dabbrev-code'. | |||
| In all these modes (and their derivatives) `company-dabbrev-code' will | |||
| complete only symbols, not text in comments or strings. In other modes | |||
| `company-dabbrev-code' will pass control to other backends | |||
| \(e.g. `company-dabbrev'\). Value t means complete in all modes." | |||
| :type '(choice (repeat :tag "Some modes" (symbol :tag "Major mode")) | |||
| (const :tag "All modes" t))) | |||
| (defcustom company-dabbrev-code-other-buffers t | |||
| "Determines whether `company-dabbrev-code' should search other buffers. | |||
| If `all', search all other buffers, except the ignored ones. If t, search | |||
| buffers with the same major mode. If `code', search all buffers with major | |||
| modes in `company-dabbrev-code-modes', or derived from one of them. See | |||
| also `company-dabbrev-code-time-limit'." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "Same major mode" t) | |||
| (const :tag "Code major modes" code) | |||
| (const :tag "All" all))) | |||
| (defcustom company-dabbrev-code-time-limit .1 | |||
| "Determines how long `company-dabbrev-code' should look for matches." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (number :tag "Seconds"))) | |||
| (defcustom company-dabbrev-code-everywhere nil | |||
| "Non-nil to offer completions in comments and strings." | |||
| :type 'boolean) | |||
| (defcustom company-dabbrev-code-ignore-case nil | |||
| "Non-nil to ignore case when collecting completion candidates." | |||
| :type 'boolean) | |||
| (defun company-dabbrev-code--make-regexp (prefix) | |||
| (concat "\\_<" (if (equal prefix "") | |||
| "\\([a-zA-Z]\\|\\s_\\)" | |||
| (regexp-quote prefix)) | |||
| "\\(\\sw\\|\\s_\\)*\\_>")) | |||
| ;;;###autoload | |||
| (defun company-dabbrev-code (command &optional arg &rest ignored) | |||
| "dabbrev-like `company-mode' backend for code. | |||
| The backend looks for all symbols in the current buffer that aren't in | |||
| comments or strings." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-dabbrev-code)) | |||
| (prefix (and (or (eq t company-dabbrev-code-modes) | |||
| (apply #'derived-mode-p company-dabbrev-code-modes)) | |||
| (or company-dabbrev-code-everywhere | |||
| (not (company-in-string-or-comment))) | |||
| (or (company-grab-symbol) 'stop))) | |||
| (candidates (let ((case-fold-search company-dabbrev-code-ignore-case)) | |||
| (company-dabbrev--search | |||
| (company-dabbrev-code--make-regexp arg) | |||
| company-dabbrev-code-time-limit | |||
| (pcase company-dabbrev-code-other-buffers | |||
| (`t (list major-mode)) | |||
| (`code company-dabbrev-code-modes) | |||
| (`all `all)) | |||
| t))) | |||
| (ignore-case company-dabbrev-code-ignore-case) | |||
| (duplicates t))) | |||
| (provide 'company-dabbrev-code) | |||
| ;;; company-dabbrev-code.el ends here | |||
| @ -0,0 +1,188 @@ | |||
| ;;; company-dabbrev.el --- dabbrev-like company-mode completion backend -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2009, 2011, 2014, 2015 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defgroup company-dabbrev nil | |||
| "dabbrev-like completion backend." | |||
| :group 'company) | |||
| (defcustom company-dabbrev-other-buffers 'all | |||
| "Determines whether `company-dabbrev' should search other buffers. | |||
| If `all', search all other buffers, except the ignored ones. If t, search | |||
| buffers with the same major mode. See also `company-dabbrev-time-limit'." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "Same major mode" t) | |||
| (const :tag "All" all))) | |||
| (defcustom company-dabbrev-ignore-buffers "\\`[ *]" | |||
| "Regexp matching the names of buffers to ignore." | |||
| :type 'regexp) | |||
| (defcustom company-dabbrev-time-limit .1 | |||
| "Determines how many seconds `company-dabbrev' should look for matches." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (number :tag "Seconds"))) | |||
| (defcustom company-dabbrev-char-regexp "\\sw" | |||
| "A regular expression matching the characters `company-dabbrev' looks for." | |||
| :type 'regexp) | |||
| (defcustom company-dabbrev-ignore-case 'keep-prefix | |||
| "Non-nil to ignore case when collecting completion candidates. | |||
| When it's `keep-prefix', the text before point will remain unchanged after | |||
| candidate is inserted, even some of its characters have different case.") | |||
| (defcustom company-dabbrev-downcase 'case-replace | |||
| "Whether to downcase the returned candidates. | |||
| The value of nil means keep them as-is. | |||
| `case-replace' means use the value of `case-replace'. | |||
| Any other value means downcase. | |||
| If you set this value to nil, you may also want to set | |||
| `company-dabbrev-ignore-case' to any value other than `keep-prefix'.") | |||
| (defcustom company-dabbrev-minimum-length 4 | |||
| "The minimum length for the completion candidate to be included. | |||
| This variable affects both `company-dabbrev' and `company-dabbrev-code'." | |||
| :type 'integer | |||
| :package-version '(company . "0.8.3")) | |||
| (defcustom company-dabbrev-ignore-invisible nil | |||
| "Non-nil to skip invisible text." | |||
| :type 'boolean | |||
| :package-version '(company . "0.9.0")) | |||
| (defmacro company-dabrev--time-limit-while (test start limit &rest body) | |||
| (declare (indent 3) (debug t)) | |||
| `(let ((company-time-limit-while-counter 0)) | |||
| (catch 'done | |||
| (while ,test | |||
| ,@body | |||
| (and ,limit | |||
| (eq (cl-incf company-time-limit-while-counter) 25) | |||
| (setq company-time-limit-while-counter 0) | |||
| (> (float-time (time-since ,start)) ,limit) | |||
| (throw 'done 'company-time-out)))))) | |||
| (defun company-dabbrev--make-regexp (prefix) | |||
| (concat (if (equal prefix "") | |||
| (concat "\\(?:" company-dabbrev-char-regexp "\\)") | |||
| (regexp-quote prefix)) | |||
| "\\(?:" company-dabbrev-char-regexp "\\)*")) | |||
| (defun company-dabbrev--search-buffer (regexp pos symbols start limit | |||
| ignore-comments) | |||
| (save-excursion | |||
| (cl-labels ((maybe-collect-match | |||
| () | |||
| (let ((match (match-string-no-properties 0))) | |||
| (when (and (>= (length match) company-dabbrev-minimum-length) | |||
| (not (and company-dabbrev-ignore-invisible | |||
| (invisible-p (match-beginning 0))))) | |||
| (push match symbols))))) | |||
| (goto-char (if pos (1- pos) (point-min))) | |||
| ;; Search before pos. | |||
| (let ((tmp-end (point))) | |||
| (company-dabrev--time-limit-while (not (bobp)) | |||
| start limit | |||
| (ignore-errors | |||
| (forward-char -10000)) | |||
| (forward-line 0) | |||
| (save-excursion | |||
| ;; Before, we used backward search, but it matches non-greedily, and | |||
| ;; that forced us to use the "beginning/end of word" anchors in | |||
| ;; `company-dabbrev--make-regexp'. | |||
| (while (re-search-forward regexp tmp-end t) | |||
| (if (and ignore-comments (save-match-data (company-in-string-or-comment))) | |||
| (re-search-forward "\\s>\\|\\s!\\|\\s\"" tmp-end t) | |||
| (maybe-collect-match)))) | |||
| (setq tmp-end (point)))) | |||
| (goto-char (or pos (point-min))) | |||
| ;; Search after pos. | |||
| (company-dabrev--time-limit-while (re-search-forward regexp nil t) | |||
| start limit | |||
| (if (and ignore-comments (save-match-data (company-in-string-or-comment))) | |||
| (re-search-forward "\\s>\\|\\s!\\|\\s\"" nil t) | |||
| (maybe-collect-match))) | |||
| symbols))) | |||
| (defun company-dabbrev--search (regexp &optional limit other-buffer-modes | |||
| ignore-comments) | |||
| (let* ((start (current-time)) | |||
| (symbols (company-dabbrev--search-buffer regexp (point) nil start limit | |||
| ignore-comments))) | |||
| (when other-buffer-modes | |||
| (cl-dolist (buffer (delq (current-buffer) (buffer-list))) | |||
| (with-current-buffer buffer | |||
| (when (if (eq other-buffer-modes 'all) | |||
| (not (string-match-p company-dabbrev-ignore-buffers | |||
| (buffer-name))) | |||
| (apply #'derived-mode-p other-buffer-modes)) | |||
| (setq symbols | |||
| (company-dabbrev--search-buffer regexp nil symbols start | |||
| limit ignore-comments)))) | |||
| (and limit | |||
| (> (float-time (time-since start)) limit) | |||
| (cl-return)))) | |||
| symbols)) | |||
| (defun company-dabbrev--prefix () | |||
| ;; Not in the middle of a word. | |||
| (unless (looking-at company-dabbrev-char-regexp) | |||
| ;; Emacs can't do greedy backward-search. | |||
| (company-grab-line (format "\\(?:^\\| \\)[^ ]*?\\(\\(?:%s\\)*\\)" | |||
| company-dabbrev-char-regexp) | |||
| 1))) | |||
| ;;;###autoload | |||
| (defun company-dabbrev (command &optional arg &rest ignored) | |||
| "dabbrev-like `company-mode' completion backend." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-dabbrev)) | |||
| (prefix (company-dabbrev--prefix)) | |||
| (candidates | |||
| (let* ((case-fold-search company-dabbrev-ignore-case) | |||
| (words (company-dabbrev--search (company-dabbrev--make-regexp arg) | |||
| company-dabbrev-time-limit | |||
| (pcase company-dabbrev-other-buffers | |||
| (`t (list major-mode)) | |||
| (`all `all)))) | |||
| (downcase-p (if (eq company-dabbrev-downcase 'case-replace) | |||
| case-replace | |||
| company-dabbrev-downcase))) | |||
| (if downcase-p | |||
| (mapcar 'downcase words) | |||
| words))) | |||
| (ignore-case company-dabbrev-ignore-case) | |||
| (duplicates t))) | |||
| (provide 'company-dabbrev) | |||
| ;;; company-dabbrev.el ends here | |||
| @ -0,0 +1,185 @@ | |||
| ;;; company-eclim.el --- company-mode completion backend for Eclim | |||
| ;; Copyright (C) 2009, 2011, 2013, 2015 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;; Using `emacs-eclim' together with (or instead of) this backend is | |||
| ;; recommended, as it allows you to use other Eclim features. | |||
| ;; | |||
| ;; The alternative backend provided by `emacs-eclim' uses `yasnippet' | |||
| ;; instead of `company-template' to expand function calls, and it supports | |||
| ;; some languages other than Java. | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'company-template) | |||
| (require 'cl-lib) | |||
| (defgroup company-eclim nil | |||
| "Completion backend for Eclim." | |||
| :group 'company) | |||
| (defun company-eclim-executable-find () | |||
| (let (file) | |||
| (cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse" | |||
| "/usr/local/lib/eclipse")) | |||
| (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root))) | |||
| (setq file (car (last (directory-files file t "^org.eclim_")))) | |||
| (file-exists-p (setq file (expand-file-name "bin/eclim" file))) | |||
| (cl-return file))))) | |||
| (defcustom company-eclim-executable | |||
| (or (bound-and-true-p eclim-executable) | |||
| (executable-find "eclim") | |||
| (company-eclim-executable-find)) | |||
| "Location of eclim executable." | |||
| :type 'file) | |||
| (defcustom company-eclim-auto-save t | |||
| "Determines whether to save the buffer when retrieving completions. | |||
| eclim can only complete correctly when the buffer has been saved." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "On" t))) | |||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defvar-local company-eclim--project-dir 'unknown) | |||
| (defvar-local company-eclim--project-name nil) | |||
| (declare-function json-read "json") | |||
| (defvar json-array-type) | |||
| (defun company-eclim--call-process (&rest args) | |||
| (let ((coding-system-for-read 'utf-8) | |||
| res) | |||
| (require 'json) | |||
| (with-temp-buffer | |||
| (if (= 0 (setq res (apply 'call-process company-eclim-executable nil t nil | |||
| "-command" args))) | |||
| (let ((json-array-type 'list)) | |||
| (goto-char (point-min)) | |||
| (unless (eobp) | |||
| (json-read))) | |||
| (message "Company-eclim command failed with error %d:\n%s" res | |||
| (buffer-substring (point-min) (point-max))) | |||
| nil)))) | |||
| (defun company-eclim--project-list () | |||
| (company-eclim--call-process "project_list")) | |||
| (defun company-eclim--project-dir () | |||
| (if (eq company-eclim--project-dir 'unknown) | |||
| (setq company-eclim--project-dir | |||
| (directory-file-name | |||
| (expand-file-name | |||
| (locate-dominating-file buffer-file-name ".project")))) | |||
| company-eclim--project-dir)) | |||
| (defun company-eclim--project-name () | |||
| (or company-eclim--project-name | |||
| (let ((dir (company-eclim--project-dir))) | |||
| (when dir | |||
| (setq company-eclim--project-name | |||
| (cl-loop for project in (company-eclim--project-list) | |||
| when (equal (cdr (assoc 'path project)) dir) | |||
| return (cdr (assoc 'name project)))))))) | |||
| (defun company-eclim--candidates (prefix) | |||
| (interactive "d") | |||
| (let ((project-file (file-relative-name buffer-file-name | |||
| (company-eclim--project-dir))) | |||
| completions) | |||
| (when company-eclim-auto-save | |||
| (when (buffer-modified-p) | |||
| (basic-save-buffer)) | |||
| ;; FIXME: Sometimes this isn't finished when we complete. | |||
| (company-eclim--call-process "java_src_update" | |||
| "-p" (company-eclim--project-name) | |||
| "-f" project-file)) | |||
| (dolist (item (cdr (assoc 'completions | |||
| (company-eclim--call-process | |||
| "java_complete" "-p" (company-eclim--project-name) | |||
| "-f" project-file | |||
| "-o" (number-to-string | |||
| (company-eclim--search-point prefix)) | |||
| "-e" "utf-8" | |||
| "-l" "standard")))) | |||
| (let* ((meta (cdr (assoc 'info item))) | |||
| (completion meta)) | |||
| (when (string-match " ?[(:-]" completion) | |||
| (setq completion (substring completion 0 (match-beginning 0)))) | |||
| (put-text-property 0 1 'meta meta completion) | |||
| (push completion completions))) | |||
| (let ((completion-ignore-case nil)) | |||
| (all-completions prefix completions)))) | |||
| (defun company-eclim--search-point (prefix) | |||
| (if (or (cl-plusp (length prefix)) (eq (char-before) ?.)) | |||
| (1- (point)) | |||
| (point))) | |||
| (defun company-eclim--meta (candidate) | |||
| (get-text-property 0 'meta candidate)) | |||
| (defun company-eclim--annotation (candidate) | |||
| (let ((meta (company-eclim--meta candidate))) | |||
| (when (string-match "\\(([^-]*\\) -" meta) | |||
| (substring meta (match-beginning 1) (match-end 1))))) | |||
| (defun company-eclim--prefix () | |||
| (let ((prefix (company-grab-symbol))) | |||
| (when prefix | |||
| ;; Completion candidates for annotations don't include '@'. | |||
| (when (eq ?@ (string-to-char prefix)) | |||
| (setq prefix (substring prefix 1))) | |||
| prefix))) | |||
| (defun company-eclim (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for Eclim. | |||
| Eclim provides access to Eclipse Java IDE features for other editors. | |||
| Eclim version 1.7.13 or newer (?) is required. | |||
| Completions only work correctly when the buffer has been saved. | |||
| `company-eclim-auto-save' determines whether to do this automatically." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-eclim)) | |||
| (prefix (and (derived-mode-p 'java-mode 'jde-mode) | |||
| buffer-file-name | |||
| company-eclim-executable | |||
| (company-eclim--project-name) | |||
| (not (company-in-string-or-comment)) | |||
| (or (company-eclim--prefix) 'stop))) | |||
| (candidates (company-eclim--candidates arg)) | |||
| (meta (company-eclim--meta arg)) | |||
| ;; because "" doesn't return everything | |||
| (no-cache (equal arg "")) | |||
| (annotation (company-eclim--annotation arg)) | |||
| (post-completion (let ((anno (company-eclim--annotation arg))) | |||
| (when anno | |||
| (insert anno) | |||
| (company-template-c-like-templatify anno)))))) | |||
| (provide 'company-eclim) | |||
| ;;; company-eclim.el ends here | |||
| @ -0,0 +1,225 @@ | |||
| ;;; company-elisp.el --- company-mode completion backend for Emacs Lisp -*- lexical-binding: t -*- | |||
| ;; Copyright (C) 2009, 2011-2013 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (require 'help-mode) | |||
| (require 'find-func) | |||
| (defgroup company-elisp nil | |||
| "Completion backend for Emacs Lisp." | |||
| :group 'company) | |||
| (defcustom company-elisp-detect-function-context t | |||
| "If enabled, offer Lisp functions only in appropriate contexts. | |||
| Functions are offered for completion only after ' and \(." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "On" t))) | |||
| (defcustom company-elisp-show-locals-first t | |||
| "If enabled, locally bound variables and functions are displayed | |||
| first in the candidates list." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "On" t))) | |||
| (defun company-elisp--prefix () | |||
| (let ((prefix (company-grab-symbol))) | |||
| (if prefix | |||
| (when (if (company-in-string-or-comment) | |||
| (= (char-before (- (point) (length prefix))) ?`) | |||
| (company-elisp--should-complete)) | |||
| prefix) | |||
| 'stop))) | |||
| (defun company-elisp--predicate (symbol) | |||
| (or (boundp symbol) | |||
| (fboundp symbol) | |||
| (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 | |||
| (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 | |||
| (company-elisp--fns-regexp "dolist" "dotimes") | |||
| "Regular expression matching head of a form with one variable binding.") | |||
| (defvar company-elisp-fun-binding-regexp | |||
| (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_\\)*\\_>\\)")) | |||
| (pos (point)) | |||
| res) | |||
| (condition-case nil | |||
| (save-excursion | |||
| (dotimes (_ company-elisp-parse-depth) | |||
| (up-list -1) | |||
| (save-excursion | |||
| (when (eq (char-after) ?\() | |||
| (forward-char 1) | |||
| (when (ignore-errors | |||
| (save-excursion (forward-list) | |||
| (<= (point) pos))) | |||
| (skip-chars-forward " \t\n") | |||
| (cond | |||
| ((looking-at (if functions-p | |||
| company-elisp-fun-binding-regexp | |||
| company-elisp-var-binding-regexp)) | |||
| (down-list 1) | |||
| (condition-case nil | |||
| (dotimes (_ company-elisp-parse-limit) | |||
| (save-excursion | |||
| (when (looking-at "[ \t\n]*(") | |||
| (down-list 1)) | |||
| (when (looking-at regexp) | |||
| (cl-pushnew (match-string-no-properties 1) res))) | |||
| (forward-sexp)) | |||
| (scan-error nil))) | |||
| ((unless functions-p | |||
| (looking-at company-elisp-var-binding-regexp-1)) | |||
| (down-list 1) | |||
| (when (looking-at regexp) | |||
| (cl-pushnew (match-string-no-properties 1) res))))))))) | |||
| (scan-error nil)) | |||
| res)) | |||
| (defun company-elisp-candidates (prefix) | |||
| (let* ((predicate (company-elisp--candidates-predicate prefix)) | |||
| (locals (company-elisp--locals prefix (eq predicate 'fboundp))) | |||
| (globals (company-elisp--globals prefix predicate)) | |||
| (locals (cl-loop for local in locals | |||
| when (not (member local globals)) | |||
| collect local))) | |||
| (if company-elisp-show-locals-first | |||
| (append (sort locals 'string<) | |||
| (sort globals 'string<)) | |||
| (append locals globals)))) | |||
| (defun company-elisp--globals (prefix predicate) | |||
| (all-completions prefix obarray predicate)) | |||
| (defun company-elisp--candidates-predicate (prefix) | |||
| (let* ((completion-ignore-case nil) | |||
| (beg (- (point) (length prefix))) | |||
| (before (char-before beg))) | |||
| (if (and company-elisp-detect-function-context | |||
| (not (memq before '(?' ?`)))) | |||
| (if (and (eq before ?\() | |||
| (not | |||
| (save-excursion | |||
| (ignore-errors | |||
| (goto-char (1- beg)) | |||
| (or (company-elisp--before-binding-varlist-p) | |||
| (progn | |||
| (up-list -1) | |||
| (company-elisp--before-binding-varlist-p))))))) | |||
| 'fboundp | |||
| 'boundp) | |||
| 'company-elisp--predicate))) | |||
| (defun company-elisp--before-binding-varlist-p () | |||
| (save-excursion | |||
| (and (prog1 (search-backward "(") | |||
| (forward-char 1)) | |||
| (looking-at company-elisp-var-binding-regexp)))) | |||
| (defun company-elisp--doc (symbol) | |||
| (let* ((symbol (intern symbol)) | |||
| (doc (if (fboundp symbol) | |||
| (documentation symbol t) | |||
| (documentation-property symbol 'variable-documentation t)))) | |||
| (and (stringp doc) | |||
| (string-match ".*$" doc) | |||
| (match-string 0 doc)))) | |||
| ;;;###autoload | |||
| (defun company-elisp (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for Emacs Lisp." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-elisp)) | |||
| (prefix (and (derived-mode-p 'emacs-lisp-mode 'inferior-emacs-lisp-mode) | |||
| (company-elisp--prefix))) | |||
| (candidates (company-elisp-candidates arg)) | |||
| (sorted company-elisp-show-locals-first) | |||
| (meta (company-elisp--doc arg)) | |||
| (doc-buffer (let ((symbol (intern arg))) | |||
| (save-window-excursion | |||
| (ignore-errors | |||
| (cond | |||
| ((fboundp symbol) (describe-function symbol)) | |||
| ((boundp symbol) (describe-variable symbol)) | |||
| ((featurep symbol) (describe-package symbol)) | |||
| ((facep symbol) (describe-face symbol)) | |||
| (t (signal 'user-error nil))) | |||
| (help-buffer))))) | |||
| (location (let ((sym (intern arg))) | |||
| (cond | |||
| ((fboundp sym) (find-definition-noselect sym nil)) | |||
| ((boundp sym) (find-definition-noselect sym 'defvar)) | |||
| ((featurep sym) (cons (find-file-noselect (find-library-name | |||
| (symbol-name sym))) | |||
| 0)) | |||
| ((facep sym) (find-definition-noselect sym 'defface))))))) | |||
| (provide 'company-elisp) | |||
| ;;; company-elisp.el ends here | |||
| @ -0,0 +1,107 @@ | |||
| ;;; company-etags.el --- company-mode completion backend for etags | |||
| ;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (require 'etags) | |||
| (defgroup company-etags nil | |||
| "Completion backend for etags." | |||
| :group 'company) | |||
| (defcustom company-etags-use-main-table-list t | |||
| "Always search `tags-table-list' if set. | |||
| If this is disabled, `company-etags' will try to find the one table for each | |||
| buffer automatically." | |||
| :type '(choice (const :tag "off" nil) | |||
| (const :tag "on" t))) | |||
| (defcustom company-etags-ignore-case nil | |||
| "Non-nil to ignore case in completion candidates." | |||
| :type 'boolean | |||
| :package-version '(company . "0.7.3")) | |||
| (defcustom company-etags-everywhere nil | |||
| "Non-nil to offer completions in comments and strings. | |||
| Set it to t or to a list of major modes." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "Any supported mode" t) | |||
| (repeat :tag "Some major modes" | |||
| (symbol :tag "Major mode"))) | |||
| :package-version '(company . "0.9.0")) | |||
| (defvar company-etags-modes '(prog-mode c-mode objc-mode c++-mode java-mode | |||
| jde-mode pascal-mode perl-mode python-mode)) | |||
| (defvar-local company-etags-buffer-table 'unknown) | |||
| (defun company-etags-find-table () | |||
| (let ((file (expand-file-name | |||
| "TAGS" | |||
| (locate-dominating-file (or buffer-file-name | |||
| default-directory) | |||
| "TAGS")))) | |||
| (when (and file (file-regular-p file)) | |||
| (list file)))) | |||
| (defun company-etags-buffer-table () | |||
| (or (and company-etags-use-main-table-list tags-table-list) | |||
| (if (eq company-etags-buffer-table 'unknown) | |||
| (setq company-etags-buffer-table (company-etags-find-table)) | |||
| company-etags-buffer-table))) | |||
| (defun company-etags--candidates (prefix) | |||
| (let ((tags-table-list (company-etags-buffer-table)) | |||
| (completion-ignore-case company-etags-ignore-case)) | |||
| (and (or tags-file-name tags-table-list) | |||
| (fboundp 'tags-completion-table) | |||
| (save-excursion | |||
| (visit-tags-table-buffer) | |||
| (all-completions prefix (tags-completion-table)))))) | |||
| ;;;###autoload | |||
| (defun company-etags (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for etags." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-etags)) | |||
| (prefix (and (apply #'derived-mode-p company-etags-modes) | |||
| (or (eq t company-etags-everywhere) | |||
| (apply #'derived-mode-p company-etags-everywhere) | |||
| (not (company-in-string-or-comment))) | |||
| (company-etags-buffer-table) | |||
| (or (company-grab-symbol) 'stop))) | |||
| (candidates (company-etags--candidates arg)) | |||
| (location (let ((tags-table-list (company-etags-buffer-table))) | |||
| (when (fboundp 'find-tag-noselect) | |||
| (save-excursion | |||
| (let ((buffer (find-tag-noselect arg))) | |||
| (cons buffer (with-current-buffer buffer (point)))))))) | |||
| (ignore-case company-etags-ignore-case))) | |||
| (provide 'company-etags) | |||
| ;;; company-etags.el ends here | |||
| @ -0,0 +1,122 @@ | |||
| ;;; company-files.el --- company-mode completion backend for file paths | |||
| ;; Copyright (C) 2009-2011, 2014-2015 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defun company-files--directory-files (dir prefix) | |||
| (ignore-errors | |||
| ;; Don't use directory-files. It produces directories without trailing /. | |||
| (let ((comp (sort (file-name-all-completions prefix dir) | |||
| (lambda (s1 s2) (string-lessp (downcase s1) (downcase s2)))))) | |||
| (if (equal prefix "") | |||
| (delete "../" (delete "./" comp)) | |||
| comp)))) | |||
| (defvar company-files--regexps | |||
| (let* ((root (if (eq system-type 'windows-nt) | |||
| "[a-zA-Z]:/" | |||
| "/")) | |||
| (begin (concat "\\(?:\\.\\{1,2\\}/\\|~/\\|" root "\\)"))) | |||
| (list (concat "\"\\(" begin "[^\"\n]*\\)") | |||
| (concat "\'\\(" begin "[^\'\n]*\\)") | |||
| (concat "\\(?:[ \t]\\|^\\)\\(" begin "[^ \t\n]*\\)")))) | |||
| (defun company-files--grab-existing-name () | |||
| ;; Grab the file name. | |||
| ;; When surrounded with quotes, it can include spaces. | |||
| (let (file dir) | |||
| (and (cl-dolist (regexp company-files--regexps) | |||
| (when (setq file (company-grab-line regexp 1)) | |||
| (cl-return file))) | |||
| (company-files--connected-p file) | |||
| (setq dir (file-name-directory file)) | |||
| (not (string-match "//" dir)) | |||
| (file-exists-p dir) | |||
| file))) | |||
| (defun company-files--connected-p (file) | |||
| (or (not (file-remote-p file)) | |||
| (file-remote-p file nil t))) | |||
| (defun company-files--trailing-slash-p (file) | |||
| ;; `file-directory-p' is very expensive on remotes. We are relying on | |||
| ;; `file-name-all-completions' returning directories with trailing / instead. | |||
| (let ((len (length file))) | |||
| (and (> len 0) (eq (aref file (1- len)) ?/)))) | |||
| (defvar company-files--completion-cache nil) | |||
| (defun company-files--complete (prefix) | |||
| (let* ((dir (file-name-directory prefix)) | |||
| (file (file-name-nondirectory prefix)) | |||
| (key (list file | |||
| (expand-file-name dir) | |||
| (nth 5 (file-attributes dir)))) | |||
| (completion-ignore-case read-file-name-completion-ignore-case)) | |||
| (unless (company-file--keys-match-p key (car company-files--completion-cache)) | |||
| (let* ((candidates (mapcar (lambda (f) (concat dir f)) | |||
| (company-files--directory-files dir file))) | |||
| (directories (unless (file-remote-p dir) | |||
| (cl-remove-if-not (lambda (f) | |||
| (and (company-files--trailing-slash-p f) | |||
| (not (file-remote-p f)) | |||
| (company-files--connected-p f))) | |||
| candidates))) | |||
| (children (and directories | |||
| (cl-mapcan (lambda (d) | |||
| (mapcar (lambda (c) (concat d c)) | |||
| (company-files--directory-files d ""))) | |||
| directories)))) | |||
| (setq company-files--completion-cache | |||
| (cons key (append candidates children))))) | |||
| (all-completions prefix | |||
| (cdr company-files--completion-cache)))) | |||
| (defun company-file--keys-match-p (new old) | |||
| (and (equal (cdr old) (cdr new)) | |||
| (string-prefix-p (car old) (car new)))) | |||
| ;;;###autoload | |||
| (defun company-files (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend existing file names. | |||
| Completions works for proper absolute and relative files paths. | |||
| File paths with spaces are only supported inside strings." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-files)) | |||
| (prefix (company-files--grab-existing-name)) | |||
| (candidates (company-files--complete arg)) | |||
| (location (cons (dired-noselect | |||
| (file-name-directory (directory-file-name arg))) 1)) | |||
| (post-completion (when (company-files--trailing-slash-p arg) | |||
| (delete-char -1))) | |||
| (sorted t) | |||
| (no-cache t))) | |||
| (provide 'company-files) | |||
| ;;; company-files.el ends here | |||
| @ -0,0 +1,116 @@ | |||
| ;;; company-gtags.el --- company-mode completion backend for GNU Global | |||
| ;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'company-template) | |||
| (require 'cl-lib) | |||
| (defgroup company-gtags nil | |||
| "Completion backend for GNU Global." | |||
| :group 'company) | |||
| (defcustom company-gtags-executable | |||
| (executable-find "global") | |||
| "Location of GNU global executable." | |||
| :type 'string) | |||
| (define-obsolete-variable-alias | |||
| 'company-gtags-gnu-global-program-name | |||
| 'company-gtags-executable "earlier") | |||
| (defcustom company-gtags-insert-arguments t | |||
| "When non-nil, insert function arguments as a template after completion." | |||
| :type 'boolean | |||
| :package-version '(company . "0.8.1")) | |||
| (defvar-local company-gtags--tags-available-p 'unknown) | |||
| (defcustom company-gtags-modes '(prog-mode jde-mode) | |||
| "Modes that use `company-gtags'. | |||
| In all these modes (and their derivatives) `company-gtags' will perform | |||
| completion." | |||
| :type '(repeat (symbol :tag "Major mode")) | |||
| :package-version '(company . "0.8.4")) | |||
| (defun company-gtags--tags-available-p () | |||
| (if (eq company-gtags--tags-available-p 'unknown) | |||
| (setq company-gtags--tags-available-p | |||
| (locate-dominating-file buffer-file-name "GTAGS")) | |||
| company-gtags--tags-available-p)) | |||
| (defun company-gtags--fetch-tags (prefix) | |||
| (with-temp-buffer | |||
| (let (tags) | |||
| (when (= 0 (call-process company-gtags-executable nil | |||
| (list (current-buffer) nil) nil "-xGq" (concat "^" prefix))) | |||
| (goto-char (point-min)) | |||
| (cl-loop while | |||
| (re-search-forward (concat | |||
| "^" | |||
| "\\([^ ]*\\)" ;; completion | |||
| "[ \t]+\\([[:digit:]]+\\)" ;; linum | |||
| "[ \t]+\\([^ \t]+\\)" ;; file | |||
| "[ \t]+\\(.*\\)" ;; definition | |||
| "$" | |||
| ) nil t) | |||
| collect | |||
| (propertize (match-string 1) | |||
| 'meta (match-string 4) | |||
| 'location (cons (expand-file-name (match-string 3)) | |||
| (string-to-number (match-string 2))) | |||
| )))))) | |||
| (defun company-gtags--annotation (arg) | |||
| (let ((meta (get-text-property 0 'meta arg))) | |||
| (when (string-match (concat arg "\\((.*)\\).*") meta) | |||
| (match-string 1 meta)))) | |||
| ;;;###autoload | |||
| (defun company-gtags (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for GNU Global." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-gtags)) | |||
| (prefix (and company-gtags-executable | |||
| buffer-file-name | |||
| (apply #'derived-mode-p company-gtags-modes) | |||
| (not (company-in-string-or-comment)) | |||
| (company-gtags--tags-available-p) | |||
| (or (company-grab-symbol) 'stop))) | |||
| (candidates (company-gtags--fetch-tags arg)) | |||
| (sorted t) | |||
| (duplicates t) | |||
| (annotation (company-gtags--annotation arg)) | |||
| (meta (get-text-property 0 'meta arg)) | |||
| (location (get-text-property 0 'location arg)) | |||
| (post-completion (let ((anno (company-gtags--annotation arg))) | |||
| (when (and company-gtags-insert-arguments anno) | |||
| (insert anno) | |||
| (company-template-c-like-templatify anno)))))) | |||
| (provide 'company-gtags) | |||
| ;;; company-gtags.el ends here | |||
| @ -0,0 +1,82 @@ | |||
| ;;; company-ispell.el --- company-mode completion backend using Ispell | |||
| ;; Copyright (C) 2009-2011, 2013-2016 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (require 'ispell) | |||
| (defgroup company-ispell nil | |||
| "Completion backend using Ispell." | |||
| :group 'company) | |||
| (defcustom company-ispell-dictionary nil | |||
| "Dictionary to use for `company-ispell'. | |||
| If nil, use `ispell-complete-word-dict'." | |||
| :type '(choice (const :tag "default (nil)" nil) | |||
| (file :tag "dictionary" t))) | |||
| (defvar company-ispell-available 'unknown) | |||
| (defalias 'company-ispell--lookup-words | |||
| (if (fboundp 'ispell-lookup-words) | |||
| 'ispell-lookup-words | |||
| 'lookup-words)) | |||
| (defun company-ispell-available () | |||
| (when (eq company-ispell-available 'unknown) | |||
| (condition-case err | |||
| (progn | |||
| (company-ispell--lookup-words "WHATEVER") | |||
| (setq company-ispell-available t)) | |||
| (error | |||
| (message "Company: ispell-look-command not found") | |||
| (setq company-ispell-available nil)))) | |||
| company-ispell-available) | |||
| ;;;###autoload | |||
| (defun company-ispell (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend using Ispell." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-ispell)) | |||
| (prefix (when (company-ispell-available) | |||
| (company-grab-word))) | |||
| (candidates | |||
| (let ((words (company-ispell--lookup-words | |||
| arg | |||
| (or company-ispell-dictionary ispell-complete-word-dict))) | |||
| (completion-ignore-case t)) | |||
| (if (string= arg "") | |||
| ;; Small optimization. | |||
| words | |||
| ;; Work around issue #284. | |||
| (all-completions arg words)))) | |||
| (sorted t) | |||
| (ignore-case 'keep-prefix))) | |||
| (provide 'company-ispell) | |||
| ;;; company-ispell.el ends here | |||
| @ -0,0 +1,242 @@ | |||
| ;;; company-keywords.el --- A company backend for programming language keywords | |||
| ;; Copyright (C) 2009-2011 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defun company-keywords-upper-lower (&rest lst) | |||
| ;; Upcase order is different for _. | |||
| (nconc (sort (mapcar 'upcase lst) 'string<) lst)) | |||
| (defvar company-keywords-alist | |||
| ;; Please contribute corrections or additions. | |||
| `((c++-mode | |||
| "asm" "auto" "bool" "break" "case" "catch" "char" "class" "const" | |||
| "const_cast" "continue" "default" "delete" "do" "double" "dynamic_cast" | |||
| "else" "enum" "explicit" "export" "extern" "false" "float" "for" "friend" | |||
| "goto" "if" "inline" "int" "long" "mutable" "namespace" "new" | |||
| "operator" "private" "protected" "public" "register" "reinterpret_cast" | |||
| "return" "short" "signed" "sizeof" "static" "static_cast" "struct" "switch" | |||
| "template" "this" "throw" "true" "try" "typedef" "typeid" "typename" | |||
| "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while") | |||
| (c-mode | |||
| "auto" "break" "case" "char" "const" "continue" "default" "do" | |||
| "double" "else" "enum" "extern" "float" "for" "goto" "if" "int" "long" | |||
| "register" "return" "short" "signed" "sizeof" "static" "struct" | |||
| "switch" "typedef" "union" "unsigned" "void" "volatile" "while") | |||
| (csharp-mode | |||
| "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case" | |||
| "catch" "char" "checked" "class" "const" "continue" "decimal" "default" | |||
| "delegate" "do" "double" "else" "enum" "event" "explicit" "extern" | |||
| "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto" | |||
| "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long" | |||
| "namespace" "new" "null" "object" "operator" "out" "override" "params" | |||
| "partial" "private" "protected" "public" "readonly" "ref" "remove" | |||
| "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static" | |||
| "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint" | |||
| "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual" | |||
| "void" "volatile" "where" "while" "yield") | |||
| (d-mode | |||
| ;; from http://www.digitalmars.com/d/2.0/lex.html | |||
| "abstract" "alias" "align" "asm" | |||
| "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch" | |||
| "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal" | |||
| "dchar" "debug" "default" "delegate" "delete" "deprecated" "do" | |||
| "double" "else" "enum" "export" "extern" "false" "final" "finally" | |||
| "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble" | |||
| "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant" | |||
| "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow" | |||
| "null" "out" "override" "package" "pragma" "private" "protected" | |||
| "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct" | |||
| "super" "switch" "synchronized" "template" "this" "throw" "true" "try" | |||
| "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union" | |||
| "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with") | |||
| (f90-mode . | |||
| ;; from f90.el | |||
| ;; ".AND." ".GE." ".GT." ".LT." ".LE." ".NE." ".OR." ".TRUE." ".FALSE." | |||
| ,(company-keywords-upper-lower | |||
| "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint" | |||
| "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable" | |||
| "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter" | |||
| "any_suffix" "asin" "assign" "assignment" "associate" "associated" | |||
| "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block" | |||
| "btest" "c_alert" "c_associated" "c_backspace" "c_bool" | |||
| "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer" | |||
| "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc" | |||
| "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t" | |||
| "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t" | |||
| "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t" | |||
| "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long" | |||
| "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line" | |||
| "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short" | |||
| "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling" | |||
| "char" "character" "character_storage_size" "class" "close" "cmplx" | |||
| "command_argument_count" "common" "complex" "conjg" "contains" "continue" | |||
| "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count" | |||
| "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift" | |||
| "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred" | |||
| "digits" "dim" "dimension" "distribute" "do" "dot_product" "double" | |||
| "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo" | |||
| "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq" | |||
| "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends" | |||
| "extends_type_of" "external" "extrinsic" "false" "file_storage_size" | |||
| "final" "floor" "flush" "forall" "format" "fraction" "function" "ge" | |||
| "generic" "get_command" "get_command_argument" "get_environment_variable" | |||
| "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution" | |||
| "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter" | |||
| "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix" | |||
| "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions" | |||
| "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode" | |||
| "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit" | |||
| "import" "include" "independent" "index" "inherit" "input_unit" | |||
| "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior" | |||
| "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter" | |||
| "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env" | |||
| "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt" | |||
| "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc" | |||
| "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge" | |||
| "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter" | |||
| "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist" | |||
| "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic" | |||
| "non_overridable" "none" "nopass" "not" "null" "nullify" | |||
| "number_of_processors" "numeric_storage_size" "only" "onto" "open" | |||
| "operator" "optional" "or" "output_unit" "pack" "parameter" "parity" | |||
| "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause" | |||
| "pointer" "popcnt" "poppar" "precision" "present" "print" "private" | |||
| "procedure" "processors" "processors_shape" "product" "product_prefix" | |||
| "product_scatter" "product_suffix" "program" "protected" "public" | |||
| "pure" "radix" "random_number" "random_seed" "range" "read" "real" | |||
| "realign" "recursive" "redistribute" "repeat" "reshape" "result" | |||
| "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan" | |||
| "select" "selected_char_kind" "selected_int_kind" "selected_real_kind" | |||
| "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing" | |||
| "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter" | |||
| "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then" | |||
| "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack" | |||
| "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write")) | |||
| (java-mode | |||
| "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class" | |||
| "continue" "default" "do" "double" "else" "enum" "extends" "final" | |||
| "finally" "float" "for" "if" "implements" "import" "instanceof" "int" | |||
| "interface" "long" "native" "new" "package" "private" "protected" "public" | |||
| "return" "short" "static" "strictfp" "super" "switch" "synchronized" | |||
| "this" "throw" "throws" "transient" "try" "void" "volatile" "while") | |||
| (javascript-mode | |||
| "break" "catch" "const" "continue" "delete" "do" "else" "export" "for" | |||
| "function" "if" "import" "in" "instanceOf" "label" "let" "new" "return" | |||
| "switch" "this" "throw" "try" "typeof" "var" "void" "while" "with" "yield") | |||
| (objc-mode | |||
| "@catch" "@class" "@encode" "@end" "@finally" "@implementation" | |||
| "@interface" "@private" "@protected" "@protocol" "@public" | |||
| "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease" | |||
| "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain") | |||
| (perl-mode | |||
| ;; from cperl.el | |||
| "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__" | |||
| "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind" | |||
| "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr" | |||
| "chroot" "close" "closedir" "cmp" "connect" "continue" "cos" | |||
| "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each" | |||
| "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent" | |||
| "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp" | |||
| "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline" | |||
| "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr" | |||
| "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname" | |||
| "getnetent" "getpeername" "getpgrp" "getppid" "getpriority" | |||
| "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam" | |||
| "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname" | |||
| "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int" | |||
| "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length" | |||
| "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map" | |||
| "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no" | |||
| "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe" | |||
| "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx" | |||
| "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo" | |||
| "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex" | |||
| "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop" | |||
| "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority" | |||
| "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl" | |||
| "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket" | |||
| "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat" | |||
| "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system" | |||
| "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc" | |||
| "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie" | |||
| "until" "use" "utime" "values" "vec" "wait" "waitpid" | |||
| "wantarray" "warn" "while" "write" "x" "xor" "y") | |||
| (php-mode | |||
| "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__" | |||
| "__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case" | |||
| "catch" "cfunction" "class" "clone" "const" "continue" "declare" | |||
| "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare" | |||
| "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception" | |||
| "exit" "extends" "final" "for" "foreach" "function" "global" | |||
| "goto" "if" "implements" "include" "instanceof" "interface" | |||
| "isset" "list" "namespace" "new" "old_function" "or" "php_user_filter" | |||
| "print" "private" "protected" "public" "require" "require_once" "return" | |||
| "static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor") | |||
| (python-mode | |||
| "and" "assert" "break" "class" "continue" "def" "del" "elif" "else" | |||
| "except" "exec" "finally" "for" "from" "global" "if" "import" "in" "is" | |||
| "lambda" "not" "or" "pass" "print" "raise" "return" "try" "while" "yield") | |||
| (ruby-mode | |||
| "BEGIN" "END" "alias" "and" "begin" "break" "case" "class" "def" "defined?" | |||
| "do" "else" "elsif" "end" "ensure" "false" "for" "if" "in" "module" | |||
| "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super" | |||
| "then" "true" "undef" "unless" "until" "when" "while" "yield") | |||
| (scala-mode | |||
| "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false" | |||
| "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match" | |||
| "new" "null" "object" "override" "package" "private" "protected" | |||
| "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val" | |||
| "var" "while" "with" "yield") | |||
| ;; aliases | |||
| (js2-mode . javascript-mode) | |||
| (espresso-mode . javascript-mode) | |||
| (js-mode . javascript-mode) | |||
| (cperl-mode . perl-mode) | |||
| (jde-mode . java-mode)) | |||
| "Alist mapping major-modes to sorted keywords for `company-keywords'.") | |||
| ;;;###autoload | |||
| (defun company-keywords (command &optional arg &rest ignored) | |||
| "`company-mode' backend for programming language keywords." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-keywords)) | |||
| (prefix (and (assq major-mode company-keywords-alist) | |||
| (not (company-in-string-or-comment)) | |||
| (or (company-grab-symbol) 'stop))) | |||
| (candidates | |||
| (let ((completion-ignore-case nil) | |||
| (symbols (cdr (assq major-mode company-keywords-alist)))) | |||
| (all-completions arg (if (consp symbols) | |||
| symbols | |||
| (cdr (assq symbols company-keywords-alist)))))) | |||
| (sorted t))) | |||
| (provide 'company-keywords) | |||
| ;;; company-keywords.el ends here | |||
| @ -0,0 +1,142 @@ | |||
| ;;; company-nxml.el --- company-mode completion backend for nxml-mode | |||
| ;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defvar rng-open-elements) | |||
| (defvar rng-validate-mode) | |||
| (defvar rng-in-attribute-regex) | |||
| (defvar rng-in-attribute-value-regex) | |||
| (declare-function rng-set-state-after "rng-nxml") | |||
| (declare-function rng-match-possible-start-tag-names "rng-match") | |||
| (declare-function rng-adjust-state-for-attribute "rng-nxml") | |||
| (declare-function rng-match-possible-attribute-names "rng-match") | |||
| (declare-function rng-adjust-state-for-attribute-value "rng-nxml") | |||
| (declare-function rng-match-possible-value-strings "rng-match") | |||
| (defconst company-nxml-token-regexp | |||
| "\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)") | |||
| (defvar company-nxml-in-attribute-value-regexp | |||
| (replace-regexp-in-string "w" company-nxml-token-regexp | |||
| "<w\\(?::w\\)?\ | |||
| \\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\ | |||
| \[ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\ | |||
| \[ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\ | |||
| \\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\=" | |||
| t t)) | |||
| (defvar company-nxml-in-tag-name-regexp | |||
| (replace-regexp-in-string "w" company-nxml-token-regexp | |||
| "<\\(/?w\\(?::w?\\)?\\)?\\=" t t)) | |||
| (defun company-nxml-all-completions (prefix alist) | |||
| (let ((candidates (mapcar 'cdr alist)) | |||
| (case-fold-search nil) | |||
| filtered) | |||
| (when (cdar rng-open-elements) | |||
| (push (concat "/" (cdar rng-open-elements)) candidates)) | |||
| (setq candidates (sort (all-completions prefix candidates) 'string<)) | |||
| (while candidates | |||
| (unless (equal (car candidates) (car filtered)) | |||
| (push (car candidates) filtered)) | |||
| (pop candidates)) | |||
| (nreverse filtered))) | |||
| (defmacro company-nxml-prepared (&rest body) | |||
| (declare (indent 0) (debug t)) | |||
| `(let ((lt-pos (save-excursion (search-backward "<" nil t))) | |||
| xmltok-dtd) | |||
| (when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos)) | |||
| ,@body))) | |||
| (defun company-nxml-tag (command &optional arg &rest ignored) | |||
| (cl-case command | |||
| (prefix (and (derived-mode-p 'nxml-mode) | |||
| rng-validate-mode | |||
| (company-grab company-nxml-in-tag-name-regexp 1))) | |||
| (candidates (company-nxml-prepared | |||
| (company-nxml-all-completions | |||
| arg (rng-match-possible-start-tag-names)))) | |||
| (sorted t))) | |||
| (defun company-nxml-attribute (command &optional arg &rest ignored) | |||
| (cl-case command | |||
| (prefix (and (derived-mode-p 'nxml-mode) | |||
| rng-validate-mode | |||
| (memq (char-after) '(?\ ?\t ?\n)) ;; outside word | |||
| (company-grab rng-in-attribute-regex 1))) | |||
| (candidates (company-nxml-prepared | |||
| (and (rng-adjust-state-for-attribute | |||
| lt-pos (- (point) (length arg))) | |||
| (company-nxml-all-completions | |||
| arg (rng-match-possible-attribute-names))))) | |||
| (sorted t))) | |||
| (defun company-nxml-attribute-value (command &optional arg &rest ignored) | |||
| (cl-case command | |||
| (prefix (and (derived-mode-p 'nxml-mode) | |||
| rng-validate-mode | |||
| (and (memq (char-after) '(?' ?\" ?\ ?\t ?\n)) ;; outside word | |||
| (looking-back company-nxml-in-attribute-value-regexp) | |||
| (or (match-string-no-properties 4) | |||
| (match-string-no-properties 5) | |||
| "")))) | |||
| (candidates (company-nxml-prepared | |||
| (let (attr-start attr-end colon) | |||
| (and (looking-back rng-in-attribute-value-regex lt-pos) | |||
| (setq colon (match-beginning 2) | |||
| attr-start (match-beginning 1) | |||
| attr-end (match-end 1)) | |||
| (rng-adjust-state-for-attribute lt-pos attr-start) | |||
| (rng-adjust-state-for-attribute-value | |||
| attr-start colon attr-end) | |||
| (all-completions | |||
| arg (rng-match-possible-value-strings)))))))) | |||
| ;;;###autoload | |||
| (defun company-nxml (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for `nxml-mode'." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-nxml)) | |||
| (prefix (or (company-nxml-tag 'prefix) | |||
| (company-nxml-attribute 'prefix) | |||
| (company-nxml-attribute-value 'prefix))) | |||
| (candidates (cond | |||
| ((company-nxml-tag 'prefix) | |||
| (company-nxml-tag 'candidates arg)) | |||
| ((company-nxml-attribute 'prefix) | |||
| (company-nxml-attribute 'candidates arg)) | |||
| ((company-nxml-attribute-value 'prefix) | |||
| (sort (company-nxml-attribute-value 'candidates arg) | |||
| 'string<)))) | |||
| (sorted t))) | |||
| (provide 'company-nxml) | |||
| ;;; company-nxml.el ends here | |||
| @ -0,0 +1,57 @@ | |||
| ;;; company-oddmuse.el --- company-mode completion backend for oddmuse-mode | |||
| ;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (eval-when-compile (require 'yaoddmuse nil t)) | |||
| (eval-when-compile (require 'oddmuse nil t)) | |||
| (defvar company-oddmuse-link-regexp | |||
| "\\(\\<[A-Z][[:alnum:]]*\\>\\)\\|\\[\\[\\([[:alnum:]]+\\>\\|\\)") | |||
| (defun company-oddmuse-get-page-table () | |||
| (cl-case major-mode | |||
| (yaoddmuse-mode (with-no-warnings | |||
| (yaoddmuse-get-pagename-table yaoddmuse-wikiname))) | |||
| (oddmuse-mode (with-no-warnings | |||
| (oddmuse-make-completion-table oddmuse-wiki))))) | |||
| ;;;###autoload | |||
| (defun company-oddmuse (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for `oddmuse-mode'." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-oddmuse)) | |||
| (prefix (let ((case-fold-search nil)) | |||
| (and (memq major-mode '(oddmuse-mode yaoddmuse-mode)) | |||
| (looking-back company-oddmuse-link-regexp (point-at-bol)) | |||
| (or (match-string 1) | |||
| (match-string 2))))) | |||
| (candidates (all-completions arg (company-oddmuse-get-page-table))))) | |||
| (provide 'company-oddmuse) | |||
| ;;; company-oddmuse.el ends here | |||
| @ -0,0 +1,8 @@ | |||
| (define-package "company" "20160211.520" "Modular text completion framework" | |||
| '((emacs "24.1") | |||
| (cl-lib "0.5")) | |||
| :url "http://company-mode.github.io/" :keywords | |||
| '("abbrev" "convenience" "matching")) | |||
| ;; Local Variables: | |||
| ;; no-byte-compile: t | |||
| ;; End: | |||
| @ -0,0 +1,167 @@ | |||
| ;;; company-semantic.el --- company-mode completion backend using Semantic | |||
| ;; Copyright (C) 2009-2011, 2013-2016 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'company-template) | |||
| (require 'cl-lib) | |||
| (defvar semantic-idle-summary-function) | |||
| (declare-function semantic-documentation-for-tag "semantic/doc" ) | |||
| (declare-function semantic-analyze-current-context "semantic/analyze") | |||
| (declare-function semantic-analyze-possible-completions "semantic/complete") | |||
| (declare-function semantic-analyze-find-tags-by-prefix "semantic/analyze/fcn") | |||
| (declare-function semantic-tag-class "semantic/tag") | |||
| (declare-function semantic-tag-name "semantic/tag") | |||
| (declare-function semantic-tag-start "semantic/tag") | |||
| (declare-function semantic-tag-buffer "semantic/tag") | |||
| (declare-function semantic-active-p "semantic") | |||
| (declare-function semantic-format-tag-prototype "semantic/format") | |||
| (defgroup company-semantic nil | |||
| "Completion backend using Semantic." | |||
| :group 'company) | |||
| (defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc | |||
| "The function turning a semantic tag into doc information." | |||
| :type 'function) | |||
| (defcustom company-semantic-begin-after-member-access t | |||
| "When non-nil, automatic completion will start whenever the current | |||
| symbol is preceded by \".\", \"->\" or \"::\", ignoring | |||
| `company-minimum-prefix-length'. | |||
| If `company-begin-commands' is a list, it should include `c-electric-lt-gt' | |||
| and `c-electric-colon', for automatic completion right after \">\" and | |||
| \":\".") | |||
| (defcustom company-semantic-insert-arguments t | |||
| "When non-nil, insert function arguments as a template after completion." | |||
| :type 'boolean | |||
| :package-version '(company . "0.9.0")) | |||
| (defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode)) | |||
| (defvar-local company-semantic--current-tags nil | |||
| "Tags for the current context.") | |||
| (defun company-semantic-documentation-for-tag (tag) | |||
| (when (semantic-tag-buffer tag) | |||
| ;; When TAG's buffer is unknown, the function below raises an error. | |||
| (semantic-documentation-for-tag tag))) | |||
| (defun company-semantic-doc-or-summary (tag) | |||
| (or (company-semantic-documentation-for-tag tag) | |||
| (and (require 'semantic-idle nil t) | |||
| (require 'semantic/idle nil t) | |||
| (funcall semantic-idle-summary-function tag nil t)))) | |||
| (defun company-semantic-summary-and-doc (tag) | |||
| (let ((doc (company-semantic-documentation-for-tag tag)) | |||
| (summary (funcall semantic-idle-summary-function tag nil t))) | |||
| (and (stringp doc) | |||
| (string-match "\n*\\(.*\\)$" doc) | |||
| (setq doc (match-string 1 doc))) | |||
| (concat summary | |||
| (when doc | |||
| (if (< (+ (length doc) (length summary) 4) (window-width)) | |||
| " -- " | |||
| "\n")) | |||
| doc))) | |||
| (defun company-semantic-doc-buffer (tag) | |||
| (let ((doc (company-semantic-documentation-for-tag tag))) | |||
| (when doc | |||
| (company-doc-buffer | |||
| (concat (funcall semantic-idle-summary-function tag nil t) | |||
| "\n" | |||
| doc))))) | |||
| (defsubst company-semantic-completions (prefix) | |||
| (ignore-errors | |||
| (let ((completion-ignore-case nil) | |||
| (context (semantic-analyze-current-context))) | |||
| (setq company-semantic--current-tags | |||
| (semantic-analyze-possible-completions context 'no-unique)) | |||
| (all-completions prefix company-semantic--current-tags)))) | |||
| (defun company-semantic-completions-raw (prefix) | |||
| (setq company-semantic--current-tags nil) | |||
| (dolist (tag (semantic-analyze-find-tags-by-prefix prefix)) | |||
| (unless (eq (semantic-tag-class tag) 'include) | |||
| (push tag company-semantic--current-tags))) | |||
| (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags))) | |||
| (defun company-semantic-annotation (argument tags) | |||
| (let* ((tag (assq argument tags)) | |||
| (kind (when tag (elt tag 1)))) | |||
| (cl-case kind | |||
| (function (let* ((prototype (semantic-format-tag-prototype tag nil nil)) | |||
| (par-pos (string-match "(" prototype))) | |||
| (when par-pos (substring prototype par-pos))))))) | |||
| (defun company-semantic--prefix () | |||
| (if company-semantic-begin-after-member-access | |||
| (company-grab-symbol-cons "\\.\\|->\\|::" 2) | |||
| (company-grab-symbol))) | |||
| ;;;###autoload | |||
| (defun company-semantic (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend using CEDET Semantic." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-semantic)) | |||
| (prefix (and (featurep 'semantic) | |||
| (semantic-active-p) | |||
| (memq major-mode company-semantic-modes) | |||
| (not (company-in-string-or-comment)) | |||
| (or (company-semantic--prefix) 'stop))) | |||
| (candidates (if (and (equal arg "") | |||
| (not (looking-back "->\\|\\." (- (point) 2)))) | |||
| (company-semantic-completions-raw arg) | |||
| (company-semantic-completions arg))) | |||
| (meta (funcall company-semantic-metadata-function | |||
| (assoc arg company-semantic--current-tags))) | |||
| (annotation (company-semantic-annotation arg | |||
| company-semantic--current-tags)) | |||
| (doc-buffer (company-semantic-doc-buffer | |||
| (assoc arg company-semantic--current-tags))) | |||
| ;; Because "" is an empty context and doesn't return local variables. | |||
| (no-cache (equal arg "")) | |||
| (duplicates t) | |||
| (location (let ((tag (assoc arg company-semantic--current-tags))) | |||
| (when (buffer-live-p (semantic-tag-buffer tag)) | |||
| (cons (semantic-tag-buffer tag) | |||
| (semantic-tag-start tag))))) | |||
| (post-completion (let ((anno (company-semantic-annotation | |||
| arg company-semantic--current-tags))) | |||
| (when (and company-semantic-insert-arguments anno) | |||
| (insert anno) | |||
| (company-template-c-like-templatify (concat arg anno))) | |||
| )))) | |||
| (provide 'company-semantic) | |||
| ;;; company-semantic.el ends here | |||
| @ -0,0 +1,214 @@ | |||
| ;;; company-template.el --- utility library for template expansion | |||
| ;; Copyright (C) 2009, 2010, 2014-2016 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Code: | |||
| (require 'cl-lib) | |||
| (defface company-template-field | |||
| '((((background dark)) (:background "yellow" :foreground "black")) | |||
| (((background light)) (:background "orange" :foreground "black"))) | |||
| "Face used for editable text in template fields." | |||
| :group 'company) | |||
| (defvar company-template-nav-map | |||
| (let ((keymap (make-sparse-keymap))) | |||
| (define-key keymap [tab] 'company-template-forward-field) | |||
| (define-key keymap (kbd "TAB") 'company-template-forward-field) | |||
| keymap)) | |||
| (defvar-local company-template--buffer-templates nil) | |||
| ;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-template-templates-at (pos) | |||
| (let (os) | |||
| (dolist (o (overlays-at pos)) | |||
| ;; FIXME: Always return the whole list of templates? | |||
| ;; We remove templates not at point after every command. | |||
| (when (memq o company-template--buffer-templates) | |||
| (push o os))) | |||
| os)) | |||
| (defun company-template-move-to-first (templ) | |||
| (interactive) | |||
| (goto-char (overlay-start templ)) | |||
| (company-template-forward-field)) | |||
| (defun company-template-forward-field () | |||
| (interactive) | |||
| (let* ((start (point)) | |||
| (templates (company-template-templates-at (point))) | |||
| (minimum (apply 'max (mapcar 'overlay-end templates))) | |||
| (fields (cl-loop for templ in templates | |||
| append (overlay-get templ 'company-template-fields)))) | |||
| (dolist (pos (mapcar 'overlay-start fields)) | |||
| (and pos | |||
| (> pos (point)) | |||
| (< pos minimum) | |||
| (setq minimum pos))) | |||
| (push-mark) | |||
| (goto-char minimum) | |||
| (company-template-remove-field (company-template-field-at start)))) | |||
| (defun company-template-field-at (&optional point) | |||
| (cl-loop for ovl in (overlays-at (or point (point))) | |||
| when (overlay-get ovl 'company-template-parent) | |||
| return ovl)) | |||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-template-declare-template (beg end) | |||
| (let ((ov (make-overlay beg end))) | |||
| ;; (overlay-put ov 'face 'highlight) | |||
| (overlay-put ov 'keymap company-template-nav-map) | |||
| (overlay-put ov 'priority 101) | |||
| (overlay-put ov 'evaporate t) | |||
| (push ov company-template--buffer-templates) | |||
| (add-hook 'post-command-hook 'company-template-post-command nil t) | |||
| ov)) | |||
| (defun company-template-remove-template (templ) | |||
| (mapc 'company-template-remove-field | |||
| (overlay-get templ 'company-template-fields)) | |||
| (setq company-template--buffer-templates | |||
| (delq templ company-template--buffer-templates)) | |||
| (delete-overlay templ)) | |||
| (defun company-template-add-field (templ beg end &optional display) | |||
| "Add new field to template TEMPL spanning from BEG to END. | |||
| When DISPLAY is non-nil, set the respective property on the overlay. | |||
| Leave point at the end of the field." | |||
| (cl-assert templ) | |||
| (when (> end (overlay-end templ)) | |||
| (move-overlay templ (overlay-start templ) end)) | |||
| (let ((ov (make-overlay beg end)) | |||
| (siblings (overlay-get templ 'company-template-fields))) | |||
| ;; (overlay-put ov 'evaporate t) | |||
| (overlay-put ov 'intangible t) | |||
| (overlay-put ov 'face 'company-template-field) | |||
| (when display | |||
| (overlay-put ov 'display display)) | |||
| (overlay-put ov 'company-template-parent templ) | |||
| (overlay-put ov 'insert-in-front-hooks '(company-template-insert-hook)) | |||
| (push ov siblings) | |||
| (overlay-put templ 'company-template-fields siblings))) | |||
| (defun company-template-remove-field (ovl &optional clear) | |||
| (when (overlayp ovl) | |||
| (when (overlay-buffer ovl) | |||
| (when clear | |||
| (delete-region (overlay-start ovl) (overlay-end ovl))) | |||
| (delete-overlay ovl)) | |||
| (let* ((templ (overlay-get ovl 'company-template-parent)) | |||
| (siblings (overlay-get templ 'company-template-fields))) | |||
| (setq siblings (delq ovl siblings)) | |||
| (overlay-put templ 'company-template-fields siblings)))) | |||
| (defun company-template-clean-up (&optional pos) | |||
| "Clean up all templates that don't contain POS." | |||
| (let ((local-ovs (overlays-at (or pos (point))))) | |||
| (dolist (templ company-template--buffer-templates) | |||
| (unless (memq templ local-ovs) | |||
| (company-template-remove-template templ))))) | |||
| ;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-template-insert-hook (ovl after-p &rest _ignore) | |||
| "Called when a snippet input prompt is modified." | |||
| (unless after-p | |||
| (company-template-remove-field ovl t))) | |||
| (defun company-template-post-command () | |||
| (company-template-clean-up) | |||
| (unless company-template--buffer-templates | |||
| (remove-hook 'post-command-hook 'company-template-post-command t))) | |||
| ;; common ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-template-c-like-templatify (call) | |||
| (let* ((end (point-marker)) | |||
| (beg (- (point) (length call))) | |||
| (templ (company-template-declare-template beg end)) | |||
| paren-open paren-close) | |||
| (with-syntax-table (make-syntax-table (syntax-table)) | |||
| (modify-syntax-entry ?< "(") | |||
| (modify-syntax-entry ?> ")") | |||
| (when (search-backward ")" beg t) | |||
| (setq paren-close (point-marker)) | |||
| (forward-char 1) | |||
| (delete-region (point) end) | |||
| (backward-sexp) | |||
| (forward-char 1) | |||
| (setq paren-open (point-marker))) | |||
| (when (search-backward ">" beg t) | |||
| (let ((angle-close (point-marker))) | |||
| (forward-char 1) | |||
| (backward-sexp) | |||
| (forward-char) | |||
| (company-template--c-like-args templ angle-close))) | |||
| (when (looking-back "\\((\\*)\\)(" (line-beginning-position)) | |||
| (delete-region (match-beginning 1) (match-end 1))) | |||
| (when paren-open | |||
| (goto-char paren-open) | |||
| (company-template--c-like-args templ paren-close))) | |||
| (if (overlay-get templ 'company-template-fields) | |||
| (company-template-move-to-first templ) | |||
| (company-template-remove-template templ) | |||
| (goto-char end)))) | |||
| (defun company-template--c-like-args (templ end) | |||
| (let ((last-pos (point))) | |||
| (while (re-search-forward "\\([^,]+\\),?" end 'move) | |||
| (when (zerop (car (parse-partial-sexp last-pos (point)))) | |||
| (company-template-add-field templ last-pos (match-end 1)) | |||
| (skip-chars-forward " ") | |||
| (setq last-pos (point)))))) | |||
| ;; objc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-template-objc-templatify (selector) | |||
| (let* ((end (point-marker)) | |||
| (beg (- (point) (length selector) 1)) | |||
| (templ (company-template-declare-template beg end)) | |||
| (cnt 0)) | |||
| (save-excursion | |||
| (goto-char beg) | |||
| (catch 'stop | |||
| (while (search-forward ":" end t) | |||
| (if (looking-at "\\(([^)]*)\\) ?") | |||
| (company-template-add-field templ (point) (match-end 1)) | |||
| ;; Not sure which conditions this case manifests under, but | |||
| ;; apparently it did before, when I wrote the first test for this | |||
| ;; function. FIXME: Revisit it. | |||
| (company-template-add-field templ (point) | |||
| (progn | |||
| (insert (format "arg%d" cnt)) | |||
| (point))) | |||
| (when (< (point) end) | |||
| (insert " ")) | |||
| (cl-incf cnt)) | |||
| (when (>= (point) end) | |||
| (throw 'stop t))))) | |||
| (company-template-move-to-first templ))) | |||
| (provide 'company-template) | |||
| ;;; company-template.el ends here | |||
| @ -0,0 +1,71 @@ | |||
| ;;; company-tempo.el --- company-mode completion backend for tempo | |||
| ;; Copyright (C) 2009-2011, 2015 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (require 'tempo) | |||
| (defgroup company-tempo nil | |||
| "Tempo completion backend." | |||
| :group 'company) | |||
| (defcustom company-tempo-expand nil | |||
| "Whether to expand a tempo tag after completion." | |||
| :type '(choice (const :tag "Off" nil) | |||
| (const :tag "On" t))) | |||
| (defsubst company-tempo-lookup (match) | |||
| (cdr (assoc match (tempo-build-collection)))) | |||
| (defun company-tempo-insert (match) | |||
| "Replace MATCH with the expanded tempo template." | |||
| (search-backward match) | |||
| (goto-char (match-beginning 0)) | |||
| (replace-match "") | |||
| (call-interactively (company-tempo-lookup match))) | |||
| (defsubst company-tempo-meta (match) | |||
| (let ((templ (company-tempo-lookup match)) | |||
| doc) | |||
| (and templ | |||
| (setq doc (documentation templ t)) | |||
| (car (split-string doc "\n" t))))) | |||
| ;;;###autoload | |||
| (defun company-tempo (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for tempo." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-tempo)) | |||
| (prefix (or (car (tempo-find-match-string tempo-match-finder)) "")) | |||
| (candidates (all-completions arg (tempo-build-collection))) | |||
| (meta (company-tempo-meta arg)) | |||
| (post-completion (when company-tempo-expand (company-tempo-insert arg))) | |||
| (sorted t))) | |||
| (provide 'company-tempo) | |||
| ;;; company-tempo.el ends here | |||
| @ -0,0 +1,123 @@ | |||
| ;;; company-xcode.el --- company-mode completion backend for Xcode projects | |||
| ;; Copyright (C) 2009-2011, 2014 Free Software Foundation, Inc. | |||
| ;; Author: Nikolaj Schumacher | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (defgroup company-xcode nil | |||
| "Completion backend for Xcode projects." | |||
| :group 'company) | |||
| (defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex") | |||
| "Location of xcodeindex executable." | |||
| :type 'file) | |||
| (defvar company-xcode-tags nil) | |||
| (defun company-xcode-reset () | |||
| "Reset the cached tags." | |||
| (interactive) | |||
| (setq company-xcode-tags nil)) | |||
| (defcustom company-xcode-types | |||
| '("Class" "Constant" "Enum" "Macro" "Modeled Class" "Structure" | |||
| "Type" "Union" "Function") | |||
| "The types of symbols offered by `company-xcode'. | |||
| No context-enabled completion is available. Types like methods will be | |||
| offered regardless of whether the class supports them. The defaults should be | |||
| valid in most contexts." | |||
| :set (lambda (variable value) | |||
| (set variable value) | |||
| (company-xcode-reset)) | |||
| :type '(set (const "Category") (const "Class") (const "Class Method") | |||
| (const "Class Variable") (const "Constant") (const "Enum") | |||
| (const "Field") (const "Instance Method") | |||
| (const "Instance Variable") (const "Macro") | |||
| (const "Modeled Class") (const "Modeled Method") | |||
| (const "Modeled Property") (const "Property") (const "Protocol") | |||
| (const "Structure") (const "Type") (const "Union") | |||
| (const "Variable") (const "Function"))) | |||
| (defvar-local company-xcode-project 'unknown) | |||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
| (defun company-xcode-fetch (project-bundle) | |||
| (setq project-bundle (directory-file-name project-bundle)) | |||
| (message "Retrieving dump from %s..." project-bundle) | |||
| (with-temp-buffer | |||
| (let ((default-directory (file-name-directory project-bundle))) | |||
| (call-process company-xcode-xcodeindex-executable nil (current-buffer) | |||
| nil "dump" "-project" | |||
| (file-name-nondirectory project-bundle) "-quiet") | |||
| (goto-char (point-min)) | |||
| (let ((regexp (concat "^\\([^\t\n]*\\)\t[^\t\n]*\t" | |||
| (regexp-opt company-xcode-types) | |||
| "\t[^\t\n]*\t[^\t\n]*")) | |||
| candidates) | |||
| (while (re-search-forward regexp nil t) | |||
| (cl-pushnew (match-string 1) candidates :test #'equal)) | |||
| (message "Retrieving dump from %s...done" project-bundle) | |||
| candidates)))) | |||
| (defun company-xcode-find-project () | |||
| (let ((dir (if buffer-file-name | |||
| (file-name-directory buffer-file-name) | |||
| (expand-file-name default-directory))) | |||
| (prev-dir nil) | |||
| file) | |||
| (while (not (or file (equal dir prev-dir))) | |||
| (setq file (car (directory-files dir t ".xcodeproj\\'" t)) | |||
| prev-dir dir | |||
| dir (file-name-directory (directory-file-name dir)))) | |||
| file)) | |||
| (defun company-xcode-tags () | |||
| (when (eq company-xcode-project 'unknown) | |||
| (setq company-xcode-project (company-xcode-find-project))) | |||
| (when company-xcode-project | |||
| (cdr (or (assoc company-xcode-project company-xcode-tags) | |||
| (car (push (cons company-xcode-project | |||
| (company-xcode-fetch company-xcode-project)) | |||
| company-xcode-tags)))))) | |||
| ;;;###autoload | |||
| (defun company-xcode (command &optional arg &rest ignored) | |||
| "`company-mode' completion backend for Xcode projects." | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-xcode)) | |||
| (prefix (and company-xcode-xcodeindex-executable | |||
| (company-xcode-tags) | |||
| (not (company-in-string-or-comment)) | |||
| (or (company-grab-symbol) 'stop))) | |||
| (candidates (let ((completion-ignore-case nil)) | |||
| (company-xcode-tags) | |||
| (all-completions arg (company-xcode-tags)))))) | |||
| (provide 'company-xcode) | |||
| ;;; company-xcode.el ends here | |||
| @ -0,0 +1,147 @@ | |||
| ;;; company-yasnippet.el --- company-mode completion backend for Yasnippet | |||
| ;; Copyright (C) 2014, 2015 Free Software Foundation, Inc. | |||
| ;; Author: Dmitry Gutov | |||
| ;; This file is part of GNU Emacs. | |||
| ;; GNU Emacs is free software: you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; GNU Emacs is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; | |||
| ;;; Code: | |||
| (require 'company) | |||
| (require 'cl-lib) | |||
| (declare-function yas--table-hash "yasnippet") | |||
| (declare-function yas--get-snippet-tables "yasnippet") | |||
| (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)) | |||
| res) | |||
| (when keyhash | |||
| (maphash | |||
| (lambda (key value) | |||
| (when (and (stringp key) | |||
| (string-prefix-p key-prefix key)) | |||
| (maphash | |||
| (lambda (name template) | |||
| (push | |||
| (propertize key | |||
| 'yas-annotation name | |||
| 'yas-template template | |||
| 'yas-prefix-offset (- (length key-prefix) | |||
| (length prefix))) | |||
| res)) | |||
| value))) | |||
| keyhash)) | |||
| res)) | |||
| tables)) | |||
| ;;;###autoload | |||
| (defun company-yasnippet (command &optional arg &rest ignore) | |||
| "`company-mode' backend for `yasnippet'. | |||
| 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 backend or | |||
| several that provide actual text completions. | |||
| (add-hook 'js-mode-hook | |||
| (lambda () | |||
| (set (make-local-variable 'company-backends) | |||
| '((company-dabbrev-code company-yasnippet))))) | |||
| * After keyword `:with', grouped with other 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) | |||
| " | |||
| (interactive (list 'interactive)) | |||
| (cl-case command | |||
| (interactive (company-begin-backend 'company-yasnippet)) | |||
| (prefix | |||
| ;; Should probably use `yas--current-key', but that's bound to be slower. | |||
| ;; How many trigger keys start with non-symbol characters anyway? | |||
| (and (bound-and-true-p yas-minor-mode) | |||
| (company-grab-symbol))) | |||
| (annotation | |||
| (concat | |||
| (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)) | |||
| (prefix-offset (get-text-property 0 'yas-prefix-offset arg))) | |||
| (yas-expand-snippet (yas--template-content template) | |||
| (- (point) (length arg) prefix-offset) | |||
| (point) | |||
| (yas--template-expand-env template)))))) | |||
| (provide 'company-yasnippet) | |||
| ;;; company-yasnippet.el ends here | |||