summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2025-03-08 12:58:29 +0100
committerDaniel Mendler <mail@daniel-mendler.de>2025-03-08 13:13:35 +0100
commitcc9cf45c651ad4784444cfdbdf238ac18dce39c9 (patch)
treedb8648eedc7ce15462f0d28e5e75a4684e5fbb98
parentc854d98373fb6eec3e1ed5a2611c0089aa565e1b (diff)
Add cape-dict-grep customization option (Fix #147)
-rw-r--r--CHANGELOG.org4
-rw-r--r--cape.el51
2 files changed, 42 insertions, 13 deletions
diff --git a/CHANGELOG.org b/CHANGELOG.org
index 79a0cbd..38700e3 100644
--- a/CHANGELOG.org
+++ b/CHANGELOG.org
@@ -4,8 +4,10 @@
* Development
+- ~cape-dict~: Add new customization variable ~cape-dict-grep~. Set to ~nil~ to filter
+ the dictionary in Lisp.
- ~cape-file~: Improve handling of environment variables as part of the path,
- e.g., $HOME.
+ e.g., ~$HOME~.
- ~cape-company-to-capf~: Handle updated return value convention of the ~prefix~
action of Company backends.
diff --git a/cape.el b/cape.el
index 1142e72..38de07a 100644
--- a/cape.el
+++ b/cape.el
@@ -67,6 +67,11 @@
"Maximal number of completion candidates returned by `cape-dict'."
:type '(choice (const nil) natnum))
+(defcustom cape-dict-grep t
+ "Filter the dictionary via grep instead of in Lisp.
+It may be beneficial to disable this setting depending on your system."
+ :type 'boolean)
+
(defcustom cape-dict-file "/usr/share/dict/words"
"Path to dictionary word list file.
This variable can also be a list of paths or
@@ -617,6 +622,8 @@ See the user options `cape-dabbrev-min-length' and
:category 'cape-dict)
"Completion extra properties for `cape-dict'.")
+(defvar cape--dict-cache nil)
+
(defun cape--dict-list (input)
"Return all words from `cape-dict-file' matching INPUT."
(let* ((inhibit-message t)
@@ -626,18 +633,38 @@ See the user options `cape-dabbrev-min-length' and
(file-directory-p default-directory))
default-directory
user-emacs-directory))
- (files (mapcar #'expand-file-name
- (ensure-list
- (if (functionp cape-dict-file)
- (funcall cape-dict-file)
- cape-dict-file))))
- (words
- (apply #'process-lines-ignore-status
- "grep"
- (concat "-Fh"
- (and (cape--case-fold-p cape-dict-case-fold) "i")
- (and cape-dict-limit (format "m%d" cape-dict-limit)))
- input files)))
+ (files (sort (mapcar #'expand-file-name
+ (ensure-list
+ (if (functionp cape-dict-file)
+ (funcall cape-dict-file)
+ cape-dict-file)))
+ #'string<))
+ (words nil))
+ (if cape-dict-grep
+ (setq words (apply #'process-lines-ignore-status
+ "grep"
+ (concat "-Fh"
+ (and (cape--case-fold-p cape-dict-case-fold) "i")
+ (and cape-dict-limit (format "m%d" cape-dict-limit)))
+ input files))
+ (let ((completion-ignore-case (cape--case-fold-p cape-dict-case-fold))
+ (completion-regexp-list (list (regexp-quote input)))
+ (count 0))
+ (catch 'limit
+ (all-completions
+ ""
+ (with-memoization (alist-get files cape--dict-cache nil nil #'equal)
+ (with-temp-buffer
+ (dolist (file files)
+ (insert-file-contents file)
+ (insert "\n"))
+ (split-string (buffer-string) "[\r\n]+" t)))
+ (lambda (word)
+ (when cape-dict-limit
+ (when (>= count cape-dict-limit) (throw 'limit nil))
+ (cl-incf count))
+ (push word words)
+ nil)))))
(cons
(apply-partially
(if (and cape-dict-limit (length= words cape-dict-limit))