Using digits to select company-mode candidates
27 Dec 2017I'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))
(mapc
(lambda (x)
(define-key map (format "%d" x) 'ora-company-number))
(number-sequence 0 9))
(define-key map " " (lambda ()
(interactive)
(company-abort)
(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."
(interactive)
(let* ((k (this-command-keys))
(re (concat "^" company-prefix k)))
(if (cl-find-if (lambda (s) (string-match re s))
company-candidates)
(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.
Outro
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!