(or emacs irrelevant)

Using digits to select company-mode candidates

I'd like to share a customization of company-mode that I've been using for a while. I refined it just recently, I'll explain below how.

Basic setting

(setq company-show-numbers t)

Now, numbers are shown next to the candidates, although they don't do anything yet:


Add some bindings

(let ((map company-active-map))
   (lambda (x)
     (define-key map (format "%d" x) 'ora-company-number))
   (number-sequence 0 9))
  (define-key map " " (lambda ()
                        (self-insert-command 1)))
  (define-key map (kbd "<return>") nil))

Besides binding 0..9 to complete their corresponding candidate, it also un-binds RET and binds SPC to close the company popup.

Actual code

(defun ora-company-number ()
  "Forward to `company-complete-number'.

Unless the number is potentially part of the candidate.
In that case, insert the number."
  (let* ((k (this-command-keys))
         (re (concat "^" company-prefix k)))
    (if (cl-find-if (lambda (s) (string-match re s))
        (self-insert-command 1)
      (company-complete-number (string-to-number k)))))

Initially, I would just bind company-complete-number. The problem with that was that if my candidate list was ("var0" "var1" "var2"), then entering 1 means:

  • select the first candidate (i.e. "var0"), instead of:
  • insert "1", resulting in "var1", i.e. the second candidate.

My customization will now check company-candidates—the list of possible completions—for the above mentioned conflict. And if it's detected, the key pressed will be inserted instead of being used to select a candidate.


Looking at git-log, I've been using company-complete-number for at least 3 years now. It's quite useful, and now also more seamless, since I don't have to type e.g. C-q 2 any more. In any case, thanks to the author and the contributors of company-mode. Merry Christmas and happy hacking in the New Year!