* bug#35689: Customizable char-fold
@ 2019-05-11 21:22 Juri Linkov
2019-05-12 19:12 ` Juri Linkov
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Juri Linkov @ 2019-05-11 21:22 UTC (permalink / raw)
To: 35689
[-- Attachment #1: Type: text/plain, Size: 74 bytes --]
Tags: patch
This patch adds long-awaited customization to char-fold.el:
[-- Attachment #2: char-fold-defcustom.patch --]
[-- Type: text/x-diff, Size: 3040 bytes --]
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index e61bc3edc6..24882008a4 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -24,6 +24,30 @@
(eval-and-compile (put 'char-fold-table 'char-table-extra-slots 1))
\f
+(defcustom char-fold-include-base nil
+ "Include mappings from composite character to base letter."
+ :type 'boolean
+ :group 'matching
+ :version "27.1")
+
+(defcustom char-fold-include-alist
+ '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
+ (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
+ (?` "❛" "‘" "‛" "" "❮" "‹"))
+ "Additional character mappings to include."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (repeat (string :tag "To")))
+ :group 'lisp
+ :version "27.1")
+
+(defcustom char-fold-exclude-alist nil
+ "Character mappings to exclude from default setting."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (character :tag "To"))
+ :group 'lisp
+ :version "27.1")
+
+\f
(defconst char-fold-table
(eval-when-compile
(let ((equiv (make-char-table 'char-fold-table))
@@ -76,7 +106,11 @@ char-fold-table
(aref equiv-multi (car decomp))))
(aset equiv (car decomp)
(cons (char-to-string char)
- (aref equiv (car decomp))))))))
+ (aref equiv (car decomp))))
+ (when char-fold-include-base
+ (aset equiv char
+ (cons (char-to-string (car decomp))
+ (aref equiv (car decomp)))))))))
(funcall make-decomp-match-char decomp char)
;; Do it again, without the non-spacing characters.
;; This allows 'a' to match 'ä'.
@@ -98,13 +132,18 @@ char-fold-table
table)
;; Add some manual entries.
- (dolist (it '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
- (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
- (?` "❛" "‘" "‛" "" "❮" "‹")))
+ (dolist (it char-fold-include-alist)
(let ((idx (car it))
(chars (cdr it)))
(aset equiv idx (append chars (aref equiv idx)))))
+ ;; Remove some entries.
+ (dolist (it char-fold-exclude-alist)
+ (let ((idx (car it))
+ (char (cdr it)))
+ (when (aref equiv idx)
+ (aset equiv idx (remove (char-to-string char) (aref equiv idx))))))
+
;; Convert the lists of characters we compiled into regexps.
(map-char-table
(lambda (char dec-list)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-11 21:22 bug#35689: Customizable char-fold Juri Linkov
@ 2019-05-12 19:12 ` Juri Linkov
2019-05-12 20:30 ` Noam Postavsky
2019-07-23 20:28 ` Juri Linkov
2019-07-28 22:46 ` Juri Linkov
2 siblings, 1 reply; 16+ messages in thread
From: Juri Linkov @ 2019-05-12 19:12 UTC (permalink / raw)
To: 35689
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
> This patch adds long-awaited customization to char-fold.el:
I noticed that its compilation fails with:
ELC char-fold.elc
In toplevel form:
char-fold.el:153:31:Error: Symbol's value as variable is void: char-fold-include-base
Makefile:296: recipe for target 'char-fold.elc' failed
make[2]: *** [char-fold.elc] Error 1
So a new patch added 'eval-and-compile' to all defcustoms:
[-- Attachment #2: char-fold-defcustom.2.patch --]
[-- Type: text/x-diff, Size: 3097 bytes --]
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index e61bc3edc6..a60d49dd8e 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -24,6 +24,30 @@
(eval-and-compile (put 'char-fold-table 'char-table-extra-slots 1))
\f
+(eval-and-compile (defcustom char-fold-include-base nil
+ "Include mappings from composite character to base letter."
+ :type 'boolean
+ :group 'matching
+ :version "27.1"))
+
+(eval-and-compile (defcustom char-fold-include-alist
+ '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
+ (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
+ (?` "❛" "‘" "‛" "" "❮" "‹"))
+ "Additional character mappings to include."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (repeat (string :tag "To")))
+ :group 'lisp
+ :version "27.1"))
+
+(eval-and-compile (defcustom char-fold-exclude-alist nil
+ "Character mappings to exclude from default setting."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (character :tag "To"))
+ :group 'lisp
+ :version "27.1"))
+
+\f
(defconst char-fold-table
(eval-when-compile
(let ((equiv (make-char-table 'char-fold-table))
@@ -76,7 +109,11 @@ char-fold-table
(aref equiv-multi (car decomp))))
(aset equiv (car decomp)
(cons (char-to-string char)
- (aref equiv (car decomp))))))))
+ (aref equiv (car decomp))))
+ (when char-fold-include-base
+ (aset equiv char
+ (cons (char-to-string (car decomp))
+ (aref equiv (car decomp)))))))))
(funcall make-decomp-match-char decomp char)
;; Do it again, without the non-spacing characters.
;; This allows 'a' to match 'ä'.
@@ -98,13 +135,18 @@ char-fold-table
table)
;; Add some manual entries.
- (dolist (it '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
- (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
- (?` "❛" "‘" "‛" "" "❮" "‹")))
+ (dolist (it char-fold-include-alist)
(let ((idx (car it))
(chars (cdr it)))
(aset equiv idx (append chars (aref equiv idx)))))
+ ;; Remove some entries.
+ (dolist (it char-fold-exclude-alist)
+ (let ((idx (car it))
+ (char (cdr it)))
+ (when (aref equiv idx)
+ (aset equiv idx (remove (char-to-string char) (aref equiv idx))))))
+
;; Convert the lists of characters we compiled into regexps.
(map-char-table
(lambda (char dec-list)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-12 19:12 ` Juri Linkov
@ 2019-05-12 20:30 ` Noam Postavsky
2019-05-13 20:31 ` Juri Linkov
0 siblings, 1 reply; 16+ messages in thread
From: Noam Postavsky @ 2019-05-12 20:30 UTC (permalink / raw)
To: Juri Linkov; +Cc: 35689
Juri Linkov <juri@linkov.net> writes:
>> This patch adds long-awaited customization to char-fold.el:
>
> I noticed that its compilation fails with:
>
> ELC char-fold.elc
> In toplevel form:
> char-fold.el:153:31:Error: Symbol's value as variable is void: char-fold-include-base
> Makefile:296: recipe for target 'char-fold.elc' failed
> make[2]: *** [char-fold.elc] Error 1
>
> So a new patch added 'eval-and-compile' to all defcustoms:
Will it actually work for a user to customize this? It looks like the
values are used during compile time, so after changing the value the
user would have to recompile char-fold.el?
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-12 20:30 ` Noam Postavsky
@ 2019-05-13 20:31 ` Juri Linkov
2019-05-13 22:18 ` Noam Postavsky
0 siblings, 1 reply; 16+ messages in thread
From: Juri Linkov @ 2019-05-13 20:31 UTC (permalink / raw)
To: Noam Postavsky; +Cc: 35689
[-- Attachment #1: Type: text/plain, Size: 674 bytes --]
>>> This patch adds long-awaited customization to char-fold.el:
>>
>> I noticed that its compilation fails with:
>>
>> ELC char-fold.elc
>> In toplevel form:
>> char-fold.el:153:31:Error: Symbol's value as variable is void: char-fold-include-base
>> Makefile:296: recipe for target 'char-fold.elc' failed
>> make[2]: *** [char-fold.elc] Error 1
>>
>> So a new patch added 'eval-and-compile' to all defcustoms:
>
> Will it actually work for a user to customize this? It looks like the
> values are used during compile time, so after changing the value the
> user would have to recompile char-fold.el?
Oh, right. Do you see a problem with a better patch:
[-- Attachment #2: char-fold-defcustom.3.patch --]
[-- Type: text/x-diff, Size: 4139 bytes --]
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index e61bc3edc6..6c3f809c2b 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -24,8 +24,43 @@
(eval-and-compile (put 'char-fold-table 'char-table-extra-slots 1))
\f
-(defconst char-fold-table
- (eval-when-compile
+(eval-and-compile (defcustom char-fold-include-base nil
+ "Include mappings from composite character to base letter."
+ :type 'boolean
+ :set (lambda (sym val)
+ (set sym val)
+ (when (boundp 'char-fold-table)
+ (setq char-fold-table (char-fold-make-table))))
+ :group 'matching
+ :version "27.1"))
+
+(eval-and-compile (defcustom char-fold-include-alist
+ '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
+ (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
+ (?` "❛" "‘" "‛" "" "❮" "‹"))
+ "Additional character mappings to include."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (repeat (string :tag "To")))
+ :set (lambda (sym val)
+ (set sym val)
+ (when (boundp 'char-fold-table)
+ (setq char-fold-table (char-fold-make-table))))
+ :group 'lisp
+ :version "27.1"))
+
+(eval-and-compile (defcustom char-fold-exclude-alist nil
+ "Character mappings to exclude from default setting."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (character :tag "To"))
+ :set (lambda (sym val)
+ (set sym val)
+ (when (boundp 'char-fold-table)
+ (setq char-fold-table (char-fold-make-table))))
+ :group 'lisp
+ :version "27.1"))
+
+(eval-and-compile
+ (defun char-fold-make-table ()
(let ((equiv (make-char-table 'char-fold-table))
(equiv-multi (make-char-table 'char-fold-table))
(table (unicode-property-table-internal 'decomposition)))
@@ -76,7 +123,11 @@ char-fold-table
(aref equiv-multi (car decomp))))
(aset equiv (car decomp)
(cons (char-to-string char)
- (aref equiv (car decomp))))))))
+ (aref equiv (car decomp))))
+ (when char-fold-include-base
+ (aset equiv char
+ (cons (char-to-string (car decomp))
+ (aref equiv (car decomp)))))))))
(funcall make-decomp-match-char decomp char)
;; Do it again, without the non-spacing characters.
;; This allows 'a' to match 'ä'.
@@ -98,13 +149,18 @@ char-fold-table
table)
;; Add some manual entries.
- (dolist (it '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
- (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
- (?` "❛" "‘" "‛" "" "❮" "‹")))
+ (dolist (it char-fold-include-alist)
(let ((idx (car it))
(chars (cdr it)))
(aset equiv idx (append chars (aref equiv idx)))))
+ ;; Remove some entries.
+ (dolist (it char-fold-exclude-alist)
+ (let ((idx (car it))
+ (char (cdr it)))
+ (when (aref equiv idx)
+ (aset equiv idx (remove (char-to-string char) (aref equiv idx))))))
+
;; Convert the lists of characters we compiled into regexps.
(map-char-table
(lambda (char dec-list)
@@ -113,7 +169,11 @@ char-fold-table
(set-char-table-range equiv char re)
(aset equiv char re))))
equiv)
- equiv))
+ equiv)))
+
+(defconst char-fold-table
+ (eval-when-compile
+ (char-fold-make-table))
"Used for folding characters of the same group during search.
This is a char-table with the `char-fold-table' subtype.
^ permalink raw reply related [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-13 20:31 ` Juri Linkov
@ 2019-05-13 22:18 ` Noam Postavsky
2019-05-14 6:37 ` Eli Zaretskii
0 siblings, 1 reply; 16+ messages in thread
From: Noam Postavsky @ 2019-05-13 22:18 UTC (permalink / raw)
To: Juri Linkov; +Cc: 35689
Juri Linkov <juri@linkov.net> writes:
> Oh, right. Do you see a problem with a better patch:
> +(eval-and-compile (defcustom char-fold-include-base nil
> + "Include mappings from composite character to base letter."
> + :type 'boolean
> + :set (lambda (sym val)
> + (set sym val)
> + (when (boundp 'char-fold-table)
> + (setq char-fold-table (char-fold-make-table))))
Looks like it could work (though I haven't tested). The docstrings are
too terse for me easily follow, and they should probably include
something along the lines of "Setting this variable directly does not
take effect; either use M-x customize or ..."
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-13 22:18 ` Noam Postavsky
@ 2019-05-14 6:37 ` Eli Zaretskii
2019-05-14 20:14 ` Juri Linkov
0 siblings, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2019-05-14 6:37 UTC (permalink / raw)
To: 35689, npostavs, juri
On May 14, 2019 1:18:18 AM GMT+03:00, Noam Postavsky <npostavs@gmail.com> wrote:
> Juri Linkov <juri@linkov.net> writes:
>
> > Oh, right. Do you see a problem with a better patch:
>
> > +(eval-and-compile (defcustom char-fold-include-base nil
> > + "Include mappings from composite character to base letter."
> > + :type 'boolean
> > + :set (lambda (sym val)
> > + (set sym val)
> > + (when (boundp 'char-fold-table)
> > + (setq char-fold-table (char-fold-make-table))))
>
> Looks like it could work (though I haven't tested). The docstrings
> are
> too terse for me easily follow, and they should probably include
> something along the lines of "Setting this variable directly does not
> take effect; either use M-x customize or ..."
We don't gave defcustoms inside eval-and/when-compile anywhere else. Do we really need this? For starters, it would defeat cus-dep.el, I think.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-14 6:37 ` Eli Zaretskii
@ 2019-05-14 20:14 ` Juri Linkov
2019-05-16 14:47 ` npostavs
0 siblings, 1 reply; 16+ messages in thread
From: Juri Linkov @ 2019-05-14 20:14 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 35689, npostavs
>> > Oh, right. Do you see a problem with a better patch:
>>
>> > +(eval-and-compile (defcustom char-fold-include-base nil
>> > + "Include mappings from composite character to base letter."
>> > + :type 'boolean
>> > + :set (lambda (sym val)
>> > + (set sym val)
>> > + (when (boundp 'char-fold-table)
>> > + (setq char-fold-table (char-fold-make-table))))
>>
>> Looks like it could work (though I haven't tested). The docstrings
>> are
>> too terse for me easily follow, and they should probably include
>> something along the lines of "Setting this variable directly does not
>> take effect; either use M-x customize or ..."
>
> We don't gave defcustoms inside eval-and/when-compile anywhere else.
> Do we really need this? For starters, it would defeat cus-dep.el, I think.
Indeed, better to try and simplify this. The goal is to pre-compile
the default char-table because its calculation is compute-intensive,
and to recalculate a new value of char-table only in case
when customized values differ from the default values.
I can't find a standard way of doing this. So instead of using eval-and-compile
I'll try to recalculate the value explicitly when variables are customized:
(when (or (get 'char-fold-include-base 'customized-value)
(get 'char-fold-include-alist 'customized-value)
(get 'char-fold-exclude-alist 'customized-value))
(setq char-fold-table (char-fold-make-table)))
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-14 20:14 ` Juri Linkov
@ 2019-05-16 14:47 ` npostavs
2019-05-16 20:13 ` Juri Linkov
0 siblings, 1 reply; 16+ messages in thread
From: npostavs @ 2019-05-16 14:47 UTC (permalink / raw)
To: Juri Linkov; +Cc: 35689, npostavs
Juri Linkov <juri@linkov.net> writes:
>> We don't gave defcustoms inside eval-and/when-compile anywhere else.
>> Do we really need this? For starters, it would defeat cus-dep.el, I think.
>
> Indeed, better to try and simplify this. The goal is to pre-compile
> the default char-table because its calculation is compute-intensive,
> and to recalculate a new value of char-table only in case
> when customized values differ from the default values.
>
> I can't find a standard way of doing this. So instead of using eval-and-compile
> I'll try to recalculate the value explicitly when variables are customized:
>
> (when (or (get 'char-fold-include-base 'customized-value)
> (get 'char-fold-include-alist 'customized-value)
> (get 'char-fold-exclude-alist 'customized-value))
> (setq char-fold-table (char-fold-make-table)))
Instead of looking at symbol property values, which can make for a
confusing time when setting variables outside of customize, I think it
would be nicer to do something like this:
(eval-and-compile (defconst char-fold--include-base-default ...))
(defcustom char-fold-include-base char-fold--include-base-default
:initialize #'custom-initialize-changed
:set (lambda (sym val)
(set-default sym val)
;; FIXME: Maybe delay this until after-init-time,
;; to avoid redundant calls to char-fold-make-table.
(setq char-fold-table (char-fold-make-table)))
...)
(eval-and-compile
(defun char-fold-make-table ()
...
(or (bound-and-true-p 'char-fold-include-base)
char-fold--include-base-default)
...))
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-16 14:47 ` npostavs
@ 2019-05-16 20:13 ` Juri Linkov
2019-05-21 20:34 ` Juri Linkov
0 siblings, 1 reply; 16+ messages in thread
From: Juri Linkov @ 2019-05-16 20:13 UTC (permalink / raw)
To: npostavs; +Cc: 35689
>> I can't find a standard way of doing this. So instead of using eval-and-compile
>> I'll try to recalculate the value explicitly when variables are customized:
>>
>> (when (or (get 'char-fold-include-base 'customized-value)
>> (get 'char-fold-include-alist 'customized-value)
>> (get 'char-fold-exclude-alist 'customized-value))
>> (setq char-fold-table (char-fold-make-table)))
>
> Instead of looking at symbol property values, which can make for a
> confusing time when setting variables outside of customize, I think it
> would be nicer to do something like this:
>
> (eval-and-compile (defconst char-fold--include-base-default ...))
>
> (defcustom char-fold-include-base char-fold--include-base-default
> :initialize #'custom-initialize-changed
I tried different possible values of :initialize,
but not custom-initialize-changed. I'll try this now.
The problem I encountered with the previous solution it that
calling `(setq char-fold-table (char-fold-make-table))' above
while loading char-fold.el by autoload, garbled data returned
from `(unicode-property-table-internal 'decomposition)',
it just returned garbage, maybe due to a broken coding.
I was busy debugging unidata-get-decomposition to
understand where this data corruption occurs.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-16 20:13 ` Juri Linkov
@ 2019-05-21 20:34 ` Juri Linkov
2019-05-21 21:45 ` npostavs
2019-06-24 17:33 ` Lars Ingebrigtsen
0 siblings, 2 replies; 16+ messages in thread
From: Juri Linkov @ 2019-05-21 20:34 UTC (permalink / raw)
To: npostavs; +Cc: 35689
[-- Attachment #1: Type: text/plain, Size: 1315 bytes --]
>>> I can't find a standard way of doing this. So instead of using eval-and-compile
>>> I'll try to recalculate the value explicitly when variables are customized:
>>>
>>> (when (or (get 'char-fold-include-base 'customized-value)
>>> (get 'char-fold-include-alist 'customized-value)
>>> (get 'char-fold-exclude-alist 'customized-value))
>>> (setq char-fold-table (char-fold-make-table)))
>>
>> Instead of looking at symbol property values, which can make for a
>> confusing time when setting variables outside of customize, I think it
>> would be nicer to do something like this:
>>
>> (defcustom char-fold-include-base char-fold--include-base-default
>> :initialize #'custom-initialize-changed
>> :set (lambda (sym val)
>> (set-default sym val)
>> ;; FIXME: Maybe delay this until after-init-time,
>> ;; to avoid redundant calls to char-fold-make-table.
>
> I tried different possible values of :initialize,
> but not custom-initialize-changed. I'll try this now.
I see no problems other than redundant calls to char-fold-make-table
when more than one variable is customized. char-fold.el is autoloaded
when isearch calls char-fold-to-regexp for the first time, so I'm not
sure how after-init-hook could help in this case.
[-- Attachment #2: char-fold-defcustom.4.patch --]
[-- Type: text/x-diff, Size: 5387 bytes --]
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index 426b1a9f84..16d6d484f0 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -21,13 +21,22 @@
;;; Code:
-(eval-and-compile (put 'char-fold-table 'char-table-extra-slots 1))
+(eval-and-compile
+ (put 'char-fold-table 'char-table-extra-slots 1)
+ (defconst char-fold--symmetric-default nil)
+ (defconst char-fold--include-alist-default
+ '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
+ (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
+ (?` "❛" "‘" "‛" "" "❮" "‹")))
+ (defconst char-fold--exclude-alist-default nil))
+
\f
-(defconst char-fold-table
- (eval-when-compile
- (let ((equiv (make-char-table 'char-fold-table))
- (equiv-multi (make-char-table 'char-fold-table))
- (table (unicode-property-table-internal 'decomposition)))
+(eval-and-compile
+ (defun char-fold-make-table ()
+ (let* ((equiv (make-char-table 'char-fold-table))
+ (equiv-multi (make-char-table 'char-fold-table))
+ (search-spaces-regexp nil) ; bug#35802
+ (table (unicode-property-table-internal 'decomposition)))
(set-char-table-extra-slot equiv 0 equiv-multi)
;; Ensure the table is populated.
@@ -75,7 +84,12 @@ char-fold-table
(aref equiv-multi (car decomp))))
(aset equiv (car decomp)
(cons (char-to-string char)
- (aref equiv (car decomp))))))))
+ (aref equiv (car decomp))))
+ (when (or (bound-and-true-p char-fold-symmetric)
+ char-fold--symmetric-default)
+ (aset equiv char
+ (cons (char-to-string (car decomp))
+ (aref equiv (car decomp)))))))))
(funcall make-decomp-match-char decomp char)
;; Do it again, without the non-spacing characters.
;; This allows 'a' to match 'ä'.
@@ -97,13 +111,20 @@ char-fold-table
table)
;; Add some manual entries.
- (dolist (it '((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
- (?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "" "❮" "❯" "‹" "›")
- (?` "❛" "‘" "‛" "" "❮" "‹")))
+ (dolist (it (or (bound-and-true-p char-fold-include-alist)
+ char-fold--include-alist-default))
(let ((idx (car it))
(chars (cdr it)))
(aset equiv idx (append chars (aref equiv idx)))))
+ ;; Remove some entries.
+ (dolist (it (or (bound-and-true-p char-fold-exclude-alist)
+ char-fold--exclude-alist-default))
+ (let ((idx (car it))
+ (char (cdr it)))
+ (when (aref equiv idx)
+ (aset equiv idx (remove (char-to-string char) (aref equiv idx))))))
+
;; Convert the lists of characters we compiled into regexps.
(map-char-table
(lambda (char dec-list)
@@ -112,7 +133,11 @@ char-fold-table
(set-char-table-range equiv char re)
(aset equiv char re))))
equiv)
- equiv))
+ equiv)))
+
+(defconst char-fold-table
+ (eval-when-compile
+ (char-fold-make-table))
"Used for folding characters of the same group during search.
This is a char-table with the `char-fold-table' subtype.
@@ -135,6 +160,40 @@ char-fold-table
Exceptionally for the space character (32), ALIST is ignored.")
+(defcustom char-fold-symmetric char-fold--symmetric-default
+ "Include symmetric mappings from composite character back to base letter."
+ :type 'boolean
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (set-default sym val)
+ ;; FIXME: Maybe delay this until after-init-hook,
+ ;; to avoid redundant calls to char-fold-make-table.
+ (setq char-fold-table (char-fold-make-table)))
+ :group 'matching
+ :version "27.1")
+
+(defcustom char-fold-include-alist char-fold--include-alist-default
+ "Additional character mappings to include."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (repeat (string :tag "To")))
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (set-default sym val)
+ (setq char-fold-table (char-fold-make-table)))
+ :group 'lisp
+ :version "27.1")
+
+(defcustom char-fold-exclude-alist char-fold--exclude-alist-default
+ "Character mappings to exclude from default setting."
+ :type '(alist :key-type (character :tag "From")
+ :value-type (character :tag "To"))
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (set-default sym val)
+ (setq char-fold-table (char-fold-make-table)))
+ :group 'lisp
+ :version "27.1")
+
(defun char-fold--make-space-string (n)
"Return a string that matches N spaces."
(format "\\(?:%s\\|%s\\)"
^ permalink raw reply related [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-21 20:34 ` Juri Linkov
@ 2019-05-21 21:45 ` npostavs
2019-06-06 20:49 ` Juri Linkov
2019-06-24 17:33 ` Lars Ingebrigtsen
1 sibling, 1 reply; 16+ messages in thread
From: npostavs @ 2019-05-21 21:45 UTC (permalink / raw)
To: Juri Linkov; +Cc: 35689, npostavs
Juri Linkov <juri@linkov.net> writes:
>>> :set (lambda (sym val)
>>> (set-default sym val)
>>> ;; FIXME: Maybe delay this until after-init-time,
>>> ;; to avoid redundant calls to char-fold-make-table.
>>
>> I tried different possible values of :initialize,
>> but not custom-initialize-changed. I'll try this now.
>
> I see no problems other than redundant calls to char-fold-make-table
> when more than one variable is customized. char-fold.el is autoloaded
> when isearch calls char-fold-to-regexp for the first time, so I'm not
> sure how after-init-hook could help in this case.
Ah, sorry, I had somehow got it into my head that char-fold.el is
preloaded.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-21 21:45 ` npostavs
@ 2019-06-06 20:49 ` Juri Linkov
0 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2019-06-06 20:49 UTC (permalink / raw)
To: npostavs; +Cc: 35689
>>>> :set (lambda (sym val)
>>>> (set-default sym val)
>>>> ;; FIXME: Maybe delay this until after-init-time,
>>>> ;; to avoid redundant calls to char-fold-make-table.
>>>
>>> I tried different possible values of :initialize,
>>> but not custom-initialize-changed. I'll try this now.
>>
>> I see no problems other than redundant calls to char-fold-make-table
>> when more than one variable is customized. char-fold.el is autoloaded
>> when isearch calls char-fold-to-regexp for the first time, so I'm not
>> sure how after-init-hook could help in this case.
>
> Ah, sorry, I had somehow got it into my head that char-fold.el is
> preloaded.
I still haven't found a way to avoid calling char-fold-make-table
3 times when 3 variables are customized. Maybe this is not possible
because currently customizable variables have no dependency on each other.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-21 20:34 ` Juri Linkov
2019-05-21 21:45 ` npostavs
@ 2019-06-24 17:33 ` Lars Ingebrigtsen
2019-06-24 20:40 ` Juri Linkov
1 sibling, 1 reply; 16+ messages in thread
From: Lars Ingebrigtsen @ 2019-06-24 17:33 UTC (permalink / raw)
To: Juri Linkov; +Cc: 35689, npostavs
Juri Linkov <juri@linkov.net> writes:
> -(defconst char-fold-table
[...]
> +(defcustom char-fold-symmetric char-fold--symmetric-default
> + "Include symmetric mappings from composite character back to base letter."
> + :type 'boolean
> + :initialize #'custom-initialize-changed
> + :set (lambda (sym val)
> + (set-default sym val)
> + ;; FIXME: Maybe delay this until after-init-hook,
> + ;; to avoid redundant calls to char-fold-make-table.
> + (setq char-fold-table (char-fold-make-table)))
OK, here's an uninformed suggestion -- instead of doing all this to
ensure that we have an updated char-fold-table when the user changes
these defaults, why not call char-fold-make-table when needed?
That is, instead of the char-fold-table variable, you'd have a
char-fold-data, which could be, say, something like this:
(defvar char-fold-data :uninitialized)
`char-fold-to-regexp' (and others) would then start with a call to
char-fold-update which would
be
(let ((new (list :additional char-fold--include-alist-default
:exclude char-fold--exclude-alist-default
...)))
(unless (equal char-fold-data new)
(setq char-fold-table (char-fold-make-table)
char-fold-data new)))
or something along those lines. That is, check whether anything has
changed, and if not, do nothing, but if it has, recompute?
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-06-24 17:33 ` Lars Ingebrigtsen
@ 2019-06-24 20:40 ` Juri Linkov
0 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2019-06-24 20:40 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 35689, npostavs
>> +(defcustom char-fold-symmetric char-fold--symmetric-default
>> + "Include symmetric mappings from composite character back to base letter."
>> + :type 'boolean
>> + :initialize #'custom-initialize-changed
>> + :set (lambda (sym val)
>> + (set-default sym val)
>> + ;; FIXME: Maybe delay this until after-init-hook,
>> + ;; to avoid redundant calls to char-fold-make-table.
>> + (setq char-fold-table (char-fold-make-table)))
>
> OK, here's an uninformed suggestion -- instead of doing all this to
> ensure that we have an updated char-fold-table when the user changes
> these defaults, why not call char-fold-make-table when needed?
>
> That is, instead of the char-fold-table variable, you'd have a
> char-fold-data, which could be, say, something like this:
>
> (defvar char-fold-data :uninitialized)
>
> `char-fold-to-regexp' (and others) would then start with a call to
> char-fold-update which would
>
> be
>
> (let ((new (list :additional char-fold--include-alist-default
> :exclude char-fold--exclude-alist-default
> ...)))
> (unless (equal char-fold-data new)
> (setq char-fold-table (char-fold-make-table)
> char-fold-data new)))
>
> or something along those lines. That is, check whether anything has
> changed, and if not, do nothing, but if it has, recompute?
Thanks for the idea, I'll try to use such composite value to detect
updates in one of three variables.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-11 21:22 bug#35689: Customizable char-fold Juri Linkov
2019-05-12 19:12 ` Juri Linkov
@ 2019-07-23 20:28 ` Juri Linkov
2019-07-28 22:46 ` Juri Linkov
2 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2019-07-23 20:28 UTC (permalink / raw)
To: 35689-done
Thanks to everyone who helped! Pushed to master as 376f5df3cc.
^ permalink raw reply [flat|nested] 16+ messages in thread
* bug#35689: Customizable char-fold
2019-05-11 21:22 bug#35689: Customizable char-fold Juri Linkov
2019-05-12 19:12 ` Juri Linkov
2019-07-23 20:28 ` Juri Linkov
@ 2019-07-28 22:46 ` Juri Linkov
2 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2019-07-28 22:46 UTC (permalink / raw)
To: 35689
[-- Attachment #1: Type: text/plain, Size: 403 bytes --]
tags 35689 + fixed
close 35689 27.0.50
quit
I'm closing this customization feature request.
More default values for char-folding could be added depending on user's locale.
But this is another feature that could be implemented within i18n efforts.
PS: As a demonstration what the current customization feature can achieve,
I'm attaching a short snippet that allows searching using Cyrillic translit:
[-- Attachment #2: char-fold-translit.el --]
[-- Type: application/emacs-lisp, Size: 1808 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2019-07-28 22:46 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-11 21:22 bug#35689: Customizable char-fold Juri Linkov
2019-05-12 19:12 ` Juri Linkov
2019-05-12 20:30 ` Noam Postavsky
2019-05-13 20:31 ` Juri Linkov
2019-05-13 22:18 ` Noam Postavsky
2019-05-14 6:37 ` Eli Zaretskii
2019-05-14 20:14 ` Juri Linkov
2019-05-16 14:47 ` npostavs
2019-05-16 20:13 ` Juri Linkov
2019-05-21 20:34 ` Juri Linkov
2019-05-21 21:45 ` npostavs
2019-06-06 20:49 ` Juri Linkov
2019-06-24 17:33 ` Lars Ingebrigtsen
2019-06-24 20:40 ` Juri Linkov
2019-07-23 20:28 ` Juri Linkov
2019-07-28 22:46 ` Juri Linkov
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).