1

I would like to have natural language completion (company-ispell for e.g.) but only when editing comments.

How should the company back-end be swapped out when editing commensts?

1

Insert below code into ~/.emacs to enable company-ispell in comment,

(defun my-in-comment-p (pos)
  "Check whether the code at POS is comment by comparing font face."
  (let* ((fontfaces (get-text-property pos 'face)))
    (if (not (listp fontfaces))
        (setq fontfaces (list fontfaces)))
    (delq nil
          (mapcar #'(lambda (f)
                      ;; learn this trick from flyspell
                      (or (eq f 'font-lock-comment-face)
                          (eq f 'font-lock-comment-delimiter-face)))
                  fontfaces))))

(eval-after-load 'company-ispell
  '(progn
     ;; use company-ispell in comment when coding
     (defadvice company-ispell-available (around company-ispell-available-hack activate)
       (cond
        ((and (derived-mode-p 'prog-mode)
              (or (not (company-in-string-or-comment)) ; respect advice in `company-in-string-or-comment'
                  (not (my-in-comment-p (point))))) ; auto-complete in comment only
         (setq ad-return-value nil))
        (t
         ad-do-it)))))
  • Notes: seems setf could be setq? Also let* can be let. Added alternate answer. – ideasman42 Jan 9 '20 at 1:02
  • setf is still syntax correct though I admit it's kind of over-engineering in this case. let* is more powerful then let when multiple variable are initialized and there is dependency of initialization among the variables. – chen bin Jan 9 '20 at 2:22
  • The function (face-at-point nil t) looks like it can replace the font accessing logic here. – ideasman42 Jan 9 '20 at 8:48
1

This is a modified version of @chen-bin's answer which uses a wrapper function instead of using advice (avoids interfering with other uses). It also generalizes the syntax checking to allow checking for other kinds of syntax.

(defun company-complete-common-use-context ()
  (interactive)
  (let ((faces-found (face-at-point nil t))
        (faces-comment-list
         '(font-lock-comment-face
           font-lock-comment-delimiter-face
           font-lock-doc-face)))
    (cond
     ((seq-intersection faces-found faces-comment-list)
      (let ((company-backends (list 'company-ispell)))
        (company-complete-common)))
     (t
      (company-complete-common)))))

Then bind the key to company-complete-common-use-context.

  • This solution works for me if I am using something like <M-tab>, but is there any way of making it also work for completion on any key stroke? – Matías Guzmán Naranjo Sep 20 '20 at 11:47
  • The other answer here (chen bin's) uses advice which should work automatically without having to bind a key to a spesific function. – ideasman42 Sep 21 '20 at 2:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.