Subject: bug#19229: ispell-phaf: No matching entry for ...

From: Eli Zaretskii <[email-masked]>
Date: Mon, 01 Dec 2014 18:24:21 +0200

> Date: Sun, 30 Nov 2014 22:55:17 +0100
> From: Alexander Shukaev <[email-masked]>
> Cc: [email-masked]
> 
> Thanks a lot for the tip.
> 
> I don't know what was wrong with MSYS2 version of hunspell, but this one works with the following minimal configuration:
> 
>     (setq ispell-program-name (executable-find "hunspell"))
>     (setq ispell-local-dictionary "en_US")
>     (setq ispell-local-dictionary-alist '(("en_US"
>                                            "[[:alpha:]]"
>                                            "[^[:alpha:]]"
>                                            "[']"
>                                            nil
>                                            nil
>                                            nil
>                                            utf-8)))

I think you don't need most of this, see below.

> Nevertheless, I can still see
> 
>     ispell-phaf: No matching entry for nil

I don't see it on my system.  With "emacs -Q", all I need is to
evaluate

  (setq ispell-program-name (executable-find "hunspell"))

After that, "M-x ispell-buffer RET" works as expected, and I see no
error messages about ispell-phaf in *Messages*.  Does that work for
you?

> So it still tries to call `ispell-parse-hunspell-affix-file' with `nil' for the first time, and only then calls it with "en_US" in my case.

But your above minimal configuration is not how Hunspell should be set
up with Emacs 24.4 and later.  First, it is best to set up the default
dictionary to be for the language you spellcheck the most.  If that's
US English, then just copy en_US.* files to the corresponding
default.* files, and that's it.

If the default dictionary is not what you want, you should only need
this one additional line to switch globally to another one:

  (ispell-change-dictionary "en_US" t)

(Of course, "en_US" can be replaced with any other language.)  With
this one line in addition to setting ispell-program-name I get a
working spelling in US English, and no error messages in "emacs -Q".
Does this work for you?

> Secondly, I think that relying on "hunspell -D" so stubbornly that `ispell-parse-hunspell-affix-file' blocks all further usage of ispell.el with hunspell if `ispell-hunspell-dict-paths-alist' is just dumb.

I don't think so.  The code in ispell.el that queries the speller
about the available dictionaries is IMO a very useful feature because
asking the speller about dictionaries is the most reliable way of
detecting which ones are available and what languages/encodings they
support.  Without that, Emacs must rely on the user to manually set up
ispell-local-dictionary-alist, which is error prone and cumbersome
(e.g., how do you tell which dictionary needs what encoding?).

With the original Ispell program, ispell-local-dictionary-alist was a
must, but modern spellers, like aspell and hunspell, can be queried
about the dictionaries, which makes your ispell-local-dictionary-alist
customization above entirely unnecessary.

>     Not all distributions of hunspell even supply "share/hunspell/*" stuff with them;

Then those distributions are simply broken: Hunspell isn't worth
anything without at least one dictionary.  It's OK to provide
dictionaries in a separate archive, but not having them around at all
is bad news for Windows users who download Hunspell, because finding
these dictionaries and figuring out how to install the various RPMs
you find out there is not for the faint at heart.

>     Some users don't use dictionaries from "share/hunspell/*" because they might get either more updated dictionaries themselves and/or already have customized personal dictionaries.

If the dictionaries are installed in a location different from the
default share/hunspell/ directory, the user should set the DICPATH
environment variable to point to the directories with the
dictionaries, and "hunspell -D" will still report them.  See "man
hunspell" for more details.

> For instance, #2 is exactly what I was planning to do:
>
>       (let ((dictionaries-dir (expand-file-name "dictionaries"
>                                                 user-emacs-directory)))
>         (make-directory dictionaries-dir t)
>         (setq ispell-local-dictionary "en_US")
>         (setq ispell-local-dictionary-alist '((nil
>                                                "[[:alpha:]]"
>                                                "[^[:alpha:]]"
>                                                "[']"
>                                                nil
>                                                ("-d" "en_US"
>                                                 "-p" dictionaries-dir)
>                                                nil
>                                                utf-8)
>                                               ("en_US"
>                                                "[[:alpha:]]"
>                                                "[^[:alpha:]]"
>                                                "[']"
>                                                nil
>                                                ("-d" "en_US"
>                                                 "-p" dictionaries-dir)
>                                                nil
>                                                utf-8)
>                                               ("german"
>                                                "[[:alpha:]]"
>                                                "[^[:alpha:]]"
>                                                "[']"
>                                                t
>                                                ("-d" "de_DE_frami"
>                                                 "-p" dictionaries-dir)
>                                                "~tex"
>                                                utf-8)
>                                               ("russian"
>                                                "[[:alpha:]]"
>                                                "[^[:alpha:]]"
>                                                "[']"
>                                                nil
>                                                ("-d" "ru_RU"
>                                                 "-p" dictionaries-dir)
>                                                nil
>                                                utf-8)))))
>
>
> and in this case I obviously don't care at all whether hunspell has anything in "share/hunspell/*" or not. So why would I be forcefully blocked to use it with some weird error from `ispell-parse-hunspell-affix-file'?

I don't see why you would need such an elaborate manual setup.  (Btw,
the -p switch is not for telling Hunspell where to find the
dictionaries, it's for telling it where are your _personal_
dictionaries.)  You are reinventing the wheel, fighting an uphill
battle against Hunspell and ispell.el while at that, and then complain
that it's hard.  Just set DICPATH in the environment and be done, it's
much simpler.  Play by the rules, and everything should "just work"
(barring bugs).

IOW, ispell.el's handling of Hunspell is based on the assumption that
the user has a working Hunspell installation with dictionaries that
the speller can find without any fancy command-line switches.  I think
this is a sound assumption, and it does work for everyone else.  It
will work for you as well, if you just install and configure Hunspell
properly, see above.

You can still tweak the installation and setup, of course -- this is
Emacs! -- but at least for your particular setup it's unneeded,
AFAICT; the defaults should work just fine.

> How about redesign?

Do you still think it's needed?