I've managed to setup company-ispell which seems to work for small files, but fails for a dump of the aspell dictionary.

This works when pressing C-SPC without any existing text before the cursor.

But when there is some text e.g. wheel, there is no completion found.

However when there is no prefix, there are multiple words starting with wheel in the list.

(use-package company
  :commands (company-complete-common))

(global-set-key (kbd "C-SPC") 'company-complete-common)

(add-hook 'after-change-major-mode-hook
  (lambda ()
    (when (derived-mode-p 'text-mode)


      (make-local-variable 'company-backends)

      ;; company-ispell is the plugin to complete words
      (setq company-backends (list 'company-ispell))

      (setq ispell-complete-word-dict
        (expand-file-name (concat user-emacs-directory "aspell_words.txt")))

      (when (and ispell-complete-word-dict (not (file-exists-p ispell-complete-word-dict)))
        (shell-command (concat "aspell -d en_US dump master > " ispell-complete-word-dict))))))

In the *Message* buffer, there is output.

Starting "look" process...
No completion found

Checking the process monitor, there aren't any hanging background processes.

How can company-mode's company-complete-common be used to complete dictionary words?

1 Answer 1


It turns out the word list needs to be sorted (case insensitive), at least sorting it makes it work for me.

Assuming you use company mode and have a shortcut to activate it.

(use-package company
  :commands (company-complete-common))

(global-set-key (kbd "C-SPC") 'company-complete-common)
;; Dictionary for completion.
(setq ispell-complete-word-dict
  (expand-file-name (concat user-emacs-directory "aspell_words.txt")))

(defun my-generic-ispell-company-complete-setup ()
  ;; Only apply this locally.
  (make-local-variable 'company-backends)
  (setq company-backends (list 'company-ispell))

  (when ispell-complete-word-dict
          (and ispell-complete-word-dict (file-exists-p ispell-complete-word-dict)))
          (and ispell-personal-dictionary (file-exists-p ispell-personal-dictionary)))
            has-dict-complete has-dict-personal
              (nth 5 (file-attributes ispell-complete-word-dict))
              (nth 5 (file-attributes ispell-personal-dictionary))))))

      (when (or (not has-dict-complete) is-dict-outdated)

          ;; Optional: insert personal dictionary, stripping header and inserting a newline.
          (when has-dict-personal
            (insert-file-contents ispell-personal-dictionary)
            (goto-char (point-min))
            (when (looking-at "personal_ws\-")
              (delete-region (line-beginning-position) (1+ (line-end-position))))
            (goto-char (point-max))
            (unless (eq ?\n (char-after))
              (insert "\n")))

          (call-process "aspell" nil t nil "-d" "en_US" "dump" "master")
          ;; Case insensitive sort is important for the lookup.
          (let ((sort-fold-case t))
            (sort-lines nil (point-min) (point-max)))
          (write-region nil nil ispell-complete-word-dict))))))

;; Enable this in appropriate modes.

(add-hook 'org-mode-hook (lambda () (my-generic-ispell-company-complete-setup)))
(add-hook 'rst-mode-hook (lambda () (my-generic-ispell-company-complete-setup)))
(add-hook 'markdown-mode-hook (lambda () (my-generic-ispell-company-complete-setup)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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