[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ispell.el doesn't find all of aspell's dictionaries

From: Magnus Henoch
Subject: Re: ispell.el doesn't find all of aspell's dictionaries
Date: Tue, 28 Jun 2005 15:12:31 +0200
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/22.0.50 (berkeley-unix)

"Richard M. Stallman" <address@hidden> writes:

>     * Some code passes a word to spellcheck on the command line, as
>       opposed to through stdin.  (aspell will interpret it according to
>       the current locale.)  I haven't checked for this thoroughly.
> Magnus, if you could do that...

I've done that now.  There are no places which need changing.

Here is my proposed patch to ispell.el.  I have placed a call to
aspell-find-dictionaries in ispell-valid-dictionary-list, protected by
a flag so it only looks for aspell's dictionaries once in a session.
This makes ispell-change-dictionary work as expected.  If new
dictionaries are installed during an emacs session, the user needs to
call aspell-find-dictionaries manually.

There is one problem with this code: the dictionary list in the menu
bar is only updated when ispell.el is loaded (probably due to a call 
to an auto-loaded function).  So before any ispell-* command is run,
the menu shows the static list of ispell dictionaries, and if new
dictionaries are added, the menu is not updated.  I'm not sure what
can/should be done about that.

2005-06-28  Magnus Henoch  <address@hidden>

        * textmodes/ispell.el (aspell-have-dictionaries): New variable.  
        (aspell-find-dictionaries): New command.
        (aspell-data-dir): New variable.
        (aspell-find-data-dir): New function.
        (aspell-find-dictionary): New function.
        (ispell-valid-dictionary-list): Call aspell-find-dictionaries if
        appropriate.  Don't look for ispell dictionaries if we use

*** orig/lisp/textmodes/ispell.el
--- mod/lisp/textmodes/ispell.el
*** 862,870 ****
--- 862,949 ----
    "Non-nil means that the OS supports asynchronous processes.")
+ ;; Make ispell.el work better with aspell.
+ (defvar aspell-have-dictionaries nil
+   "Non-nil if we have queried aspell for dictionaries at least once.")
+ (defun aspell-find-dictonaries ()
+   "Find aspell's dictionaries, and record into `ispell-dictionary-alist'."
+   (interactive)
+   (unless ispell-really-aspell
+     (error "This function only works with aspell."))
+   (let ((dictionaries
+        (split-string
+         (with-temp-buffer
+           (call-process ispell-program-name nil t nil "dicts")
+           (buffer-string)))))
+     (setq ispell-dictionary-alist
+         (mapcar #'aspell-find-dictionary dictionaries))
+     ;; Add a default entry
+     (let* ((english-dict (assoc "en" ispell-dictionary-alist))
+          (default-dict (cons nil (cdr english-dict))))
+       (push default-dict ispell-dictionary-alist))
+     (setq aspell-have-dictionaries t)))
+ (defvar aspell-data-dir nil
+   "Data directory of aspell.")
+ (defun aspell-find-data-dir ()
+   "Find aspell's data directory and set `aspell-data-dir'.
+ Return aspell-data-dir."
+   (setq aspell-data-dir (with-temp-buffer
+                         (call-process ispell-program-name nil t nil "config" 
+                         ;; Is there a better way to trim surrounding 
+                         (car (split-string (buffer-string))))))
+ (defun aspell-find-dictionary (dict-name)
+   (let* ((lang ;; Strip out region, variant, etc.
+         (and (string-match "^[[:alpha:]]+" dict-name)
+              (match-string 0 dict-name)))
+        (data-file
+         (concat (or aspell-data-dir (aspell-find-data-dir))
+                 "/" lang ".dat"))
+        otherchars)
+     ;; This file really should exist; there is no sensible recovery.
+     (with-temp-buffer
+       (insert-file-contents data-file)
+       ;; There is zero or one line with special characters declarations.
+       (when (search-forward-regexp "^special" nil t)
+       (let ((specials (split-string 
+                        (buffer-substring (point)
+                                          (progn (end-of-line) (point))))))
+         ;; The line looks like: special ' -** - -** . -** : -*-
+         ;; -** means that this character
+         ;;    - doesn't appear at word start
+         ;;    * may appear in the middle of a word
+         ;;    * may appear at word end
+         ;; `otherchars' is about the middle case.
+         (while specials
+           (when (eq (aref (cadr specials) 1) ?*)
+             (push (car specials) otherchars))
+           (setq specials (cddr specials))))))
+     (list dict-name
+         "[[:alpha:]]"
+         "[^[:alpha:]]"
+         (regexp-opt otherchars)
+         t                             ; We can't tell, so set this to t
+         (list "-d" dict-name "--encoding=utf-8")
+         nil                           ; aspell doesn't support this
+         ;; Here we specify the encoding to use while communicating with
+         ;; aspell.  This doesn't apply to command line arguments, so
+         ;; just don't pass words to spellcheck as arguments...
+         'utf-8)))
  (defun ispell-valid-dictionary-list ()
    "Returns a list of valid dictionaries.
  The variable `ispell-library-directory' defines the library location."
+   ;; If Ispell is really Aspell, query it for the dictionary list.
+   (when (and (not aspell-have-dictionaries)
+            (condition-case ()
+                (progn (ispell-check-version) t)
+              (error nil))
+            ispell-really-aspell)
+     (aspell-find-dictonaries))
    (let ((dicts (append ispell-local-dictionary-alist ispell-dictionary-alist))
        (dict-list (cons "default" nil))
        name load-dict)
*** 875,881 ****
        (if (and
           ;; include all dictionaries if lib directory not known.
!          (or (not ispell-library-directory)
               (file-exists-p (concat ispell-library-directory
                                      "/" name ".hash"))
               (file-exists-p (concat ispell-library-directory "/" name ".has"))
--- 954,962 ----
        (if (and
           ;; include all dictionaries if lib directory not known.
!          ;; For Aspell, we already know which dictionaries exist.
!          (or ispell-really-aspell
!              (not ispell-library-directory)
               (file-exists-p (concat ispell-library-directory
                                      "/" name ".hash"))
               (file-exists-p (concat ispell-library-directory "/" name ".has"))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]