--- /dev/null
+((nil . ((indent-tabs-mode . nil)
+ (fill-column . 80))))
-Company is an Emacs extension for performing text completion.
-Completion candidates are retrieved from a variety of modular
-back-ends, such as Semantic.
-
-Once installed, enable company-mode with M-x company-mode.
-For further information, see the docstring for `company-mode'.
+Company is a modular in-buffer completion framework.\r
+\r
+See <http://company-mode.github.com/> for more information.\r
;;; Commentary:
-;;
+;;
;;; Code:
;;; company-clang.el --- A company-mode completion back-end for clang
-;; Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
;;; Code:
(defcustom company-clang-executable
(executable-find "clang")
- "*Location of clang executable."
+ "Location of clang executable."
:group 'company-clang
:type 'file)
(defcustom company-clang-auto-save t
- "*Determines whether to save the buffer when retrieving completions.
+ "Determines whether to save the buffer when retrieving completions.
clang can only complete correctly when the buffer has been saved."
:group 'company-clang
:type '(choice (const :tag "Off" nil)
(const :tag "On" t)))
(defcustom company-clang-arguments nil
- "*Additional arguments to pass to clang when completing.
+ "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" nil)))
(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix
- "*A function to determine the prefix file for the current buffer."
+ "A function to determine the prefix file for the current buffer."
:group 'company-clang
:type '(function :tag "Guesser function" nil))
;; 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 (company-clang--file-substring file 0 4)))
+ (magic-number (and file (company-clang--file-substring file 0 4))))
(unless (member magic-number '("CPCH" "gpch"))
file)))
;; TODO: How to handle OVERLOAD and Pattern?
(defconst company-clang--completion-pattern
- "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)")
+ "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?")
(defconst company-clang--error-buffer-name "*clang error*")
+(defvar company-clang--meta-cache nil)
+
(defun company-clang--parse-output (prefix)
(goto-char (point-min))
(let ((pattern (format company-clang--completion-pattern
(regexp-quote prefix)))
+ (case-fold-search nil)
lines match)
+ (setq company-clang--meta-cache (make-hash-table :test 'equal))
(while (re-search-forward pattern nil t)
(setq match (match-string-no-properties 1))
+ (let ((meta (match-string-no-properties 2)))
+ (when (and meta (not (string= match meta)))
+ (puthash match meta company-clang--meta-cache)))
(unless (equal match "Pattern")
(push match lines)))
lines))
(1+ (current-column)))))
(defsubst company-clang--build-complete-args (pos)
- (append '("-cc1" "-fsyntax-only")
+ (append '("-cc1" "-fsyntax-only" "-code-completion-macros")
company-clang-arguments
(when (stringp company-clang--prefix)
(list "-include" (expand-file-name company-clang--prefix)))
(with-temp-buffer
(call-process company-clang-executable nil t nil "--version")
(goto-char (point-min))
- (when (re-search-forward "\\`clang version \\([0-9.]+\\)" nil t)
- (match-string-no-properties 1))))
+ (if (re-search-forward "clang version \\([0-9.]+\\)" nil t)
+ (match-string-no-properties 1)
+ "0")))
(defun company-clang-objc-templatify (selector)
(let* ((end (point))
(not (company-in-string-or-comment))
(or (company-grab-symbol) 'stop)))
(candidates (company-clang--candidates arg))
+ (meta (let ((meta (gethash arg company-clang--meta-cache)))
+ (when meta
+ (replace-regexp-in-string
+ "#]" " "
+ (replace-regexp-in-string "[<{[]#\\|#[>}]" "" meta t)
+ t))))
(post-completion (and (derived-mode-p 'objc-mode)
(string-match ":" arg)
(company-clang-objc-templatify arg)))))
(case command
(interactive (company-begin-backend 'company-css))
(prefix (and (derived-mode-p 'css-mode)
- (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))))
+ (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)
;;; Commentary:
-;;
+;;
;;; Code:
haskell-mode java-mode javascript-mode jde-mode js2-mode lisp-mode
lua-mode objc-mode perl-mode php-mode python-mode ruby-mode scheme-mode
shell-script-mode)
- "*Modes that use `company-dabbrev-code'.
+ "Modes that use `company-dabbrev-code'.
In all these modes `company-dabbrev-code' will complete only symbols, not text
in comments or strings. In other modes `company-dabbrev-code' will pass control
-to other back-ends \(e.g. `company-dabbrev'\).
+to other back-ends \(e.g. `company-dabbrev'\).
Value t means complete in all modes."
:group 'company
:type '(choice (repeat (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.
+ "Determines whether `company-dabbrev-code' should search other buffers.
If `all', search all other buffers. If t, search buffers with the same
major mode.
See also `company-dabbrev-code-time-limit'."
(const :tag "All" all)))
(defcustom company-dabbrev-code-time-limit .5
- "*Determines how long `company-dabbrev-code' should look for matches."
+ "Determines how long `company-dabbrev-code' should look for matches."
:group 'company
:type '(choice (const :tag "Off" nil)
(number :tag "Seconds")))
(apply 'derived-mode-p company-dabbrev-code-modes))
(not (company-in-string-or-comment))
(or (company-grab-symbol) 'stop)))
- (candidates (let ((completion-ignore-case nil))
+ (candidates (let ((case-fold-search nil))
(company-dabbrev--search
(company-dabbrev-code--make-regexp arg)
company-dabbrev-code-time-limit
;;; Commentary:
-;;
+;;
;;; Code:
(eval-when-compile (require 'cl))
(defcustom company-dabbrev-other-buffers 'all
- "*Determines whether `company-dabbrev' should search other buffers.
+ "Determines whether `company-dabbrev' should search other buffers.
If `all', search all other buffers. If t, search buffers with the same
major mode.
See also `company-dabbrev-time-limit'."
(const :tag "All" all)))
(defcustom company-dabbrev-time-limit .5
- "*Determines how many seconds `company-dabbrev' should look for matches."
+ "Determines how many seconds `company-dabbrev' should look for matches."
:group 'company
: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."
+ "A regular expression matching the characters `company-dabbrev' looks for."
:group 'company
:type 'regexp)
;;; company-eclim.el --- A company-mode completion back-end for eclim.
-;; Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;; 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:
-;;
+;;
+;; Eclim version 1.7.13 or newer (?) is required.
+;;
+;; This completion backend is pretty barebone.
+;;
+;; `emacs-eclim' provides an alternative backend, and it also allows you to
+;; actually control Eclim from Emacs.
;;; Code:
(defcustom company-eclim-executable
(or (executable-find "eclim") (company-eclim-executable-find))
- "*Location of eclim executable."
+ "Location of eclim executable."
:group 'company
:type 'file)
(defcustom company-eclim-auto-save t
- "*Determines whether to save the buffer when retrieving completions.
+ "Determines whether to save the buffer when retrieving completions.
eclim can only complete correctly when the buffer has been saved."
:group 'company
:type '(choice (const :tag "Off" nil)
(defvar company-eclim--doc nil)
(make-variable-buffer-local 'company-eclim--doc)
-(defun company-eclim--buffer-lines ()
- (goto-char (point-max))
- (let (lines)
- (while (= 0 (forward-line -1))
- (push (buffer-substring-no-properties (point-at-bol) (point-at-eol))
- lines))
- lines))
-
(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)))
- (company-eclim--buffer-lines)
+ (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 ()
- (mapcar (lambda (line) (nreverse (split-string line " *- *" nil)))
- (company-eclim--call-process "project_list")))
+ (company-eclim--call-process "project_list"))
(defun company-eclim--project-dir ()
(if (eq company-eclim--project-dir 'unknown)
(defun company-eclim--project-name ()
(if (eq company-eclim--project-name 'unknown)
(setq company-eclim--project-name
- (car (cddr (assoc (company-eclim--project-dir)
- (company-eclim--project-list)))))
+ (let ((project (find-if (lambda (project)
+ (equal (cdr (assoc 'path project))
+ (company-eclim--project-dir)))
+ (company-eclim--project-list))))
+ (when project
+ (cdr (assoc 'name project)))))
company-eclim--project-name))
(defun company-eclim--candidates (prefix)
(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))
+ "-p" (company-eclim--project-name)
+ "-f" project-file))
(setq company-eclim--doc
- (mapcar (lambda (line)
- (cdr (split-string line "|" nil)))
- (company-eclim--call-process
- "java_complete" "-p" (company-eclim--project-name)
- "-f" project-file
- "-o" (number-to-string (1- (point)))
- "-e" "utf-8"
- "-l" "standard"))))
+ (cdr (assoc 'completions
+ (company-eclim--call-process
+ "java_complete" "-p" (company-eclim--project-name)
+ "-f" project-file
+ "-o" (number-to-string (1- (point)))
+ "-e" "utf-8"
+ "-l" "standard")))))
(let ((completion-ignore-case nil))
- (all-completions prefix (mapcar 'car company-eclim--doc))))
+ ;; TODO: Handle overloaded methods somehow. Show one candidate per overload?
+ ;; That would look nice, but kinda useless: a bunch of candidates for the
+ ;; same completion. Maybe do expansion like `company-clang-objc-templatify'.
+ (all-completions prefix (mapcar (lambda (item) (cdr (assoc 'completion item)))
+ company-eclim--doc))))
+
+(defun company-eclim--meta (candidate)
+ (cdr (assoc 'info (find-if
+ (lambda (item) (equal (cdr (assoc 'completion item))
+ arg))
+ company-eclim--doc))))
(defun company-eclim (command &optional arg &rest ignored)
"A `company-mode' completion back-end for eclim.
(not (company-in-string-or-comment))
(or (company-grab-symbol) 'stop)))
(candidates (company-eclim--candidates arg))
- (meta (cadr (assoc arg company-eclim--doc)))
+ (meta (company-eclim--meta arg))
+ (duplicates t)
;; because "" doesn't return everything
(no-cache (equal arg ""))))
;;; company-elisp.el --- A company-mode completion back-end for emacs-lisp-mode
-;; Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011-2012 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
;;; Code:
(require 'help-mode)
(defcustom company-elisp-detect-function-context t
- "*If enabled, offer Lisp functions only in appropriate contexts.
+ "If enabled, offer Lisp functions only in appropriate contexts.
Functions are offered for completion only after ' and \(."
:group 'company
:type '(choice (const :tag "Off" nil)
(defun company-elisp-predicate (symbol)
(or (boundp symbol)
- (fboundp symbol)))
+ (fboundp symbol)
+ (facep symbol)
+ (featurep symbol)))
(defvar company-elisp-parse-limit 30)
(defvar company-elisp-parse-depth 100)
(meta (company-elisp-doc arg))
(doc-buffer (let ((symbol (intern arg)))
(save-window-excursion
- (when (or (ignore-errors (describe-function symbol))
- (ignore-errors (describe-variable symbol)))
+ (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)))
- (or (ignore-errors (find-definition-noselect sym nil))
- (ignore-errors (find-definition-noselect sym 'defvar))
- (ignore-errors (find-definition-noselect sym t)))))))
+ (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
;;; Commentary:
-;;
+;;
;;; Code:
(require 'company)
-(eval-when-compile (require 'etags))
-(eval-when-compile (require 'cl))
+(require 'etags)
(defcustom company-etags-use-main-table-list t
- "*Always search `tags-table-list' if set.
+ "Always search `tags-table-list' if set.
If this is disabled, `company-etags' will try to find the one table for each
buffer automatically."
:group 'company-mode
(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 nil))
+ (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)
"A `company-mode' completion back-end for etags."
(interactive (company-begin-backend 'company-etags))
(prefix (and (memq major-mode company-etags-modes)
(not (company-in-string-or-comment))
- (require 'etags nil t)
(company-etags-buffer-table)
(or (company-grab-symbol) 'stop)))
- (candidates (let ((tags-table-list (company-etags-buffer-table))
- (completion-ignore-case nil))
- (and (or tags-file-name tags-table-list)
- (fboundp 'tags-completion-table)
- tags-table-list
- (all-completions arg (tags-completion-table)))))
+ (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))))))))
- (sorted t)))
+ (cons buffer (with-current-buffer buffer (point))))))))))
(provide 'company-etags)
;;; company-etags.el ends here
;;; company-files.el --- A company-mode completion back-end for file names
-;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
;;; Code:
(when (file-directory-p file)
;; Add one level of children.
(dolist (child (company-files-directory-files file ""))
- (push (concat file child) candidates))))
+ (push (concat file
+ (unless (eq (aref file (1- (length file))) ?/) "/")
+ child) candidates))))
(setq company-files-completion-cache (cons dir (nreverse candidates))))
(cdr company-files-completion-cache)))
;;; Commentary:
-;;
+;;
;;; Code:
(defcustom company-gtags-executable
(executable-find "global")
- "*Location of GNU global executable."
+ "Location of GNU global executable."
:type 'string
:group 'company)
;;; Commentary:
-;;
+;;
;;; Code:
(eval-when-compile (require 'cl))
(defcustom company-ispell-dictionary nil
- "*Dictionary to use for `company-ispell'.
+ "Dictionary to use for `company-ispell'.
If nil, use `ispell-complete-word-dict'."
:group 'company
:type '(choice (const :tag "default (nil)" nil)
;;; Commentary:
-;;
+;;
;;; Code:
(espresso-mode . javascript-mode)
(cperl-mode . perl-mode)
(jde-mode . java-mode))
- "*Alist mapping major-modes to sorted keywords for `company-keywords'.")
+ "Alist mapping major-modes to sorted keywords for `company-keywords'.")
;;;###autoload
(defun company-keywords (command &optional arg &rest ignored)
"A `company-mode' back-end for programming language keywords."
(interactive (list 'interactive))
(case command
- (interactive (company-begin-backend 'company-))
+ (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)))
(provide 'company-keywords)
;;; company-keywords.el ends here
-
-
;;; company-nxml.el --- A company-mode completion back-end for nxml-mode
-;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
;;; Code:
(require 'company)
-(require 'nxml-mode)
-(require 'rng-nxml)
(eval-when-compile (require 'cl))
+(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:]]*\\_>\\)")
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))))
+ (company-nxml-all-completions
+ arg (rng-match-possible-start-tag-names))))
(sorted t)))
(defun company-nxml-attribute (command &optional arg &rest ignored)
(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)))
+ 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)))))
+ (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)
(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))))))))
+ (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)
;;; Commentary:
-;;
+;;
;;; Code:
;;; Commentary:
-;;
+;;
+;; The main problem with using this backend is installing Pysmell.
+;; I couldn't manage to do that. --Dmitry
;;; Code:
;;; company-ropemacs.el --- A company-mode completion back-end for pysmell.el
-;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
+;; Requires pymacs Emacs package (you can get it from Marmalade),
+;; and on Python side: pymacs, rope, ropemacs and ropemode.
;;; Code:
(eval-when-compile (require 'cl))
-(require 'pymacs)
-
-(unless (fboundp 'rope-completions)
- (pymacs-load "ropemacs" "rope-"))
-
-(unless (fboundp 'rope-completions)
- (error "rope-completions not found, try development version of ropemacs"))
(defun company-ropemacs--grab-symbol ()
(let ((symbol (company-grab-symbol)))
"A `company-mode' completion back-end for ropemacs."
(interactive (list 'interactive))
(case command
+ (init (when (and (derived-mode-p 'python-mode)
+ (not (fboundp 'rope-completions)))
+ (require 'pymacs)
+ (pymacs-load "ropemacs" "rope-")))
(interactive (company-begin-backend 'company-ropemacs))
(prefix (and (derived-mode-p 'python-mode)
(not (company-in-string-or-comment))
;;; company-semantic.el --- A company-mode back-end using CEDET Semantic
-;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
;;; Commentary:
-;;
+;;
;;; Code:
(require 'company)
-(or (require 'semantic-analyze nil t)
- (require 'semantic/analyze))
(eval-when-compile (require 'cl))
+(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")
+
(defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
- "*The function turning a semantic tag into doc information."
+ "The function turning a semantic tag into doc information."
:group 'company
:type 'function)
(interactive (list 'interactive))
(case command
(interactive (company-begin-backend 'company-semantic))
- (prefix (and (memq major-mode company-semantic-modes)
+ (prefix (and (featurep 'semantic)
(semantic-active-p)
+ (memq major-mode company-semantic-modes)
(not (company-in-string-or-comment))
(or (company-semantic--grab) 'stop)))
(candidates (if (and (equal arg "")
(defface company-template-field
'((((background dark)) (:background "yellow" :foreground "black"))
(((background light)) (:background "orange" :foreground "black")))
- "*Face used for editable text in template fields."
+ "Face used for editable text in template fields."
:group 'company)
(defvar company-template-nav-map
(remove-hook 'post-command-hook 'company-template-post-command t)))
(provide 'company-template)
-
;;; company-template.el ends here
;;; Commentary:
-;;
+;;
;;; Code:
--- /dev/null
+(require 'ert)
+(require 'company)
+(require 'company-keywords)
+
+(ert-deftest sorted-keywords ()
+ "Test that keywords in `company-keywords-alist' are in alphabetical order."
+ (dolist (pair company-keywords-alist)
+ (when (consp (cdr pair))
+ (let ((prev (cadr pair)))
+ (dolist (next (cddr pair))
+ (should (not (equal prev next)))
+ (should (string< prev next))
+ (setq prev next))))))
;;; Commentary:
-;;
+;;
;;; Code:
(eval-when-compile (require 'cl))
(defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex")
- "*Location of xcodeindex executable."
+ "Location of xcodeindex executable."
:group 'company-xcode
:type 'file)
(defcustom company-xcode-types
'("Class" "Constant" "Enum" "Macro" "Modeled Class" "Structure"
"Type" "Union" "Function")
- "*The types of symbols offered by `company-xcode'.
+ "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."
;;; company.el --- Extensible inline text completion mechanism
-;; Copyright (C) 2009-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
-;; Version: 0.5
+;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
+;; Version: 0.6
;; Keywords: abbrev, convenience, matching
-;; URL: http://nschum.de/src/emacs/company-mode/
-;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
+;; URL: http://company-mode.github.com/
+;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x, GNU Emacs 24.x
;; This file is part of GNU Emacs.
;; candidates are called back-ends, modules for displaying them are front-ends.
;;
;; Company comes with many back-ends, e.g. `company-elisp'. These are
-;; distributed in individual files and can be used individually.
+;; distributed in separate files and can be used individually.
;;
;; Place company.el and the back-ends you want to use in a directory and add the
;; following to your .emacs:
;; (defun company-my-backend (command &optional arg &rest ignored)
;; (case command
;; (prefix (when (looking-back "foo\\>")
-;; (match-string 0)))
+;; (match-string 0)))
;; (candidates (list "foobar" "foobaz" "foobarbaz"))
;; (meta (format "This value is named %s" arg))))
;;
-;; Sometimes it is a good idea to mix two back-ends together, for example to
-;; enrich gtags with dabbrev-code results (to emulate local variables):
-;; To do this, add a list with the merged back-ends as an element in
-;; company-backends.
+;; Sometimes it is a good idea to mix several back-ends together, for example to
+;; enrich gtags with dabbrev-code results (to emulate local variables).
+;; To do this, add a list with both back-ends as an element in company-backends.
;;
;; Known Issues:
;; When point is at the very end of the buffer, the pseudo-tooltip appears very
;;
;;; Change Log:
;;
+;; 2013-03-19 (0.6)
+;; Switching between tag files now works correctly with `company-etags'.
+;; Clang completions now include macros and are case-sensitive.
+;; Added `company-capf': completion adapter using
+;; `completion-at-point-functions'. (Stefan Monnier)
+;; `company-elisp' has some improvements.
+;; Instead of `overrriding-terminal-local-map', we're now using
+;; `emulation-mode-map-alists' (experimental). This largely means that when
+;; the completion keymap is active, other minor modes' keymaps are still
+;; used, so, for example, it's not as easy to circumvent `paredit-mode'
+;; accidentally when it's enabled.
+;; Fixed two old tooltip annoyances.
+;; Some performance improvements.
+;; `company-clang' now shows meta information, too.
+;; Candidates from grouped back-ends are merged more conservatively: only
+;; back-ends that return the same prefix at point are used.
+;; Loading of `nxml', `semantic', `pymacs' and `ropemacs' is now deferred.
+;; `company-pysmell' is not used by default anymore.
+;; Across-the-board bugfixing.
+;;
;; 2010-02-24 (0.5)
;; `company-ropemacs' now provides location and docs. (Fernando H. Silva)
;; Added `company-with-candidate-inserted' macro.
(defface company-tooltip
'((t :background "yellow"
:foreground "black"))
- "*Face used for the tool tip."
+ "Face used for the tool tip."
:group 'company)
(defface company-tooltip-selection
'((default :inherit company-tooltip)
(((class color) (min-colors 88)) (:background "orange1"))
(t (:background "green")))
- "*Face used for the selection in the tool tip."
+ "Face used for the selection in the tool tip."
:group 'company)
(defface company-tooltip-mouse
'((default :inherit highlight))
- "*Face used for the tool tip item under the mouse."
+ "Face used for the tool tip item under the mouse."
:group 'company)
(defface company-tooltip-common
'((t :inherit company-tooltip
:foreground "red"))
- "*Face used for the common completion in the tool tip."
+ "Face used for the common completion in the tool tip."
:group 'company)
(defface company-tooltip-common-selection
'((t :inherit company-tooltip-selection
:foreground "red"))
- "*Face used for the selected common completion in the tool tip."
+ "Face used for the selected common completion in the tool tip."
:group 'company)
(defface company-preview
'((t :background "blue4"
:foreground "wheat"))
- "*Face used for the completion preview."
+ "Face used for the completion preview."
:group 'company)
(defface company-preview-common
'((t :inherit company-preview
:foreground "red"))
- "*Face used for the common part of the completion preview."
+ "Face used for the common part of the completion preview."
:group 'company)
(defface company-preview-search
'((t :inherit company-preview
:background "blue1"))
- "*Face used for the search string in the completion preview."
+ "Face used for the search string in the completion preview."
:group 'company)
(defface company-echo nil
- "*Face used for completions in the echo area."
+ "Face used for completions in the echo area."
:group 'company)
(defface company-echo-common
'((((background dark)) (:foreground "firebrick1"))
(((background light)) (:background "firebrick4")))
- "*Face used for the common part of completions in the echo area."
+ "Face used for the common part of completions in the echo area."
:group 'company)
(defun company-frontends-set (variable value)
(defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
company-preview-if-just-one-frontend
company-echo-metadata-frontend)
- "*The list of active front-ends (visualizations).
+ "The list of active front-ends (visualizations).
Each front-end is a function that takes one argument. It is called with
one of the following arguments:
(function :tag "custom function" nil))))
(defcustom company-tooltip-limit 10
- "*The maximum number of candidates in the tool tip"
+ "The maximum number of candidates in the tool tip"
:group 'company
:type 'integer)
(defcustom company-tooltip-minimum 6
- "*The minimum height of the tool tip.
+ "The minimum height of the tool tip.
If this many lines are not available, prefer to display the tooltip above."
:group 'company
:type 'integer)
(return t))))))
(defun company-capf (command &optional arg &rest args)
- "Adapter for Company completion to use `completion-at-point-functions'."
+ "`company-mode' back-end using `completion-at-point-functions'.
+Requires Emacs 24.1 or newer."
(interactive (list 'interactive))
(case command
(interactive (company-begin-backend 'company-capf))
;; Ignore misbehaving functions.
#'completion--capf-wrapper 'optimist)))
(when (consp res)
- (if (> (nth 1 res) (point))
+ (if (> (nth 2 res) (point))
'stop
- (buffer-substring-no-properties (nth 0 res) (point))))))
+ (buffer-substring-no-properties (nth 1 res) (point))))))
(candidates
(let ((res (run-hook-wrapped 'completion-at-point-functions
;; Ignore misbehaving functions.
#'completion--capf-wrapper 'optimist)))
(when (consp res)
- (all-completions arg (nth 2 res)
- (plist-get (nthcdr 3 res) :predicate)))))))
+ (all-completions arg (nth 3 res)
+ (plist-get (nthcdr 4 res) :predicate)))))))
-(defcustom company-backends '(;; company-capf ;FIXME: Untested!
- company-elisp company-nxml company-css
- company-eclim company-semantic company-clang
+(defcustom company-backends '(company-elisp company-nxml company-css
+ company-clang company-semantic company-eclim
company-xcode company-ropemacs
(company-gtags company-etags company-dabbrev-code
- company-pysmell company-keywords)
+ company-keywords)
company-oddmuse company-files company-dabbrev)
- "*The list of active back-ends (completion engines).
+ "The list of active back-ends (completion engines).
Each list elements can itself be a list of back-ends. In that case their
completions are merged. Otherwise only the first matching back-end returns
results.
(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
(defcustom company-completion-started-hook nil
- "*Hook run when company starts completing.
+ "Hook run when company starts completing.
The hook is called with one argument that is non-nil if the completion was
started manually."
:group 'company
:type 'hook)
(defcustom company-completion-cancelled-hook nil
- "*Hook run when company cancels completing.
+ "Hook run when company cancels completing.
The hook is called with one argument that is non-nil if the completion was
aborted manually."
:group 'company
:type 'hook)
(defcustom company-completion-finished-hook nil
- "*Hook run when company successfully completes.
+ "Hook run when company successfully completes.
The hook is called with the selected candidate as an argument."
:group 'company
:type 'hook)
(defcustom company-minimum-prefix-length 3
- "*The minimum prefix length for automatic completion."
+ "The minimum prefix length for automatic completion."
:group 'company
:type '(integer :tag "prefix length"))
(defcustom company-require-match 'company-explicit-action-p
- "*If enabled, disallow non-matching input.
+ "If enabled, disallow non-matching input.
This can be a function do determine if a match is required.
This can be overridden by the back-end, if it returns t or 'never to
(function :tag "Predicate function")))
(defcustom company-idle-delay .7
- "*The idle delay in seconds until automatic completions starts.
+ "The idle delay in seconds until automatic completions starts.
A value of nil means never complete automatically, t means complete
immediately when a prefix of `company-minimum-prefix-length' is reached."
:group 'company
(number :tag "seconds")))
(defcustom company-begin-commands t
- "*A list of commands following which company will start completing.
+ "A list of commands following which company will start completing.
If this is t, it will complete after any command. See `company-idle-delay'.
Alternatively any command with a non-nil 'company-begin property is treated as
(repeat :tag "Commands" function)))
(defcustom company-show-numbers nil
- "*If enabled, show quick-access numbers for the first ten candidates."
+ "If enabled, show quick-access numbers for the first ten candidates."
:group 'company
:type '(choice (const :tag "off" nil)
(const :tag "on" t)))
(defvar company-end-of-buffer-workaround t
- "*Work around a visualization bug when completing at the end of the buffer.
+ "Work around a visualization bug when completing at the end of the buffer.
The work-around consists of adding a newline.")
;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-key keymap [mouse-3] 'company-select-mouse)
(define-key keymap [up-mouse-1] 'ignore)
(define-key keymap [up-mouse-3] 'ignore)
- (define-key keymap "\C-m" 'company-complete-selection)
- (define-key keymap "\t" 'company-complete-common)
+ (define-key keymap [return] 'company-complete-selection)
+ (define-key keymap [tab] 'company-complete-common)
(define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
(define-key keymap "\C-w" 'company-show-location)
(define-key keymap "\C-s" 'company-search-candidates)
(unless (memq backend company--disabled-backends)
(message "Company back-end '%s' could not be initialized:\n%s"
backend (error-message-string err)))
- (push backend company--disabled-backends)
+ (pushnew backend company--disabled-backends)
nil))
(mapc 'company-init-backend backend)))
;;;###autoload
(define-minor-mode company-mode
- "\"complete anything\"; in in-buffer completion framework.
+ "\"complete anything\"; is an in-buffer completion framework.
Completion starts automatically, depending on the values
`company-idle-delay' and `company-minimum-prefix-length'.
(kill-local-variable 'company-point)))
(define-globalized-minor-mode global-company-mode company-mode
- (lambda () (company-mode 1)))
+ (lambda () (unless (or noninteractive (eq (aref (buffer-name) 0) ?\s))
+ (company-mode 1))))
(defsubst company-assert-enabled ()
(unless company-mode
;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar company-overriding-keymap-bound nil)
-(make-variable-buffer-local 'company-overriding-keymap-bound)
-
-(defvar company-old-keymap nil)
-(make-variable-buffer-local 'company-old-keymap)
-
(defvar company-my-keymap nil)
(make-variable-buffer-local 'company-my-keymap)
+(defvar company-emulation-alist '((t . nil)))
+
(defsubst company-enable-overriding-keymap (keymap)
- (setq company-my-keymap keymap)
- (when company-overriding-keymap-bound
- (company-uninstall-map)))
+ (company-uninstall-map)
+ (setq company-my-keymap keymap))
+
+(defun company-ensure-emulation-alist ()
+ (unless (eq 'company-emulation-alist (car emulation-mode-map-alists))
+ (setq emulation-mode-map-alists
+ (cons 'company-emulation-alist
+ (delq 'company-emulation-alist emulation-mode-map-alists)))))
(defun company-install-map ()
- (unless (or company-overriding-keymap-bound
+ (unless (or (cdar company-emulation-alist)
(null company-my-keymap))
- (setq company-old-keymap overriding-terminal-local-map
- overriding-terminal-local-map company-my-keymap
- company-overriding-keymap-bound t)))
+ (setf (cdar company-emulation-alist) company-my-keymap)))
(defun company-uninstall-map ()
- (when (eq overriding-terminal-local-map company-my-keymap)
- (setq overriding-terminal-local-map company-old-keymap
- company-overriding-keymap-bound nil)))
+ (setf (cdar company-emulation-alist) nil))
;; Hack:
;; Emacs calculates the active keymaps before reading the event. That means we
(apply 'company--multi-backend-adapter company-backend args)))
(defun company--multi-backend-adapter (backends command &rest args)
- (case command
- (candidates
- (apply 'append (mapcar (lambda (backend) (apply backend command args))
- backends)))
- (sorted nil)
- (duplicates t)
- (otherwise
- (let (value)
- (dolist (backend backends)
- (when (setq value (apply backend command args))
- (return value)))))))
+ (let ((backends (remove-if (lambda (b) (eq 'failed (get b 'company-init)))
+ backends)))
+ (case command
+ (candidates
+ (loop for backend in backends
+ when (equal (funcall backend 'prefix)
+ (car args))
+ nconc (apply backend 'candidates args)))
+ (sorted nil)
+ (duplicates t)
+ (otherwise
+ (let (value)
+ (dolist (backend backends)
+ (when (setq value (apply backend command args))
+ (return value))))))))
;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun company--should-complete ()
(and (not (or buffer-read-only overriding-terminal-local-map
- overriding-local-map))
+ overriding-local-map
+ (minibufferp)))
;; Check if in the middle of entering a key combination.
(or (equal (this-command-keys-vector) [])
(not (keymapp (key-binding (this-command-keys-vector)))))
(setq company-candidates nil)))
(defun company-calculate-candidates (prefix)
- (let ((candidates (cdr (assoc prefix company-candidates-cache))))
+ (let ((candidates (cdr (assoc prefix company-candidates-cache)))
+ (ignore-case (company-call-backend 'ignore-case)))
(or candidates
(when company-candidates-cache
(let ((len (length prefix))
- (completion-ignore-case (company-call-backend 'ignore-case))
+ (completion-ignore-case ignore-case)
prev)
(dotimes (i (1+ len))
(when (setq prev (cdr (assoc (substring prefix 0 (- len i))
(while c2
(setcdr c2 (progn (while (equal (pop c2) (car c2)))
c2)))))))
- (if (or (cdr candidates)
- (not (equal (car candidates) prefix)))
+ (if (and candidates
+ (or (cdr candidates)
+ (not (eq t (compare-strings (car candidates) nil nil
+ prefix nil nil ignore-case)))))
;; Don't start when already completed and unique.
candidates
;; Not the right place? maybe when setting?
(return c)))))
(defun company-begin ()
- (setq company-candidates
- (or (and company-candidates (company--continue))
- (and (company--should-complete) (company--begin-new))))
+ (or (and company-candidates (company--continue))
+ (and (company--should-complete) (company--begin-new)))
(when company-candidates
(when (and company-end-of-buffer-workaround (eobp))
(save-excursion (insert "\n"))
(setq company-added-newline (buffer-chars-modified-tick)))
(setq company-point (point)
company--point-max (point-max))
+ (company-ensure-emulation-alist)
(company-enable-overriding-keymap company-active-map)
(company-call-frontends 'update)))
(make-string len ?\ )))
(defsubst company-safe-substring (str from &optional to)
- (let ((len (length str)))
- (if (> from len)
- ""
- (if (and to (> to len))
- (concat (substring str from)
- (company-space-string (- to len)))
- (substring str from to)))))
+ (if (> from (string-width str))
+ ""
+ (with-temp-buffer
+ (insert str)
+ (move-to-column from)
+ (let ((beg (point)))
+ (if to
+ (progn
+ (move-to-column to)
+ (concat (buffer-substring beg (point))
+ (let ((padding (- to (current-column))))
+ (when (> padding 0)
+ (company-space-string padding)))))
+ (buffer-substring beg (point-max)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun company-buffer-lines (beg end)
(goto-char beg)
- (let ((row (company--row))
- lines)
- (while (and (equal (move-to-window-line (incf row)) row)
+ (let (lines)
+ (while (and (= 1 (vertical-motion 1))
(<= (point) end))
(push (buffer-substring beg (min end (1- (point)))) lines)
(setq beg (point)))
;; Append whole new lines.
(while lines
(push (concat (company-space-string column) (pop lines)) new))
- (concat (when nl "\n")
- (mapconcat 'identity (nreverse new) "\n")
- "\n")))
+
+ (let ((str (concat (when nl "\n")
+ (mapconcat 'identity (nreverse new) "\n")
+ "\n")))
+ (font-lock-append-text-property 0 (length str) 'face 'default str)
+ str)))
(defun company--create-lines (selection limit)
(defsubst company--pseudo-tooltip-height ()
"Calculate the appropriate tooltip height.
Returns a negative number if the tooltip should be displayed above point."
- (let* ((lines (count-lines (window-start) (point-at-bol)))
+ (let* ((lines (company--row))
(below (- (company--window-inner-height) 1 lines)))
(if (and (< below (min company-tooltip-minimum company-candidates-length))
(> lines below))
(length company-prefix)))))
(company-pseudo-tooltip-unhide))
(hide (company-pseudo-tooltip-hide)
- (setq company-tooltip-offset 0))
+ (setq company-tooltip-offset 0))
(update (when (overlayp company-pseudo-tooltip-overlay)
- (company-pseudo-tooltip-edit company-candidates
- company-selection)))))
+ (company-pseudo-tooltip-edit company-candidates
+ company-selection)))))
(defun company-pseudo-tooltip-unless-just-one-frontend (command)
"`company-pseudo-tooltip-frontend', but not shown for single candidates."
(defsubst company-echo-show-soon (&optional getter)
(when company-echo-timer
(cancel-timer company-echo-timer))
- (setq company-echo-timer (run-with-timer company-echo-delay nil
- 'company-echo-show getter)))
+ (setq company-echo-timer (run-with-timer 0 nil 'company-echo-show getter)))
+
+(defsubst company-echo-show-when-idle (&optional getter)
+ (when (sit-for .01)
+ (company-echo-show getter)))
+
+(defsubst company-echo-show-when-not-busy (&optional getter)
+ "Run `company-echo-show' with arg GETTER once Emacs isn't busy."
+ (when (sit-for company-echo-delay)
+ (company-echo-show getter)))
(defun company-echo-format ()
"}")))
(defun company-echo-hide ()
- (when company-echo-timer
- (cancel-timer company-echo-timer))
(unless (equal company-echo-last-msg "")
(setq company-echo-last-msg "")
(company-echo-show)))
(defun company-echo-frontend (command)
"A `company-mode' front-end showing the candidates in the echo area."
(case command
- (pre-command (company-echo-show-soon))
(post-command (company-echo-show-soon 'company-echo-format))
(hide (company-echo-hide))))
(defun company-echo-strip-common-frontend (command)
"A `company-mode' front-end showing the candidates in the echo area."
(case command
- (pre-command (company-echo-show-soon))
(post-command (company-echo-show-soon 'company-echo-strip-common-format))
(hide (company-echo-hide))))
(defun company-echo-metadata-frontend (command)
"A `company-mode' front-end showing the documentation in the echo area."
(case command
- (pre-command (company-echo-show-soon))
- (post-command (company-echo-show-soon 'company-fetch-metadata))
+ (post-command (company-echo-show-when-idle 'company-fetch-metadata))
(hide (company-echo-hide))))
;; templates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;