Commit 35c7dc06 authored by Artur Malabarba's avatar Artur Malabarba

* lisp/character-fold.el: Code simplifications

(character-fold-table): Reduce the scope of a variable.
(character-fold-to-regexp): Change logic to work directly on the
input string.  It's a little easier to understand, probably
faster, and sets us up for implementing multi-char matches.

* test/automated/character-fold-tests.el
(character-fold--test-fold-to-regexp): New test.
parent ea087151
......@@ -25,13 +25,14 @@
(defconst character-fold-table
(let* ((equiv (make-char-table 'character-fold-table))
(table (unicode-property-table-internal 'decomposition))
(func (char-table-extra-slot table 1)))
(let ((equiv (make-char-table 'character-fold-table))
(table (unicode-property-table-internal 'decomposition)))
;; Ensure the table is populated.
(lambda (char v) (when (consp char) (funcall func (car char) v table)))
(let ((func (char-table-extra-slot table 1)))
(map-char-table (lambda (char v)
(when (consp char)
(funcall func (car char) v table)))
;; Compile a list of all complex characters that each simple
;; character should match.
......@@ -126,9 +127,10 @@
Any character in STRING that has an entry in
`character-fold-table' is replaced with that entry (which is a
regexp) and other characters are `regexp-quote'd."
(let* ((spaces 0)
(chars (mapcar #'identity string))
(out chars))
(let ((spaces 0)
(i 0)
(end (length string))
(out nil))
;; When the user types a space, we want to match the table entry
;; for ?\s, which is generally a regexp like "[ ...]". However,
;; the `search-spaces-regexp' variable doesn't "see" spaces inside
......@@ -137,24 +139,19 @@ regexp) and other characters are `regexp-quote'd."
;; search engine acts on a bunch of spaces, not on individual
;; spaces, so if the string contains sequential spaces like " ", we
;; need to keep them grouped together like this: "\\( \\|[ ...][ ...]\\)".
(while chars
(let ((c (car chars)))
(setcar chars
((eq c ?\s)
(setq spaces (1+ spaces))
((> spaces 0)
(prog1 (concat (character-fold--make-space-string spaces)
(or (aref character-fold-table c)
(regexp-quote (string c))))
(setq spaces 0)))
(t (or (aref character-fold-table c)
(regexp-quote (string c))))))
(setq chars (cdr chars))))
(concat (apply #'concat out)
(when (> spaces 0)
(character-fold--make-space-string spaces)))))
(while (< i end)
(pcase (aref string i)
(`?\s (setq spaces (1+ spaces)))
(c (when (> spaces 0)
(push (character-fold--make-space-string spaces) out)
(setq spaces 0))
(push (or (aref character-fold-table c)
(regexp-quote (string c)))
(setq i (1+ i)))
(when (> spaces 0)
(push (character-fold--make-space-string spaces) out))
(apply #'concat (nreverse out))))
;;; Commands provided for completeness.
......@@ -54,5 +54,15 @@
(concat w1 "\s\n\s\t\f\t\n\r\t" w2)
(concat w1 (make-string 90 ?\s) w2)))))
(ert-deftest character-fold--test-fold-to-regexp ()
(let ((character-fold-table (make-char-table 'character-fold-table)))
(aset character-fold-table ?a "abc")
(aset character-fold-table ?1 "123")
(aset character-fold-table ?\s "-!-")
(should (equal (character-fold-to-regexp "a1a1")
(should (equal (character-fold-to-regexp "a1 a 1")
"abc123\\(?: \\|-!--!-\\)abc\\(?: \\|-!-\\)123"))))
(provide 'character-fold-tests)
;;; character-fold-tests.el ends here
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment