Tuesday, September 20, 2016

Emacs 25.1 & hunspell

In Emacs 25 you don't ever need to modify ispell-dictionary-alist variable explicitly. Ispell package reads, during its initialization, the hunspell's .aff files & automatically fills the variable w/ parsed values.

If you have at least hunspell + hunspell-en-US dictionary installed, the minimum configuration, that works regardless of the underlying OS is:

(setenv "LANG" "en_US.UTF-8")
(setq ispell-program-name "hunspell")
(setq ispell-dictionary "en_US")

hunspell cuts out en_US part from LANG env variable and uses it as a default dictionary. To check it outside of Emacs, run:

$ hunspell -D

If it says

LOADED DICTIONARY:
/usr/share/myspell/en_US.aff
/usr/share/myspell/en_US.dic

& waits for the user input from the stdin, then perhaps hunspell was configured properly.

ispell-dictionary on the other hand, is an Ispell-only setting. It uses it to start a hunspell session.

Iff the Ispell package has been initialized correctly, ispell-hunspell-dict-paths-alist variable should contain pairs like

("american" "/usr/share/myspell/en_US.aff")
("british" "/usr/share/myspell/en_GB.aff")

& ispell-dictionary-alist--the parsed values from the corresponding .aff files.

If ispell-hunspell-dict-paths-alist is nil, that means Ispell is either has failed to parse the output of a `hunspell -D` invocation or has failed to read the .aff files. The latter could occur if you use a native Windows version of Emacs w/ hunspell from Cygwin. If that is the case, you can always set the pairs manually:

(setq ispell-program-name "c:/cygwin64/bin/hunspell.exe")
(setq ispell-hunspell-dict-paths-alist
      '(("en_US" "C:/cygwin64/usr/share/myspell/en_US.aff")
        ("ru_RU" "C:/cygwin64/usr/share/myspell/ru_RU.aff")
        ("uk_UA" "C:/cygwin64/usr/share/myspell/uk_UA.aff")
        ("en_GB" "C:/cygwin64/usr/share/myspell/en_GB.aff")))

You'll need to restart Emacs after that.

The Apostrophe

If you can, try up update the hunspell dictionaries alongside the spell checker itself. The old versions lack the proper WORDCHARS setting inside the .aff files which results in wrong results (haha) for words that contain the ' sign. For example, if your dictionaries are up to date, the word isn't must not confuse the spell checker:

$ echo isn\'t | hunspell
Hunspell 1.3.3
*

If you get this instead:

$ echo isn\'t | hunspell
Hunspell 1.3.3
& isn 9 0: sin, ins, ism, is, in, inn, ion, isl, is n
*

the dictionaries are no good & no Emacs will fix that.

Switching Dictionaries On The Fly

If you find yourself switching dictionaries depending on the Emacs input mode, use the Mule hooks to set the right dictionary automatically:

(setq ispell-dictionary "en_GB")

(defun my-hunspell-hook()
  "Set a local hunspell dictionary based on the current input method."
  (setq ispell-local-dictionary
        (cond
         ((null current-input-method)
          ispell-dictionary)
         ((string-match-p "ukrainian" current-input-method)
          "uk_UA")
         ((string-match-p "russian" current-input-method)
          "ru_RU")
         (t
          (user-error "input method %s is not supported"
                      current-input-method)))
        ))

(defun my-hunspell-hook-reset()
  (setq ispell-local-dictionary ispell-dictionary))

(add-hook 'input-method-activate-hook 'my-hunspell-hook)
(add-hook 'input-method-deactivate-hook 'my-hunspell-hook-reset)

No comments:

Post a Comment