branch: elpa/flx commit 12589211c6d9e1d9dd628f09719d51f6b8257a8e Author: Le Wang <le.w...@agworld.com.au> Commit: Le Wang <le.w...@agworld.com.au>
Implement case-fold searching - #52 --- flx.el | 15 ++++++++++----- tests/flx-test.el | 29 +++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/flx.el b/flx.el index b3a2f5cc3f..81c3e88855 100644 --- a/flx.el +++ b/flx.el @@ -6,7 +6,7 @@ ;; Maintainer: Le Wang ;; Description: fuzzy matching with good sorting ;; Created: Wed Apr 17 01:01:41 2013 (+0800) -;; Version: 0.1 +;; Version: 0.3 ;; Package-Requires: ((cl-lib "0.3")) ;; URL: https://github.com/lewang/flx @@ -62,11 +62,17 @@ is a sorted list of indexes for character occurrences." (let* ((res (make-hash-table :test 'eq :size 32)) (str-len (length str)) - char) + down-char) (cl-loop for index from (1- str-len) downto 0 + for char = (aref str index) do (progn - (setq char (downcase (aref str index))) - (push index (gethash char res)))) + ;; simulate `case-fold-search' + (if (flx-capital-p char) + (progn + (push index (gethash char res)) + (setq down-char (downcase char))) + (setq down-char char)) + (push index (gethash down-char res)))) (puthash 'heatmap (funcall heatmap-func str) res) res)) @@ -271,7 +277,6 @@ e.g. (\"aab\" \"ab\") returns (defun flx-score (str query &optional cache) "return best score matching QUERY against STR" - (setq query (downcase query)) (unless (or (zerop (length query)) (zerop (length str))) (let* ((info-hash (flx-process-cache str cache)) diff --git a/tests/flx-test.el b/tests/flx-test.el index 880d6b6e9c..635e1beeb4 100644 --- a/tests/flx-test.el +++ b/tests/flx-test.el @@ -41,14 +41,18 @@ (should (= 1 1))) (ert-deftest flx-get-hash-for-string () - (let ((h (flx-get-hash-for-string "aab" 'flx-get-heatmap-str)) - (count 0)) + (let ((h (flx-get-hash-for-string "aab" 'flx-get-heatmap-str))) (should (equal '(0 1) (gethash ?a h) )) (should (equal '(2) (gethash ?b h))) - (maphash (lambda (k v) - (incf count)) - h) - (should (= 3 count)))) + (should (= 3 (hash-table-count h))))) + +(ert-deftest flx-get-hash-mixed-case () + (let ((h (flx-get-hash-for-string "aAb" 'flx-get-heatmap-str))) + (should (equal '(0 1) (gethash ?a h) )) + (should (equal '(1) (gethash ?A h) )) + (should (equal '(2) (gethash ?b h))) + ;; upper case appears twice + (should (= 4 (hash-table-count h))))) (ert-deftest flx-boundary-p () (should (flx-boundary-p ?/ ?a)) @@ -140,8 +144,8 @@ (ert-deftest flx-score-capital () - "QUERY should be downcased." - (should (flx-score "abc" "A" (flx-make-filename-cache)))) + "QUERY should not be downcased." + (should-not (flx-score "abc" "A" (flx-make-filename-cache)))) (ert-deftest flx-score-string () "score as string" @@ -349,6 +353,15 @@ substring can overpower abbreviation." (lower (flx-score "sane-defaults.el" query (flx-make-filename-cache)))) (should (> (car higher) (car lower))))) +(ert-deftest flx-case-fold () + "Lower case can match lower or upper case, but upper case can only match upper case." + (let* ((query "def") + (lower-folds (flx-score "Defuns/" query (flx-make-filename-cache)))) + (should lower-folds)) + (let* ((query "Def") + (upper-no-folds (flx-score "defuns/" query (flx-make-filename-cache)))) + (should (not upper-no-folds)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;