## Next
+* New user option `company-continue-commands`.
* New back-end command, `annotation`, for text displayed inline in the popup
that's not a part of completion candidate.
* `company-capf`, `company-clang` and `company-eclim` use `annotation`.
(should (eq nil company-candidates-length))
(should (eq 4 (point))))))
+(ert-deftest company-should-complete-whitelist ()
+ (with-temp-buffer
+ (insert "ab")
+ (company-mode)
+ (let (company-frontends
+ company-begin-commands
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("abc" "abd")))))))
+ (let ((company-continue-commands nil))
+ (let (this-command)
+ (company-complete))
+ (company-call 'backward-delete-char 1)
+ (should (null company-candidates-length)))
+ (let ((company-continue-commands '(backward-delete-char)))
+ (let (this-command)
+ (company-complete))
+ (company-call 'backward-delete-char 1)
+ (should (eq 2 company-candidates-length))))))
+
+(ert-deftest company-should-complete-blacklist ()
+ (with-temp-buffer
+ (insert "ab")
+ (company-mode)
+ (let (company-frontends
+ company-begin-commands
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("abc" "abd")))))))
+ (let ((company-continue-commands '(not backward-delete-char)))
+ (let (this-command)
+ (company-complete))
+ (company-call 'backward-delete-char 1)
+ (should (null company-candidates-length)))
+ (let ((company-continue-commands '(not backward-delete-char-untabify)))
+ (let (this-command)
+ (company-complete))
+ (company-call 'backward-delete-char 1)
+ (should (eq 2 company-candidates-length))))))
+
(ert-deftest company-auto-complete-explicit ()
(with-temp-buffer
(insert "ab")
(defun company-call (name &rest args)
(let* ((maybe (intern (format "company-%s" name)))
(command (if (fboundp maybe) maybe name)))
+ (let ((this-command command))
+ (run-hooks 'pre-command-hook))
(apply command args)
(let ((this-command command))
(run-hooks 'post-command-hook))))
(const :tag "Self insert command" '(self-insert-command))
(repeat :tag "Commands" function)))
+(defcustom company-continue-commands t
+ "A list of commands that are allowed during completion.
+If this is t, or if `company-begin-commands' is t, any command is allowed.
+Otherwise, the value must be a list of symbols. If it starts with `not',
+the cdr is the list of commands that abort completion. Otherwise, all
+commands except those in that list, or in `company-begin-commands', or
+commands in the `company-' namespace, abort completion."
+ :type '(choice (const :tag "Any command" t)
+ (repeat :tag "Commands" function)))
+
(defcustom company-show-numbers nil
"If enabled, show quick-access numbers for the first ten candidates."
:type '(choice (const :tag "off" nil)
(and (symbolp this-command) (get this-command 'company-begin)))
(not (and transient-mark-mode mark-active))))
+(defun company--should-continue ()
+ (or (eq t company-begin-commands)
+ (eq t company-continue-commands)
+ (if (eq 'not (car company-continue-commands))
+ (not (memq this-command (cdr company-continue-commands)))
+ (or (memq this-command company-begin-commands)
+ (memq this-command company-continue-commands)
+ (string-match-p "\\`company-" (symbol-name this-command))))))
+
(defun company-call-frontends (command)
(dolist (frontend company-frontends)
(condition-case err
(unless (company-keep this-command)
(condition-case err
(when company-candidates
- (company-call-frontends 'pre-command))
+ (company-call-frontends 'pre-command)
+ (unless (company--should-continue)
+ (company-abort)))
(error (message "Company: An error occurred in pre-command")
(message "%s" (error-message-string err))
(company-cancel))))