branch: master commit 75e9490fec6f3400bcdfb83d4e76afe7a874be16 Author: Ian Dunn <du...@gnu.org> Commit: Ian Dunn <du...@gnu.org>
Account for case handling in completion * paced.el (paced-dictionary-fix-completion-case): New defmethod. (paced-completion-finish): Removed. (paced-dictionary-completions): Get completions for the given action. (paced-completion-table-function): Use it. * paced-tests.el: Added new tests for each completion type. --- paced-tests.el | 45 ++++++++++++++++++++++++++++++++++++++ paced.el | 69 ++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/paced-tests.el b/paced-tests.el index b4a2c41..96fb32f 100644 --- a/paced-tests.el +++ b/paced-tests.el @@ -370,6 +370,51 @@ (let ((usage-hash (oref test-dict usage-hash))) (should (map-empty-p usage-hash))))) +(ert-deftest paced-completions-try-completion () + (let* ((paced--registered-dictionaries paced-test-default-registered-map) + (paced-global-dict-enable-alist '((text-mode . "test-dict-case"))) + (cmd (paced-file-population-command :file paced-first-test-file)) + test-dict) + (paced-load-dictionary-from-file paced-test-dict-save-file) + (setq test-dict (paced-named-dictionary "test-dict-case")) + (should (paced-dictionary-p test-dict)) + (oset test-dict population-commands (list cmd)) + (paced-dictionary-repopulate test-dict) + (let ((completions (paced-dictionary-completions test-dict "o" nil))) + (should (equal completions '("o")))))) + +(ert-deftest paced-completions-all-completions () + (let* ((paced--registered-dictionaries paced-test-default-registered-map) + (paced-global-dict-enable-alist '((text-mode . "test-dict-case"))) + (cmd (paced-file-population-command :file paced-first-test-file)) + test-dict) + (paced-load-dictionary-from-file paced-test-dict-save-file) + (setq test-dict (paced-named-dictionary "test-dict-case")) + (should (paced-dictionary-p test-dict)) + (oset test-dict population-commands (list cmd)) + (paced-dictionary-repopulate test-dict) + (should (equal (paced-dictionary-completions test-dict "o" t) + '("one"))) + (should (equal (paced-dictionary-completions test-dict "on" t) + '("one"))) + (should (equal (paced-dictionary-completions test-dict "t" t) + '("three" "two"))) + (should (equal (paced-dictionary-completions test-dict "v" t) + nil)))) + +(ert-deftest paced-completions-test-completion () + (let* ((paced--registered-dictionaries paced-test-default-registered-map) + (paced-global-dict-enable-alist '((text-mode . "test-dict-case"))) + (cmd (paced-file-population-command :file paced-first-test-file)) + test-dict) + (paced-load-dictionary-from-file paced-test-dict-save-file) + (setq test-dict (paced-named-dictionary "test-dict-case")) + (should (paced-dictionary-p test-dict)) + (oset test-dict population-commands (list cmd)) + (paced-dictionary-repopulate test-dict) + (should (paced-dictionary-completions test-dict "one" 'lambda)) + (should-not (paced-dictionary-completions test-dict "o" 'lambda)))) + (provide 'paced-tests) ;;; paced-tests.el ends here diff --git a/paced.el b/paced.el index 6a85734..7956bcd 100644 --- a/paced.el +++ b/paced.el @@ -638,35 +638,58 @@ This adds `paced-completion-at-point' to ; ;; Completion ;; ; ; ;;;;;;;;;;;;;;;; ; -(defun paced-completion-finish (prefix completions) - "Account for case differences in the prefix by prepending PREFIX to COMPLETIONS." - (cond - ((not (listp completions)) - ;; If completions is not a list, it's likely 't', in which - ;; case just return the original prefix. - (list prefix)) - (t - (let ((prefix-length (length prefix))) - (mapcar - (lambda (completion) - (when (stringp completion) - (concat prefix (substring-no-properties completion prefix-length)))) - completions))))) +(cl-defmethod paced-dictionary-fix-completion-case ((dict paced-dictionary) prefix completions) + "Account for case differences in the prefix by prepending PREFIX to COMPLETIONS. + +The specific case differences should mirror those handled by +case-handling in `paced-dictionary-process-word'." + ;; Anything we changed during population, we want to maintain that part of the + ;; prefix during completion. + (if (not (listp completions)) + ;; If completions is not a list, it's likely 't', in which + ;; case just return the original prefix. + (list prefix) + (pcase (oref dict case-handling) + (`preserve completions) + ((or `downcase `upcase) + ;; Changed entire word, so maintain entire prefix + (let ((prefix-length (length prefix))) + (mapcar + (lambda (completion) + (when (stringp completion) + (concat prefix (substring-no-properties completion prefix-length)))) + completions))) + ((or `downcase-first `upcase-first) + ;; Only changed the first letter, so maintain just one letter of the + ;; original prefix + (let ((prefix-length 1)) + (mapcar + (lambda (completion) + (when (stringp completion) + (concat (substring prefix 0 prefix-length) + (substring-no-properties completion prefix-length)))) + completions)))))) + +(cl-defmethod paced-dictionary-completions ((dict paced-dictionary) prefix action &optional pred) + (let* ((completion-ignore-case paced-completion-ignore-case) + (usage-hash (oref dict usage-hash)) + completions) + (pcase action + (`nil + (setq completions (try-completion prefix usage-hash pred))) + (`t + (setq completions (all-completions prefix usage-hash pred))) + (`lambda + (setq completions (test-completion prefix usage-hash pred)))) + (paced-dictionary-fix-completion-case dict prefix completions))) (defun paced-completion-table-function (string pred action) "Completion table function for paced dictionaries." (if-let* ((dict (paced-current-dictionary))) (let* ((completion-ignore-case paced-completion-ignore-case)) (pcase action - (`nil - (paced-completion-finish string - (try-completion string (oref dict usage-hash) pred))) - (`t - (paced-completion-finish string - (all-completions string (oref dict usage-hash) pred))) - (`lambda - (paced-completion-finish string - (test-completion string (oref dict usage-hash) pred))) + ((or `nil `t `lambda) + (paced-dictionary-completions dict string action pred)) (`(boundaries . _) nil) (`metadata `(metadata . ((category . paced)