"Richard M. Stallman" <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> * 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 aspell. *** 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" "data-dir") + ;; Is there a better way to trim surrounding whitespace? + (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 name ;; 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 name ;; 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")) _______________________________________________ Emacs-pretest-bug mailing list Emacs-pretest-bug@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug