Subject: Re: bug#25830: 25.2; ispell doesn't parse hunspell dictionaries properly

From: Eli Zaretskii <[email-masked]>
Date: Mon, 27 Feb 2017 17:54:44 +0200

> Date: Sat, 25 Feb 2017 13:15:23 +0100
> From: Martin Kletzander <[email-masked]>
> Cc: [email-masked]
> 
> >Thanks.  I'll look into invoking ispell-hunspell-add-multi-dic
> >automatically when we find more than one dictionary loaded by
> >Hunspell, as it reports when invoked with the -D option.
> 
> Thank you.  Feel free too Cc me on any patch for that, I'll gladly test
> it out (and learn more about the underlying code).

Please try the patch below.  (If it doesn't apply to your version of
ispell.el, tell me which version of Emacs you have, and I will try to
produce a compatible patch.)

TIA

--- lisp/textmodes/ispell.el~0	2017-01-08 06:23:52.000000000 +0200
+++ lisp/textmodes/ispell.el	2017-02-27 17:42:50.340586100 +0200
@@ -829,6 +829,15 @@
 				   (fboundp 'accept-process-output))
   "Non-nil means that the OS supports asynchronous processes.")
 
+(defvar ispell-current-dictionary nil
+  "The name of the current dictionary, or nil for the default.
+This is passed to the Ispell process using the `-d' switch and is
+used as key in `ispell-local-dictionary-alist' and `ispell-dictionary-alist'.")
+
+(defvar ispell-current-personal-dictionary nil
+  "The name of the current personal dictionary, or nil for the default.
+This is passed to the Ispell process using the `-p' switch.")
+
 ;; Make ispell.el work better with aspell.
 
 (defvar ispell-aspell-dictionary-alist nil
@@ -1087,6 +1096,7 @@
       (ispell-find-hunspell-dictionaries)
       (setq ispell-dictionary-alist ispell-hunspell-dictionary-alist))
     (or (assoc first-dict ispell-local-dictionary-alist)
+        (assoc first-dict ispell-hunspell-dictionary-alist)
         (assoc first-dict ispell-dictionary-alist)
         (error "Unknown dictionary: %s" first-dict)))
   (cl-pushnew (list dict '()) ispell-dictionary-alist :test #'equal)
@@ -1110,18 +1120,25 @@
 	  "[\n\r]+"
 	  t))
 	hunspell-default-dict
-	hunspell-default-dict-entry)
+	hunspell-default-dict-entry
+        hunspell-multi-dict)
     (dolist (dict hunspell-found-dicts)
       (let* ((full-name (file-name-nondirectory dict))
 	     (basename  (file-name-sans-extension full-name))
 	     (affix-file (concat dict ".aff")))
 	(if (string-match "\\.aff$" dict)
 	    ;; Found default dictionary
-	    (if hunspell-default-dict
-		(error "ispell-fhd: Default dict already defined as %s.  Not using %s.\n"
-		       hunspell-default-dict dict)
-	      (setq affix-file dict)
-	      (setq hunspell-default-dict (list basename affix-file)))
+            (progn
+              (if hunspell-default-dict
+                  (setq hunspell-multi-dict
+                        (concat (or hunspell-multi-dict
+                                    (car hunspell-default-dict))
+                                "," basename))
+                (setq affix-file dict)
+                (setq hunspell-default-dict (list basename affix-file)))
+              (ispell-print-if-debug
+               "++ ispell-fhd: default dict-entry:%s name:%s basename:%s\n"
+               dict full-name basename))
 	  (if (and (not (assoc basename ispell-hunspell-dict-paths-alist))
 		   (file-exists-p affix-file))
 	      ;; Entry has an associated .aff file and no previous value.
@@ -1171,7 +1188,12 @@
       (cl-pushnew (if (string= dict hunspell-default-dict)
                       hunspell-default-dict-entry
                     (list dict))
-                  ispell-hunspell-dictionary-alist :test #'equal))))
+                  ispell-hunspell-dictionary-alist :test #'equal))
+    ;; If we found more than one loaded dictionary, set up for using
+    ;; multiple dictionaries.
+    (when hunspell-multi-dict
+      (ispell-hunspell-add-multi-dic hunspell-multi-dict)
+      (setq ispell-current-dictionary hunspell-multi-dict))))
 
 ;; Set params according to the selected spellchecker
 
@@ -1416,15 +1438,6 @@
 
 ;;; **********************************************************************
 
-(defvar ispell-current-dictionary nil
-  "The name of the current dictionary, or nil for the default.
-This is passed to the Ispell process using the `-d' switch and is
-used as key in `ispell-local-dictionary-alist' and `ispell-dictionary-alist'.")
-
-(defvar ispell-current-personal-dictionary nil
-  "The name of the current personal dictionary, or nil for the default.
-This is passed to the Ispell process using the `-p' switch.")
-
 (defun ispell-decode-string (str)
   "Decodes multibyte character strings."
   (decode-coding-string str (ispell-get-coding-system)))