aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2005-08-09 14:12:44 +0000
committerRichard M. Stallman2005-08-09 14:12:44 +0000
commite7cdb3e043eeec251bc504b368900b5797c49910 (patch)
treec5b53d3794f67fd85098419764941893320afe25
parent8ad8316c3eb56952e12b682b6cedce95210a8da1 (diff)
downloademacs-e7cdb3e043eeec251bc504b368900b5797c49910.tar.gz
emacs-e7cdb3e043eeec251bc504b368900b5797c49910.zip
(ispell-word): More fboundp checks.
(ispell-find-aspell-dictionaries): New command. (ispell-have-aspell-dictionaries): New variable. (ispell-aspell-data-dir, ispell-aspell-dict-dir): New variables. (ispell-get-aspell-config-value): New function. (ispell-aspell-find-dictionary): New function. (ispell-aspell-add-aliases): New function. (ispell-valid-dictionary-list): Call ispell-find-aspell-dictionaries if appropriate. Don't look for ispell dictionaries if we use aspell. (ispell-menu-map): Don't build a submenu of dictionaries.
-rw-r--r--lisp/ChangeLog21
-rw-r--r--lisp/textmodes/ispell.el148
2 files changed, 128 insertions, 41 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 817bee01c17..5ddf15cceda 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -12,6 +12,8 @@
12 12
132005-08-09 Richard M. Stallman <rms@gnu.org> 132005-08-09 Richard M. Stallman <rms@gnu.org>
14 14
15 * textmodes/ispell.el (ispell-word): More fboundp checks.
16
15 * files.el (find-file-noselect): Don't call set-buffer-major-mode. 17 * files.el (find-file-noselect): Don't call set-buffer-major-mode.
16 (find-file-noselect-1): Call it here, only if RAWFILE. 18 (find-file-noselect-1): Call it here, only if RAWFILE.
17 (normal-mode): Always set some major mode. 19 (normal-mode): Always set some major mode.
@@ -20,15 +22,16 @@
20 22
212005-08-09 Magnus Henoch <mange@freemail.hu> 232005-08-09 Magnus Henoch <mange@freemail.hu>
22 24
23 * textmodes/ispell.el (aspell-have-dictionaries): New variable. 25 * textmodes/ispell.el (ispell-find-aspell-dictionaries): New command.
24 (aspell-find-dictionaries): New command. 26 (ispell-have-aspell-dictionaries): New variable.
25 (aspell-data-dir): New variable. 27 (ispell-aspell-data-dir, ispell-aspell-dict-dir): New variables.
26 (aspell-find-data-dir): New function. 28 (ispell-get-aspell-config-value): New function.
27 (aspell-find-dictionary): New function. 29 (ispell-aspell-find-dictionary): New function.
28 (ispell-valid-dictionary-list): Call aspell-find-dictionaries if 30 (ispell-aspell-add-aliases): New function.
29 appropriate. Don't look for ispell dictionaries if we use 31 (ispell-valid-dictionary-list): Call ispell-find-aspell-dictionaries if
30 aspell. 32 appropriate. Don't look for ispell dictionaries if we use aspell.
31 33 (ispell-menu-map): Don't build a submenu of dictionaries.
34
322005-08-09 Richard M. Stallman <rms@gnu.org> 352005-08-09 Richard M. Stallman <rms@gnu.org>
33 36
34 * progmodes/sql.el (sql-interactive-mode-map): Use fboundp. 37 * progmodes/sql.el (sql-interactive-mode-map): Use fboundp.
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index a0a0ca20218..5afdf63ff2a 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -862,9 +862,113 @@ and added as a submenu of the \"Edit\" menu.")
862 ) 862 )
863 "Non-nil means that the OS supports asynchronous processes.") 863 "Non-nil means that the OS supports asynchronous processes.")
864 864
865;; Make ispell.el work better with aspell.
866
867(defvar ispell-have-aspell-dictionaries nil
868 "Non-nil if we have queried Aspell for dictionaries at least once.")
869
870(defun ispell-find-aspell-dictionaries ()
871 "Find Aspell's dictionaries, and record in `ispell-dictionary-alist'."
872 (interactive)
873 (unless ispell-really-aspell
874 (error "This function only works with aspell"))
875 (let ((dictionaries
876 (split-string
877 (with-temp-buffer
878 (call-process ispell-program-name nil t nil "dicts")
879 (buffer-string)))))
880 (setq ispell-dictionary-alist
881 (mapcar #'ispell-aspell-find-dictionary dictionaries))
882 (ispell-aspell-add-aliases)
883 ;; Add a default entry
884 (let* ((english-dict (assoc "en" ispell-dictionary-alist))
885 (default-dict (cons nil (cdr english-dict))))
886 (push default-dict ispell-dictionary-alist))
887 (setq ispell-have-aspell-dictionaries t)))
888
889(defvar ispell-aspell-data-dir nil
890 "Data directory of Aspell.")
891
892(defvar ispell-aspell-dict-dir nil
893 "Dictionary directory of Aspell.")
894
895(defun ispell-get-aspell-config-value (key)
896 "Return value of Aspell configuration option KEY.
897Assumes that value contains no whitespace."
898 (with-temp-buffer
899 (call-process ispell-program-name nil t nil "config" key)
900 (car (split-string (buffer-string)))))
901
902(defun ispell-aspell-find-dictionary (dict-name)
903 (let* ((lang ;; Strip out region, variant, etc.
904 (and (string-match "^[[:alpha:]]+" dict-name)
905 (match-string 0 dict-name)))
906 (data-file
907 (concat (or ispell-aspell-data-dir
908 (setq ispell-aspell-data-dir
909 (ispell-get-aspell-config-value "data-dir")))
910 "/" lang ".dat"))
911 otherchars)
912 ;; This file really should exist; there is no sensible recovery.
913 (with-temp-buffer
914 (insert-file-contents data-file)
915 ;; There is zero or one line with special characters declarations.
916 (when (search-forward-regexp "^special" nil t)
917 (let ((specials (split-string
918 (buffer-substring (point)
919 (progn (end-of-line) (point))))))
920 ;; The line looks like: special ' -** - -** . -** : -*-
921 ;; -** means that this character
922 ;; - doesn't appear at word start
923 ;; * may appear in the middle of a word
924 ;; * may appear at word end
925 ;; `otherchars' is about the middle case.
926 (while specials
927 (when (eq (aref (cadr specials) 1) ?*)
928 (push (car specials) otherchars))
929 (setq specials (cddr specials))))))
930 (list dict-name
931 "[[:alpha:]]"
932 "[^[:alpha:]]"
933 (regexp-opt otherchars)
934 t ; We can't tell, so set this to t
935 (list "-d" dict-name "--encoding=utf-8")
936 nil ; aspell doesn't support this
937 ;; Here we specify the encoding to use while communicating with
938 ;; aspell. This doesn't apply to command line arguments, so
939 ;; just don't pass words to spellcheck as arguments...
940 'utf-8)))
941
942(defun ispell-aspell-add-aliases ()
943 "Find aspell's dictionary aliases and add them to `ispell-dictionary-alist'."
944 (let ((aliases (file-expand-wildcards
945 (concat (or ispell-aspell-dict-dir
946 (setq ispell-aspell-dict-dir
947 (ispell-get-aspell-config-value "dict-dir")))
948 "/*.alias"))))
949 (dolist (alias-file aliases)
950 (with-temp-buffer
951 (insert-file-contents alias-file)
952 ;; Look for a line "add FOO.multi", extract FOO
953 (when (search-forward-regexp "^add \\([^.]+\\)\\.multi" nil t)
954 (let* ((aliasname (file-name-sans-extension
955 (file-name-nondirectory alias-file)))
956 (already-exists-p (assoc aliasname ispell-dictionary-alist))
957 (realname (match-string 1))
958 (realdict (assoc realname ispell-dictionary-alist)))
959 (when (and realdict (not already-exists-p))
960 (push (cons aliasname (cdr realdict)) ispell-dictionary-alist))))))))
961
865(defun ispell-valid-dictionary-list () 962(defun ispell-valid-dictionary-list ()
866 "Returns a list of valid dictionaries. 963 "Returns a list of valid dictionaries.
867The variable `ispell-library-directory' defines the library location." 964The variable `ispell-library-directory' defines the library location."
965 ;; If Ispell is really Aspell, query it for the dictionary list.
966 (when (and (not ispell-have-aspell-dictionaries)
967 (condition-case ()
968 (progn (ispell-check-version) t)
969 (error nil))
970 ispell-really-aspell)
971 (ispell-find-aspell-dictionaries))
868 (let ((dicts (append ispell-local-dictionary-alist ispell-dictionary-alist)) 972 (let ((dicts (append ispell-local-dictionary-alist ispell-dictionary-alist))
869 (dict-list (cons "default" nil)) 973 (dict-list (cons "default" nil))
870 name load-dict) 974 name load-dict)
@@ -875,7 +979,9 @@ The variable `ispell-library-directory' defines the library location."
875 (if (and 979 (if (and
876 name 980 name
877 ;; include all dictionaries if lib directory not known. 981 ;; include all dictionaries if lib directory not known.
878 (or (not ispell-library-directory) 982 ;; For Aspell, we already know which dictionaries exist.
983 (or ispell-really-aspell
984 (not ispell-library-directory)
879 (file-exists-p (concat ispell-library-directory 985 (file-exists-p (concat ispell-library-directory
880 "/" name ".hash")) 986 "/" name ".hash"))
881 (file-exists-p (concat ispell-library-directory "/" name ".has")) 987 (file-exists-p (concat ispell-library-directory "/" name ".has"))
@@ -887,36 +993,11 @@ The variable `ispell-library-directory' defines the library location."
887 (setq dict-list (cons name dict-list)))) 993 (setq dict-list (cons name dict-list))))
888 dict-list)) 994 dict-list))
889 995
890;;;###autoload
891(if ispell-menu-map-needed
892 (let ((dicts (if (fboundp 'ispell-valid-dictionary-list)
893 (ispell-valid-dictionary-list)
894 ;; This case is used in loaddefs.el
895 ;; since ispell-valid-dictionary-list isn't defined then.
896 (mapcar (lambda (x) (or (car x) "default"))
897 ispell-dictionary-alist)))
898 (dict-map (make-sparse-keymap "Dictionaries")))
899 (setq ispell-menu-map (make-sparse-keymap "Spell"))
900 ;; add the dictionaries to the bottom of the list.
901 (if (not dicts)
902 (define-key ispell-menu-map [default]
903 '("Select Default Dict"
904 "Dictionary for which Ispell was configured"
905 . (lambda () (interactive)
906 (ispell-change-dictionary "default")))))
907 (fset 'ispell-dict-map dict-map)
908 (define-key ispell-menu-map [dictionaries]
909 `(menu-item "Select Dict" ispell-dict-map))
910 (dolist (name dicts)
911 (define-key dict-map (vector (intern name))
912 (cons (concat "Select " (capitalize name) " Dict")
913 `(lambda () (interactive)
914 (ispell-change-dictionary ,name)))))))
915
916;;; define commands in menu in opposite order you want them to appear. 996;;; define commands in menu in opposite order you want them to appear.
917;;;###autoload 997;;;###autoload
918(if ispell-menu-map-needed 998(if ispell-menu-map-needed
919 (progn 999 (progn
1000 (setq ispell-menu-map (make-sparse-keymap "Spell"))
920 (define-key ispell-menu-map [ispell-change-dictionary] 1001 (define-key ispell-menu-map [ispell-change-dictionary]
921 '(menu-item "Change Dictionary..." ispell-change-dictionary 1002 '(menu-item "Change Dictionary..." ispell-change-dictionary
922 :help "Supply explicit dictionary file name")) 1003 :help "Supply explicit dictionary file name"))
@@ -1491,7 +1572,8 @@ quit spell session exited."
1491 (funcall ispell-format-word word))) 1572 (funcall ispell-format-word word)))
1492 (and (fboundp 'extent-at) 1573 (and (fboundp 'extent-at)
1493 (extent-at start) 1574 (extent-at start)
1494 (delete-extent (extent-at start)))) 1575 (and (fboundp 'delete-extent)
1576 (delete-extent (extent-at start)))))
1495 ((stringp poss) 1577 ((stringp poss)
1496 (or quietly 1578 (or quietly
1497 (message "%s is correct because of root %s" 1579 (message "%s is correct because of root %s"
@@ -1499,13 +1581,15 @@ quit spell session exited."
1499 (funcall ispell-format-word poss))) 1581 (funcall ispell-format-word poss)))
1500 (and (fboundp 'extent-at) 1582 (and (fboundp 'extent-at)
1501 (extent-at start) 1583 (extent-at start)
1502 (delete-extent (extent-at start)))) 1584 (and (fboundp 'delete-extent)
1585 (delete-extent (extent-at start)))))
1503 ((null poss) (message "Error in ispell process")) 1586 ((null poss) (message "Error in ispell process"))
1504 (ispell-check-only ; called from ispell minor mode. 1587 (ispell-check-only ; called from ispell minor mode.
1505 (if (fboundp 'make-extent) 1588 (if (fboundp 'make-extent)
1506 (let ((ext (make-extent start end))) 1589 (if (fboundp 'set-extent-property)
1507 (set-extent-property ext 'face ispell-highlight-face) 1590 (let ((ext (make-extent start end)))
1508 (set-extent-property ext 'priority 2000)) 1591 (set-extent-property ext 'face ispell-highlight-face)
1592 (set-extent-property ext 'priority 2000)))
1509 (beep) 1593 (beep)
1510 (message "%s is incorrect"(funcall ispell-format-word word)))) 1594 (message "%s is incorrect"(funcall ispell-format-word word))))
1511 (t ; prompt for correct word. 1595 (t ; prompt for correct word.