rrthomas / enchant

enchant spellchecking library
http://rrthomas.github.io/enchant/
GNU Lesser General Public License v2.1
347 stars 60 forks source link

Enchant doesn't seem to be reading `enchant.ordering` #328

Closed fergiemcdowall closed 1 year ago

fergiemcdowall commented 1 year ago

I have installed enchant on my macbook. I would like to only use AppleSpell for all languages and have therefore created the file ~/.config/enchant/enchant.ordering which looks like this ->

> cat ~/.config/enchant/enchant.ordering 
*:AppleSpell

Yet running enchant-lsmod-2 shows that aspell is still selected and has precedence over AppleSpell ->

> enchant-lsmod-2
aspell (Aspell Provider)
AppleSpell (AppleSpell Provider)

What gives? How do I get enchant to read the config file such that it defaults to AppleSpell on mac?

rrthomas commented 1 year ago

As you'll see in the man page for enchant-lsmod-2, running the command with no arguments just lists the available providers.

enchant-lsmod-2 -list-dicts will show what provider is selected for each language.

fergiemcdowall commented 1 year ago

The output from enchant-lsmod-2 shows me that aspell has precedence over AppleSpell (I think?). This seems to be wrong since I have only specified *:AppleSpell in the config file.

Therefore, when I run enchant-lsmod-2 -list-dicts, most of the dictionaries are marked as aspell, when I would expect there to be none since I have only specified AppleSpell in enchant.ordering

output of enchant-lsmod-2 -list-dicts ->

> enchant-lsmod-2 -list-dicts
af (aspell)
am (aspell)
ar (aspell)
ast (aspell)
az (aspell)
be (aspell)
be_BY (aspell)
be_SU (aspell)
bg (aspell)
bn (aspell)
br (aspell)
ca (aspell)
cs (aspell)
csb (aspell)
cy (aspell)
da (aspell)
de (aspell)
de_AT (aspell)
de_CH (aspell)
de_DE (AppleSpell)
el (aspell)
en (aspell)
en_AU (aspell)
en_CA (aspell)
en_GB (aspell)
en_US (aspell)
eo (aspell)
es (aspell)
es_ES (AppleSpell)
et (aspell)
fa (aspell)
fi (aspell)
fo (aspell)
fr (aspell)
fr_CH (aspell)
fr_FR (AppleSpell)
fy (aspell)
ga (aspell)
gd (aspell)
gl (aspell)
gr (aspell)
grc (aspell)
gu (aspell)
gv (aspell)
he (aspell)
hi (aspell)
hil (aspell)
hr (aspell)
hsb (aspell)
hu (aspell)
hu_HU (AppleSpell)
hus (aspell)
hy (aspell)
ia (aspell)
id (aspell)
it (aspell)
it_IT (AppleSpell)
kn (aspell)
ku (aspell)
ky (aspell)
la (aspell)
lt (aspell)
lv (aspell)
mg (aspell)
mi (aspell)
mk (aspell)
ml (aspell)
mn (aspell)
mr (aspell)
ms (aspell)
mt (aspell)
nds (aspell)
nl (aspell)
nl_NL (AppleSpell)
nn (aspell)
ny (aspell)
or (aspell)
pa (aspell)
pl (aspell)
pt_BR (AppleSpell)
pt_PT (aspell)
qu (aspell)
ro (aspell)
ru (aspell)
rw (aspell)
sc (aspell)
sk (aspell)
sk_SK (aspell)
sl (aspell)
sr (aspell)
srd (aspell)
sv (aspell)
sv_SE (AppleSpell)
sw (aspell)
ta (aspell)
te (aspell)
tet (aspell)
tk (aspell)
tl (aspell)
tn (aspell)
tr (aspell)
uk (aspell)
uz (aspell)
vi (aspell)
wa (aspell)
yi (aspell)
zu (aspell)

Surely I should only see the languages marked (AppleSpell), and surely there should be more of them?

rrthomas commented 1 year ago

What should happen is that Enchant should use AppleSpell for all languages for which AppleSpell has dictionaries, and other providers for other languages. (In particular, just because you didn't mention aspell it doesn't stop Enchant from ever using it: Enchant will still use its own enchant.ordering file, just at a lower priority.) I am guessing that you're expecting to see AppleSpell used for en or en_US. but it isn't. However, it is used for some other languages. That suggests to me that either Enchant doesn't see the AppleSpell dictionary/dictionaries for English, for some reason. (If it were globally preferring aspell to AppleSpell, as per its default enchant.ordering, I would expect languages like de_DE to use aspell.)

BTW, you can also use enchant-lsmod-2 -lang en_US to get the back-end for a particular language.

Looks like some further debugging is needed here. I'm wishing I had a -debug option to enchant-lsmod to show everything it finds in the configuration, but meanwhile, what you could do is overwrite the "system" enchant.ordering (probably /usr/local/share/enchant/enchant.ordering) with a file that has the same contents as your personal one, and see if that changes things.

fergiemcdowall commented 1 year ago

Yes, editing the system files at /opt/homebrew/Cellar/enchant/2.5.0/share/enchant (kind of) works.

If I remove entries from /opt/homebrew/Cellar/enchant/2.5.0/share/enchant/AppleSpell.config I can see that they are no longer marked as "AppleSpell" in the output of enchant-lsmod-2 -list-dicts.

I would like to get enchant to use AppleSpell for Norwegian. I am fairly sure that OSX has the dictionary because I can do norwegian spellchecking on other applications. Yet adding nb_NO no Norsk to AppleSpell.config doesnt seem to work.

How do I see which language packs AppleSpell has installed so that I can work out how to specify Norwegian in AppleSpell.config?

fergiemcdowall commented 1 year ago

Adding nb_NO nb Norsk Bokmål to AppleSpell.config seems to work

rrthomas commented 1 year ago

Thanks for the updates, and for experimenting. I think the best thing here, if you're able to help further, would be for me to add some debugging to enchant-lsmod-2, so I can find out whether Enchant is actually doing anything wrong, or whether it's just complicated. (A -debug flag could be useful for users too, and I do get a fair number of questions about enchant.ordering.)

benthamite commented 1 year ago

I am experiencing a similar issue.

> cat ~/.config/enchant/enchant.ordering:

*:AppleSpell

> cat /opt/homebrew/Cellar/enchant/2.5.0/share/enchant/AppleSpell.config:

de_DE   de  Deutsch
en_US   en  English
en_AU   en_AU   Australian English
en_CA   en_CA   Canadian English
en_GB   en_GB   British English
es_ES   es  Español
fr_FR   fr  Français
it_IT   it  Italiano
nl_NL   nl  Nederlands
pt_PT   pt  Português
pt_BR   pt_BR   Português do Brasil
sv_SE   sv  Svenska
hu_HU   hu      Magyar (MySpellX)

Yet

cat enchant-lsmod-2 -lang en_EN:

en_EN (aspell)

(Aspell is also used for the other English variantes.)

This affects only English; e.g.:

cat enchant-lsmod-2 -lang es_ES:

es_ES (AppleSpell)

Do you have a sense of what might be causing this issue or what steps I could take to diagnose it?

rrthomas commented 1 year ago

I don't recognize en_EN as a locale you're likely to have; specifically, EN does not appear to be a valid country code. Nor is such a locale configured in the list you sent. I'm guessing that AppleSpell doesn't recognize it, but Aspell is more forgiving.

benthamite commented 1 year ago

Thanks. The same is true of the other English locales, though:

en (aspell)
en_AU (aspell)
en_CA (aspell)
en_GB (aspell)
en_US (aspell)

For completeness, here's the full output of enchant-lsmod-2 -list-dicts:

af (aspell)
am (aspell)
ar (aspell)
ast (aspell)
az (aspell)
be (aspell)
be_BY (aspell)
be_SU (aspell)
bg (aspell)
bn (aspell)
br (aspell)
ca (aspell)
cs (aspell)
csb (aspell)
cy (aspell)
da (aspell)
de (aspell)
de_AT (aspell)
de_CH (aspell)
de_DE (AppleSpell)
el (aspell)
en (aspell)
en_AU (aspell)
en_CA (aspell)
en_GB (aspell)
en_US (aspell)
eo (aspell)
es (aspell)
es_ES (AppleSpell)
et (aspell)
fa (aspell)
fi (aspell)
fo (aspell)
fr (aspell)
fr_CH (aspell)
fr_FR (AppleSpell)
fy (aspell)
ga (aspell)
gd (aspell)
gl (aspell)
gr (aspell)
grc (aspell)
gu (aspell)
gv (aspell)
he (aspell)
hi (aspell)
hil (aspell)
hr (aspell)
hsb (aspell)
hu (aspell)
hu_HU (AppleSpell)
hus (aspell)
hy (aspell)
ia (aspell)
id (aspell)
it (aspell)
it_IT (AppleSpell)
kn (aspell)
ku (aspell)
ky (aspell)
la (aspell)
lt (aspell)
lv (aspell)
mg (aspell)
mi (aspell)
mk (aspell)
ml (aspell)
mn (aspell)
mr (aspell)
ms (aspell)
mt (aspell)
nds (aspell)
nl (aspell)
nl_NL (AppleSpell)
nn (aspell)
ny (aspell)
or (aspell)
pa (aspell)
pl (aspell)
pt_BR (AppleSpell)
pt_PT (aspell)
qu (aspell)
ro (aspell)
ru (aspell)
rw (aspell)
sc (aspell)
sk (aspell)
sk_SK (aspell)
sl (aspell)
sr (aspell)
srd (aspell)
sv (aspell)
sv_SE (AppleSpell)
sw (aspell)
ta (aspell)
te (aspell)
tet (aspell)
tk (aspell)
tl (aspell)
tn (aspell)
tr (aspell)
uk (aspell)
uz (aspell)
vi (aspell)
wa (aspell)
yi (aspell)
zu (aspell)
rrthomas commented 1 year ago

Thanks, it does seem that something is up here. If I add debugging to Enchant, would you be able to try building it from source? No problem if not, of course, it will just take a bit longer for you to get a version with debugging that is likely to help diagnose what's going on here.

benthamite commented 1 year ago

If I add debugging to Enchant, would you be able to try building it from source?

Yes, happy to try.

rrthomas commented 1 year ago

I've added some debug code, which can be activated by setting the G_MESSAGES_DEBUG environment variable, for example thus:

env G_MESSAGES_DEBUG=libenchant ./src/enchant-lsmod-2 -list-dicts

This should print the enchant.ordering files read, and all of the dictionaries found, along with the priority assigned to each. Hopefully that will give me a clue as to what is going on here.

benthamite commented 1 year ago

Apologies if I'm misunderstanding you, but I don't see any new commits. Where was the debug code added?

rrthomas commented 1 year ago

I'm sorry, I had forgotten that, unlike most of the projects I maintain, I do my Enchant development in my own fork: https://github.com/rrthomas/enchant/

rrthomas commented 1 year ago

With the release of 2.6.0, the debug code is now released, so now would be a good time to try to track this problem down!

benthamite commented 1 year ago

Because I wasn't able to build from source, I ended up switching to Aspell, so I won't be able to test this. But thanks for your help, anyway.

rrthomas commented 1 year ago

Thanks for letting me know! I'll close this issue for now, but don't hesitate to reopen it if you come back to Enchant and still have a problem.

fergiemcdowall commented 1 year ago

Not that I want to be difficult or anything, but I think the original bug still stands... 🙂

rrthomas commented 1 year ago

It may do, or it may have been fixed by recent changes in this area. With clear evidence of something being wrong (which it should now be easy to get), I will certainly look into it.

jdtsmith commented 10 months ago

I find the same issue with:

% cat enchant.ordering 
*:AppleSpell,hunspell,aspell
Output of env G_MESSAGES_DEBUG=libenchant enchant-lsmod-2 -list-dicts
(process:30274): libenchant-DEBUG: 17:58:36.087: reading ordering file /Users/jdsmith/.config/enchant/enchant.ordering
(process:30274): libenchant-DEBUG: 17:58:36.090: enchant_broker_list_dicts
(process:30274): libenchant-DEBUG: 17:58:36.090: provider Aspell Provider
(process:30274): libenchant-DEBUG: 17:58:36.091: tag af
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag am
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag ar
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag ast
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag az
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag be
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag be_BY
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag be_SU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag bg
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag bn
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag br
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag ca
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag ca
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag ca
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag cs
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag csb
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag cy
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag da
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag de
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag de
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag de_AT
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag de_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag de_DE
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag el
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_AU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_AU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_AU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_AU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_AU
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_CA
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_CA
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_CA
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_CA
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_CA
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_GB
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_US
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_US
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_US
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_US
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag en_US
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag eo
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag es
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag et
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fa
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fa
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fa
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fa
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fi
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fo
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_CH
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.091: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.091: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag fr_FR
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag fy
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ga
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gd
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gl
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gl
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gr
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag grc
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gu
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag gv
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag he
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hi
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hil
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hr
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hsb
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hu
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hus
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag hy
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ia
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag id
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag it
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag kn
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ku
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ky
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag la
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag lt
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag lv
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mg
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mi
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mk
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ml
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mn
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mr
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ms
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag mt
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag nds
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag nl
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag nn
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag ny
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag or
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag pa
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag pl
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.092: tag pt_BR
(process:30274): libenchant-DEBUG: 17:58:36.092: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag pt_PT
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag qu
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ro
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ro
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ru
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ru
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ru
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ru
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag rw
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sc
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sk
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sk_SK
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sl
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sr
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sr
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sr
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag srd
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sv
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag sw
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag ta
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag te
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag tet
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag tk
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag tl
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag tn
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag tr
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag uk
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag uz
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag vi
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag wa
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag yi
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: tag zu
(process:30274): libenchant-DEBUG: 17:58:36.093: priority 1
(process:30274): libenchant-DEBUG: 17:58:36.093: provider AppleSpell Provider
rrthomas commented 10 months ago

Thanks for this, @jdtsmith. Please format the debug output so it's legible. Enchant is finding no dictionaries for AppleSpell according to the output.

jdtsmith commented 10 months ago

No problem. I'm here trying (in perhaps a roundabout way) to solve a thread-race lockup in a Mac port of emacs using the libenchant-based jinx package. I had to move enchant_applespell.so out of the way to get around this, since it seems AppleSpell is initialized even if not used. See this discussion for more info if interested.

A small excerpt from the stack trace on lockup:

   11  enchant_broker_init + 308 (libenchant-2.2.dylib + 20012) [0x10c8d4e2c] 1-11
    11  ??? (enchant_applespell.so + 29168) [0x10ecab1f0] 1-11
     11  ??? (enchant_applespell.so + 27448) [0x10ecaab38] 1-11
      11  +[NSSpellChecker sharedSpellChecker] + 140 (AppKit + 2025568) [0x184617860] 1-11
       11  _dispatch_once_callout + 32 (libdispatch.dylib + 20812) [0x1809fa14c] 1-11
        11  _dispatch_client_callout + 20 (libdispatch.dylib + 14608) [0x1809f8910] 1-11
         11  __36+[NSSpellChecker sharedSpellChecker]_block_invoke + 20 (AppKit + 2025592) [0x184617878] 1-11
          11  -[NSSpellChecker init] + 252 (AppKit + 2025860) [0x184617984] 1-11
           11  -[NSSpellChecker _fillSpellCheckerPopupButton:] + 76 (AppKit + 2029636) [0x184618844] 1-11
            11  -[NSApplication(NSServicesMenuPrivate) _fillSpellCheckerPopupButton:] + 1380 (AppKit + 2031860) [0x1846190f4] 1-11
             11  -[NSMenu insertItem:atIndex:] + 520 (AppKit + 194208) [0x1844586a0] 1-11
              11  -[NSNotificationCenter postNotificationName:object:userInfo:] + 88 (Foundation + 36848) [0x181d3dff0] 1-11
               11  _CFXNotificationPost + 828 (CoreFoundation + 266780) [0x180c4b21c] 1-11
                11  -[NSOperation waitUntilFinished] + 512 (Foundation + 312364) [0x181d8142c] 1-11
                 11  __psynch_cvwait + 8 (libsystem_kernel.dylib + 20588) [0x180b6d06c] 1-11
                  *11  psynch_cvcontinue + 0 (com.apple.kec.pthread + 18204) [0xfffffe000b7bd1bc] 1-11
rrthomas commented 9 months ago

I had a quick look at the discussion you pointed at. Enchant is indeed not thread-safe by design, and one should use different brokers etc. in each thread.

Also, indeed all providers will be initialized. It might be possible in theory not to load unused providers sometimes, but not always. Remember that it's always possible for Enchant to fall back to a provider not explicitly mentioned in enchant.ordering.

It's interesting that there's a problem in Emacs here, because one reason I prefer using the Enchant front end with Emacs is precisely that it can't bring Emacs down. (I've said this before elsewhere, I think!). I wrote the Enchant support for ispell-mode; although I'm not fond of that code, that's mainly because the support for several different spelling engines complicates it, and I'd love to see a simpler version that only supports Enchant.

jdtsmith commented 9 months ago

Thanks for your thoughts. Since emacs runs no threads in parallel (it has a GIL like python), I'm not sure either.

This is specifically a problem on one Mac port (only) with a new emacs package which compiles a loadable emacs module to interact directly with libenchant via the internal API, instead of as an external process. It's very fast. Looking at the traceback above, do you see anything obvious enchant could be doing differently?

minad commented 9 months ago

@rrthomas

It's interesting that there's a problem in Emacs here, because one reason I prefer using the Enchant front end with Emacs is precisely that it can't bring Emacs down. (I've said this before elsewhere, I think!). I wrote the Enchant support for ispell-mode; although I'm not fond of that code, that's mainly because the support for several different spelling engines complicates it, and I'd love to see a simpler version that only supports Enchant.

Yes, using Enchant as a separate process is obviously more safe. We had talked about this before. But then, there is no problem in the officially supported Emacs versions and I NEVER had a crash due to Jinx/Enchant. My initial Jinx commit was on 2023-03-24 and I basically have Jinx enabled globally in every text/prog buffer since then. Also no reports on the Jinx issue tracker like "I installed and activated Jinx and Emacs crashed". I think it is fair to say that Enchant is relatively solid. I don't want to miss the performance advantage of loading Enchant into the Emacs process.

(EDIT: Small correction, there was a single crash report https://github.com/minad/jinx/issues/5, soon after release of the package, but the bug has been fixed since then in Enchant and guarded against in Jinx. The function enchant_dict_get_extra_word_characters did sometimes not return UTF-8.)

jdtsmith commented 9 months ago

@minad how challenging would it be for jinx to offer the option for either a compiled module or a subprocess style via a pipe? I ask because I wonder if your optimization work to avoid checking unnecessary text might constitute the bulk of the improvement.

minad commented 9 months ago

@jdtsmith Not challenging, but not interesting for Jinx. Jinx will stick to the current design, which works well, and which is its raison d'être. If Enchant wouldn't be stable enough and would crash repeatedly, my reaction would have more likely been to drop Enchant instead of using it via a pipe, or I wouldn't even have started the development of Jinx in the first place.

For the technical reasons - you may be right that the main performance win is due to the laziness. However process filters with a lot of back and forth for checking single words have overhead since they basically fill up the event loop, introducing latency issues. If you are interested in using a separate process, I suggest you take a look at jit-spell. See also https://github.com/astoff/jit-spell/issues/9.

rrthomas commented 9 months ago

I think it is fair to say that Enchant is relatively solid.

I believe so! And I believe the same to be true of all the current fully-supported back-ends. But of course it's not true in general: Enchant will load any provider that's offered, and that in turn can rely on any spelling engine. Of course, it would be possible to distinguish "official" providers from 3rd-party code, but then there's still the potential for an update to any back-end to break. Having said that, Emacs already links directly with several libraries of which that is just as true.