Here's what I would do, using the 466544-strong words.txt
file from english-words as an example:
(defun my-dictionary ()
"Return hash-table whose keys comprise words.txt."
(with-temp-buffer
(insert-file-contents "/path/to/english-words/words.txt")
(let ((table (make-hash-table :test #'equal :size 466544)))
(while (not (eobp))
(puthash (buffer-substring (point) (line-end-position)) nil table)
(forward-line))
table)))
(defvar my-dictionary
(lazy-completion-table my-dictionary my-dictionary)
"Lazy completion table for function `my-dictionary'.")
The basic idea is that you read and cache the contents of your dictionary file into a data structure (a hash-table in my example) which standard completion functions such as completing-read
and completion-in-region
can understand. The benefit of this is that you can pick and choose between minibuffer and in-buffer completion, as well as from many conforming completion frameworks, using the same completion collection. See (elisp) Completion
for more information on this.
After that, you can pass the lazy (cached) collection to whichever conforming completion frontend tickles your fancy. With ivy-mode
enabled, for example, a call to
(completion-in-region START END my-dictionary)
for some buffer positions START
and END
will perform an in-place in-buffer completion like the one you describe.
Here is a more concrete example which completes in-buffer the word preceding point:
(defun my-complete-word-in-region ()
"Complete word preceding point under `my-dictionary'."
(interactive)
(completion-in-region
(save-excursion
(skip-syntax-backward "w")
(point))
(point)
my-dictionary))
You could then bind this to some convenient key.
If the dictionary file you want to read in does not change very often, you can speed up the initial hash-table-creation latency of the function my-dictionary
by creating the hash-table and writing its printed representation to some auxiliary file ahead of time, and then reading that auxiliary file as Lisp instead, though it may not be worth the effort, given a subsequent caching of the hash-table in memory and the inherent latency of fuzzy completion.
See also issue #1174 for some ivy
-specific performance tips.