diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2003-05-13 22:52:20 +0000 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2003-05-13 22:52:20 +0000 |
commit | e8733492114d74455e401efcab27bcb627f48b19 (patch) | |
tree | a59e03c2ebd9bd29a471b58e96c7af4683929972 /lisp/textmodes/ispell.el | |
parent | 39a561e69e2e371e10b3b5d55b158fb013f8fd7c (diff) | |
download | emacs-e8733492114d74455e401efcab27bcb627f48b19.tar.gz |
Version 3.5VENDOR-3_5
Diffstat (limited to 'lisp/textmodes/ispell.el')
-rw-r--r-- | lisp/textmodes/ispell.el | 673 |
1 files changed, 490 insertions, 183 deletions
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 9788eb18ec8..cc22053f80d 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -1,11 +1,11 @@ ;;; ispell.el --- Interface to International Ispell Versions 3.1 and 3.2 -;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. -;; Author: Ken Stevens <k.stevens@ieee.org> -;; Maintainer: <k.stevens@ieee.org> -;; Stevens Mod Date: Fri Aug 4 09:41:50 PDT 2000 -;; Stevens Revision: 3.4 +;; Author: Ken Stevens <k.stevens@ieee.org> +;; Maintainer: Ken Stevens <k.stevens@ieee.org> +;; Stevens Mod Date: Wed Jul 11 18:43:57 PDT 2001 +;; Stevens Revision: 3.5 ;; Status : Release with 3.1.12+ and 3.2.0+ ispell. ;; Bug Reports : ispell-el-bugs@itcorp.com ;; Web Site : http://kdstevens.com/~stevens/ispell-page.html @@ -129,6 +129,15 @@ ;; Modifications made in latest versions: +;; Revision 3.5 2001/7/11 18:43:57 kss +;; Added fix for aspell to work in XEmacs (check-ispell-version). +;; Added Portuguese dictionary definition. +;; New feature: MIME mail message support, Fcc support. +;; Bug fix: retain comment syntax on lines with region skipping. (TeX $ bug...) +;; Improved allocation for graphic mode lines. (Miles Bader) +;; Support -v flag for old versions of aspell. (Eli Zaretskii) +;; Clear minibuffer on ^G from ispell-help (Tak Ota) + ;; Revision 3.4 2000/8/4 09:41:50 kss ;; Support new color display functions. ;; Fixed misalignment offset bug when replacing a string after a shift made. @@ -137,7 +146,7 @@ ;; Added dictionary definition for Italian (William Deakin) ;; HTML region skipping greatly improved. (Chuck D. Phillips) ;; improved menus. Fixed regexp matching http/email addresses. -;; one arg always for xemacs sleep-for (gunnar Evermann) +;; one arg always for XEmacs sleep-for (gunnar Evermann) ;; support for synchronous processes (Eli Zaretskii) ;; Revision 3.3 1999/11/29 11:38:34 kss @@ -214,7 +223,6 @@ (and (not version18p) (not (boundp 'epoch::version)) - (defalias 'ispell 'ispell-buffer) (defalias 'ispell-check-version 'check-ispell-version)) @@ -279,12 +287,9 @@ This minimizes redisplay thrashing." :type 'boolean :group 'ispell) -(defcustom ispell-choices-win-default-height (if xemacsp 3 2) +(defcustom ispell-choices-win-default-height 2 "*The default size of the `*Choices*' window, including mode line. -Must be greater than 1. -XEmacs modeline is thicker than a line of text, so it partially covers the -last line of text in the buffer. Include an extra line in XEmacs to see -all of the choices clearly." +Must be greater than 1." :type 'integer :group 'ispell) @@ -322,6 +327,13 @@ E.g. you may use the following value: :group 'ispell) +(defcustom ispell-message-fcc-skip 50000 + "*Query before saving Fcc message copy if attachment larger than this value. +Nil always stores Fcc copy of message." + :type '(choice integer (const :tag "off" nil)) + :group 'ispell) + + (defcustom ispell-grep-command "egrep" "Name of the grep command for search processes." :type 'string @@ -455,11 +467,15 @@ for language-specific arguments." "*Indicates whether ispell should skip spell checking of SGML markup. If t, always skip SGML markup; if nil, never skip; if non-t and non-nil, guess whether SGML markup should be skipped according to the name of the -buffer's major mode." +buffer's major mode. + +This is a local variable. To change the default value use `set-default'." :type '(choice (const :tag "always" t) (const :tag "never" nil) (const :tag "use-mode-name" use-mode-name)) :group 'ispell) +(make-variable-buffer-local 'ispell-skip-html) + ;;; Define definitions here only for personal dictionaries. ;;;###autoload @@ -586,10 +602,14 @@ See `ispell-dictionary-alist'." ("norsk7-tex" ; 7 bit Norwegian TeX mode "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1) - ("polish" ; polish mode + ("polish" ; Polish mode "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" - "" nil ( "-d" "polish") nil iso-8859-2))) + "" nil ( "-d" "polish") nil iso-8859-2) + ("portugues" ; Portuguese mode + "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" + "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" + "[']" t ("-C" "-d" "portugues") "~latin1" iso-8859-1))) ;;; Sixth part of dictionary, shortened for loaddefs.el @@ -602,13 +622,16 @@ See `ispell-dictionary-alist'." "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" "" nil ("-d" "russian") nil koi8-r) + ("slovak" ; Slovakian + "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" + "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" + "" nil ("-B" "-d" "slovak") nil iso-8859-2) ("svenska" ; Swedish mode "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" "[']" nil ("-C") "~list" iso-8859-1))) - ;;;###autoload (defcustom ispell-dictionary-alist (append ispell-local-dictionary-alist ; dictionary customizations @@ -704,9 +727,10 @@ LANGUAGE.aff file \(e.g., english.aff\)." (defvar ispell-offset -1 "Offset that maps protocol differences between ispell 3.1 versions.") -(defconst ispell-version "ispell.el 3.4 -- Fri Aug 4 09:41:50 PDT 2000") +(defconst ispell-version "ispell.el 3.5 - 07/11/01") +;;;###autoload (defun check-ispell-version (&optional interactivep) "Ensure that `ispell-program-name' is valid and the correct version. Returns version number if called interactively. @@ -726,20 +750,25 @@ Otherwise returns the library path if defined." (save-excursion (set-buffer (get-buffer-create " *ispell-tmp*")) (erase-buffer) - (setq status (call-process ispell-program-name nil t nil "-vv")) + (setq status (call-process + ispell-program-name nil t nil + ;; aspell doesn't accept the -vv switch. + (let ((case-fold-search + (memq system-type '(ms-dos windows-nt))) + (speller + (file-name-nondirectory ispell-program-name))) + ;; Assume anything that isn't `aspell' is Ispell. + (if (string-match "\\`aspell" speller) "-v" "-vv")))) (goto-char (point-min)) - (if interactivep - (progn - (end-of-line) - (setq result (concat (buffer-substring-no-properties (point-min) - (point)) - ", " - ispell-version)) - (message result)) - ;; return library path. - (re-search-forward "LIBDIR = \\\"\\([^ \t\n]*\\)\\\"" nil t) - (if (match-beginning 0) - (setq result (buffer-substring (match-beginning 1) (match-end 1))))) + (if (not interactivep) + ;; return library path. + (if (re-search-forward "LIBDIR = \\\"\\([^ \t\n]*\\)\\\"" nil t) + (setq result (buffer-substring (match-beginning 1) + (match-end 1)))) + ;; write message string to minibuffer + (end-of-line) + (message (concat (buffer-substring-no-properties (point-min) (point)) + ", " ispell-version))) (goto-char (point-min)) (if (not (memq status '(0 nil))) (error "%s exited with %s %s" ispell-program-name @@ -800,12 +829,27 @@ and added as a submenu of the \"Edit\" menu.") (not xemacsp) 'reload)) -(defvar ispell-library-path (check-ispell-version) +(defvar ispell-library-path (if (or (not (fboundp 'byte-compiling-files-p)) + (not (byte-compiling-files-p))) + (check-ispell-version)) "The directory where ispell dictionaries reside.") +(defvar ispell-process nil + "The process object for Ispell.") + +(defvar ispell-async-processp (and (fboundp 'kill-process) + (fboundp 'process-send-string) + (fboundp 'accept-process-output) + ;;(fboundp 'start-process) + ;;(fboundp 'set-process-filter) + ;;(fboundp 'process-kill-without-query) + ) + "Non-nil means that the OS supports asynchronous processes.") ;;;###autoload -(if ispell-menu-map-needed +(if (and ispell-menu-map-needed + (or (not (fboundp 'byte-compiling-files-p)) + (not (byte-compiling-files-p)))) (let ((dicts (reverse (cons (cons "default" nil) ispell-dictionary-alist))) ;; `ispell-library-path' intentionally not defined in autoload (path (and (boundp 'ispell-library-path) ispell-library-path)) @@ -837,14 +881,16 @@ and added as a submenu of the \"Edit\" menu.") ;;; define commands in menu in opposite order you want them to appear. ;;;###autoload -(if ispell-menu-map-needed +(if (and ispell-menu-map-needed + (or (not (fboundp 'byte-compiling-files-p)) + (not (byte-compiling-files-p)))) (progn (define-key ispell-menu-map [ispell-change-dictionary] '(menu-item "Change Dictionary..." ispell-change-dictionary :help "Supply explicit path to dictionary")) (define-key ispell-menu-map [ispell-kill-ispell] '(menu-item "Kill Process" ispell-kill-ispell - :enable (and ispell-process + :enable (and (boundp 'ispell-process) ispell-process (eq (ispell-process-status) 'run)) :help "Terminate Ispell subprocess")) (define-key ispell-menu-map [ispell-pdict-save] @@ -864,7 +910,9 @@ and added as a submenu of the \"Edit\" menu.") :help "Complete word fragment at cursor")))) ;;;###autoload -(if ispell-menu-map-needed +(if (and ispell-menu-map-needed + (or (not (fboundp 'byte-compiling-files-p)) + (not (byte-compiling-files-p)))) (progn (define-key ispell-menu-map [ispell-continue] '(menu-item "Continue Spell-Checking" ispell-continue @@ -880,9 +928,10 @@ and added as a submenu of the \"Edit\" menu.") '(menu-item "Spell-Check Comments" ispell-comments-and-strings :help "Spell-check only comments and strings")))) - ;;;###autoload -(if ispell-menu-map-needed +(if (and ispell-menu-map-needed + (or (not (fboundp 'byte-compiling-files-p)) + (not (byte-compiling-files-p)))) (progn (define-key ispell-menu-map [ispell-region] '(menu-item "Spell-Check Region" ispell-region @@ -897,7 +946,7 @@ and added as a submenu of the \"Edit\" menu.") ;;(put 'ispell-region 'menu-enable 'mark-active) (fset 'ispell-menu-map (symbol-value 'ispell-menu-map)))) -;;; XEmacs versions 19 & 20 +;;; XEmacs versions 19+ (if (and xemacsp (not version18p) (featurep 'menubar) @@ -946,10 +995,16 @@ and added as a submenu of the \"Edit\" menu.") (setq ispell-menu-xemacs menu) (if current-menubar (progn - (delete-menu-item '("Edit" "Spell")) ; in case already defined - (add-menu '("Edit") "Spell" ispell-menu-xemacs))))) - -;;; Allow incrementing characters as integers in XEmacs 20 + (if (car (find-menu-item current-menubar '("Cmds"))) + (progn + ;; XEmacs 21.2 + (delete-menu-item '("Cmds" "Spell-Check")) + (add-menu '("Cmds") "Spell-Check" ispell-menu-xemacs)) + ;; previous + (delete-menu-item '("Edit" "Spell")) ; in case already defined + (add-menu '("Edit") "Spell" ispell-menu-xemacs)))))) + +;;; Allow incrementing characters as integers in XEmacs 20+ (if (and xemacsp (fboundp 'int-char)) (fset 'ispell-int-char 'int-char) @@ -999,17 +1054,6 @@ Protects against bogus binding of `enable-multibyte-characters' in XEmacs." (defun ispell-get-coding-system () (nth 7 (assoc ispell-dictionary ispell-dictionary-alist))) -(defvar ispell-process nil - "The process object for Ispell.") - -(defvar ispell-async-processp (and (fboundp 'kill-process) - (fboundp 'process-send-string) - (fboundp 'accept-process-output) - ;;(fboundp 'start-process) - ;;(fboundp 'set-process-filter) - ;;(fboundp 'process-kill-without-query) - ) - "Non-nil means that the OS supports asynchronous processes.") (defvar ispell-pdict-modified-p nil "Non-nil means personal dictionary has modifications to be saved.") @@ -1044,7 +1088,8 @@ Protects against bogus binding of `enable-multibyte-characters' in XEmacs." "Marker for return point from recursive edit.") (defvar ispell-checking-message nil - "Non-nil when we're checking a mail message.") + "Non-nil when we're checking a mail message. +Used to hold MIME boundaries.") (defconst ispell-choices-buffer "*Choices*") @@ -1084,10 +1129,14 @@ The last occurring definition in the buffer will be used.") (ispell-pdict-keyword forward-line) (ispell-parsing-keyword forward-line) ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*") - ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage" . "^---* End of [Ff]orwarded [Mm]essage") + ;; assume multiline uuencoded file? "\nM.*$"? + ("^begin [0-9][0-9][0-9] [^ \t]+$" . "\nend\n") + ("^%!PS-Adobe-[123].0" . "\n%%EOF\n") + ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage" + . "^---* End of [Ff]orwarded [Mm]essage") ;; Matches e-mail addresses, file names, http addresses, etc. The `-+' ;; pattern necessary for performance reasons when `-' part of word syntax. - ("\\(-+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+\\)") + ("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)") ;; This is a pretty complex regexp. It can be simplified to the following: ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+" ;; but some valid text will be skipped, e.g. "his/her". This could be @@ -1118,13 +1167,13 @@ Valid forms include: ;;("\\\\author" ispell-tex-arg-end) ("\\\\bibliographystyle" ispell-tex-arg-end) ("\\\\makebox" ispell-tex-arg-end 0) - ;;("\\\\epsfig" ispell-tex-arg-end) + ("\\\\e?psfig" ispell-tex-arg-end) ("\\\\document\\(class\\|style\\)" . "\\\\begin[ \t\n]*{[ \t\n]*document[ \t\n]*}")) (;; delimited with \begin. In ispell: displaymath, eqnarray, eqnarray*, ;; equation, minipage, picture, tabular, tabular* (ispell) - ("\\(figure\\|table\\)\\*?" ispell-tex-arg-end 0) - ("list" ispell-tex-arg-end 2) + ("\\(figure\\|table\\)\\*?" ispell-tex-arg-end 0) + ("list" ispell-tex-arg-end 2) ("program" . "\\\\end[ \t\n]*{[ \t\n]*program[ \t\n]*}") ("verbatim\\*?" . "\\\\end[ \t\n]*{[ \t\n]*verbatim\\*?[ \t\n]*}"))) "*Lists of regions to be skipped in TeX mode. @@ -1135,6 +1184,22 @@ Delete or add any regions you want to be automatically selected for skipping in latex mode.") +;;;###autoload +(defvar ispell-html-skip-alists + '(("<[cC][oO][dD][eE]\\>[^>]*>" "</[cC][oO][dD][eE]*>") + ("<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "</[sS][cC][rR][iI][pP][tT]>") + ("<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "</[aA][pP][pP][lL][eE][tT]>") + ("<[vV][eE][rR][bB]\\>[^>]*>" "<[vV][eE][rR][bB]\\>[^>]*>") + ;;("<[tT][tT]\\>[^>]*>" "<[tT][tT]\\>[^>]*>") + ("<[tT][tT]/" "/") + ("<[^ \t\n>]" ">") + ("&[^ \t\n;]" "[; \t\n]")) + "*Lists of start and end keys to skip in HTML buffers. +Same format as `ispell-skip-region-alist' +Note - substrings of other matches must come last + (e.g. \"<[tT][tT]/\" and \"<[^ \t\n>]\").") + + (defvar ispell-local-pdict ispell-personal-dictionary "A buffer local variable containing the current personal dictionary. If non-nil, the value must be a string, which is a file name. @@ -1167,6 +1232,20 @@ You can set this variable in hooks in your init file -- eg: (defvar ispell-check-only nil "If non-nil, `ispell-word' does not try to correct the word.") +(defconst ispell-graphic-p + (if (fboundp 'display-graphic-p) + (display-graphic-p) + xemacsp) + "True if running on a `graphics capable' display. +These displays have thicker mode lines that can partially cover text.") + +(if (fboundp 'mode-line-window-height-fudge) + (defalias 'ispell-mode-line-window-height-fudge + 'mode-line-window-height-fudge) + (defun ispell-mode-line-window-height-fudge () + "Return 1 if running on a `graphics capable' display, otherwise 0." + (if ispell-graphic-p 1 0))) + ;;; ********************************************************************** ;;; ********************************************************************** @@ -1210,7 +1289,7 @@ pass it the output of the last ispell invocation." ;; terrible kludge, and it's a bit slow, but it does get the work done.) (let ((cmd (aref string 0)) ;; The following commands are not passed to Ispell until - ;; we have a *reall* reason to invoke it. + ;; we have a *real* reason to invoke it. (cmds-to-defer '(?* ?@ ?~ ?+ ?- ?! ?%)) (default-major-mode 'fundamental-mode) (session-buf ispell-session-buffer) @@ -1225,9 +1304,8 @@ pass it the output of the last ispell invocation." (insert string) (if (not (memq cmd cmds-to-defer)) (let (coding-system-for-read coding-system-for-write status) - (if (or xemacsp - (and (boundp 'enable-multibyte-characters) - enable-multibyte-characters)) + (if (and (boundp 'enable-multibyte-characters) + enable-multibyte-characters) (setq coding-system-for-read (ispell-get-coding-system) coding-system-for-write (ispell-get-coding-system))) (set-buffer output-buf) @@ -1297,7 +1375,7 @@ This will check or reload the dictionary. Use \\[ispell-change-dictionary] or \\[ispell-region] to update the Ispell process. return values: -nil word is correct or spelling is accpeted. +nil word is correct or spelling is accepted. 0 word is inserted into buffer-local definitions. \"word\" word corrected from word list. \(\"word\" arg\) word is hand entered. @@ -1339,16 +1417,26 @@ quit spell session exited." (cond ((eq poss t) (or quietly (message "%s is correct" - (funcall ispell-format-word word)))) + (funcall ispell-format-word word))) + (and (fboundp 'extent-at) + (extent-at start) + (delete-extent (extent-at start)))) ((stringp poss) (or quietly (message "%s is correct because of root %s" (funcall ispell-format-word word) - (funcall ispell-format-word poss)))) + (funcall ispell-format-word poss))) + (and (fboundp 'extent-at) + (extent-at start) + (delete-extent (extent-at start)))) ((null poss) (message "Error in ispell process")) (ispell-check-only ; called from ispell minor mode. - (beep) - (message "%s is incorrect" (funcall ispell-format-word word))) + (if (fboundp 'make-extent) + (let ((ext (make-extent start end))) + (set-extent-property ext 'face ispell-highlight-face) + (set-extent-property ext 'priority 2000)) + (beep) + (message "%s is incorrect"(funcall ispell-format-word word)))) (t ; prompt for correct word. (save-window-excursion (setq replace (ispell-command-loop @@ -1454,7 +1542,7 @@ Word syntax described by `ispell-dictionary-alist' (which see)." ;;; a value or a list, whose value is the state of whether the ;;; dictionary needs to be saved. -;;; ###autoload +;;;###autoload (defun ispell-pdict-save (&optional no-query force-save) "Check to see if the personal dictionary has been modified. If so, ask if it needs to be saved." @@ -1470,6 +1558,14 @@ If so, ask if it needs to be saved." (setq ispell-pdict-modified-p nil)) +(defun ispell-choices-win-default-height () + "Return the default height of the `*Choices*' window for this display. +This is the value of of the variable `ispell-choices-win-default-height', +plus a possible fudge factor to work around problems with mode-lines that +obscure the last buffer line on graphics capable displays." + (+ ispell-choices-win-default-height (ispell-mode-line-window-height-fudge))) + + (defun ispell-command-loop (miss guess word start end) "Display possible corrections from list MISS. GUESS lists possibly valid affix construction of WORD. @@ -1485,11 +1581,11 @@ indicates whether the dictionary has been modified when option `a' or `i' is used. Global `ispell-quit' set to start location to continue spell session." (let ((count ?0) - (line ispell-choices-win-default-height) + (line (ispell-choices-win-default-height)) (max-lines (- (window-height) 4)) ; ensure 4 context lines. (choices miss) (window-min-height (min window-min-height - ispell-choices-win-default-height)) + (ispell-choices-win-default-height))) (command-characters '( ? ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m )) (dedicated (window-dedicated-p (selected-window))) (skipped 0) @@ -1499,9 +1595,11 @@ Global `ispell-quit' set to start location to continue spell session." (save-excursion (set-buffer (get-buffer-create ispell-choices-buffer)) (setq mode-line-format (concat "-- %b -- word: " word)) - ;; XEmacs: prevent thick modeline vs increasing height in overlay-window - ;;(and (fboundp 'set-specifier) - ;; (set-specifier has-modeline-p (cons (current-buffer) nil))) + ;; XEmacs: no need for horizontal scrollbar in choices window + (and (fboundp 'set-specifier) + (boundp 'horizontal-scrollbar-visible-p) + (set-specifier horizontal-scrollbar-visible-p nil + (cons (current-buffer) nil))) (erase-buffer) (if guess (progn @@ -1660,7 +1758,7 @@ Global `ispell-quit' set to start location to continue spell session." new-word) miss (lookup-words new-word) choices miss - line ispell-choices-win-default-height) + line (ispell-choices-win-default-height)) (while (and choices ; adjust choices window. (< (if (> (+ 7 (current-column) (length (car choices)) @@ -1762,19 +1860,19 @@ Global `ispell-quit' set to start location to continue spell session." ;; without scrolling the spelled window when possible (let ((window-line (- line (window-height choices-window))) (visible (progn (vertical-motion -1) (point)))) - (if (< line ispell-choices-win-default-height) + (if (< line (ispell-choices-win-default-height)) (setq window-line (+ window-line - (- ispell-choices-win-default-height + (- (ispell-choices-win-default-height) line)))) (move-to-window-line 0) (vertical-motion window-line) (set-window-start (selected-window) (if (> (point) visible) visible (point))) (goto-char end) - (select-window (previous-window)) ; *Choices* window + (select-window choices-window) (enlarge-window window-line))) ;; Overlay *Choices* window when it isn't showing - (ispell-overlay-window (max line ispell-choices-win-default-height))) + (ispell-overlay-window (max line (ispell-choices-win-default-height)))) (switch-to-buffer ispell-choices-buffer) (goto-char (point-min))))) @@ -1847,19 +1945,22 @@ SPC: Accept word this time. (save-window-excursion (if ispell-help-in-bufferp (progn - (ispell-overlay-window (if xemacsp 5 4)) + (ispell-overlay-window + (+ 4 (ispell-mode-line-window-height-fudge))) (switch-to-buffer (get-buffer-create "*Ispell Help*")) (insert (concat help-1 "\n" help-2 "\n" help-3)) (sit-for 5) (kill-buffer "*Ispell Help*")) - (select-window (minibuffer-window)) - (erase-buffer) - (if (not version18p) (message nil)) - ;;(set-minibuffer-window (selected-window)) - (enlarge-window 2) - (insert (concat help-1 "\n" help-2 "\n" help-3)) - (sit-for 5) - (erase-buffer)))))) + (unwind-protect + (progn + (select-window (minibuffer-window)) + (erase-buffer) + (if (not version18p) (message nil)) + ;;(set-minibuffer-window (selected-window)) + (enlarge-window 2) + (insert (concat help-1 "\n" help-2 "\n" help-3)) + (sit-for 5)) + (erase-buffer))))))) (defun lookup-words (word &optional lookup-dict) @@ -2037,7 +2138,7 @@ The variable `ispell-highlight-face' selects the face to use for highlighting." Ensure that the line above point is still visible but otherwise avoid scrolling the current window. Leave the new window selected." (save-excursion - (let ((oldot (save-excursion (forward-line -1) (point))) + (let ((oldot (save-excursion (vertical-motion -1) (point))) (top (save-excursion (move-to-window-line height) (point)))) ;; If line above old point (line starting at oldot) would be ;; hidden by new window, scroll it to just below new win @@ -2065,7 +2166,7 @@ scrolling the current window. Leave the new window selected." MISS-LIST and GUESS-LIST are possibly null lists of guesses and misses. 4: Nil when an error has occurred. -Optinal second arg ACCEPT-LIST is list of words already accepted. +Optional second arg ACCEPT-LIST is list of words already accepted. Optional third arg SHIFT is an offset to apply based on previous corrections." (cond ((string= output "") t) ; for startup with pipes... @@ -2164,8 +2265,8 @@ Keeps argument list for future ispell invocations for no async support." (ispell-kill-ispell t) (message "Starting new Ispell process...") (sit-for 0) - (check-ispell-version) - (setq ispell-process-directory default-directory + (setq ispell-library-path (check-ispell-version) + ispell-process-directory default-directory ispell-process (ispell-start-process) ispell-filter nil ispell-filter-continue nil) @@ -2254,7 +2355,7 @@ A new one will be started as soon as necessary. By just answering RET you can find out what the current dictionary is. -With prefix argument, set the default directory." +With prefix argument, set the default dictionary." (interactive (list (completing-read "Use new dictionary (RET for current, SPC to complete): " @@ -2302,6 +2403,8 @@ Return nil if spell session is quit, (interactive "r") ; Don't flag errors on read-only bufs. (if (not recheckp) (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc. + (let ((skip-region-start (make-marker)) + (rstart (make-marker))) (unwind-protect (save-excursion (message "Spell checking %s using %s dictionary..." @@ -2313,19 +2416,12 @@ Return nil if spell session is quit, (goto-char reg-start) (let ((transient-mark-mode) (case-fold-search case-fold-search) - (skip-region-start (make-marker)) - (skip-regexp (ispell-begin-skip-region-regexp)) - (skip-alist ispell-skip-region-alist) + (query-fcc t) + in-comment key) - (if (eq ispell-parser 'tex) - (setq case-fold-search nil - skip-alist - (append (car ispell-tex-skip-alists) - (car (cdr ispell-tex-skip-alists)) - skip-alist))) (let (message-log-max) (message "searching for regions to skip")) - (if (re-search-forward skip-regexp reg-end t) + (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t) (progn (setq key (buffer-substring-no-properties (match-beginning 0) (match-end 0))) @@ -2334,6 +2430,7 @@ Return nil if spell session is quit, (let (message-log-max) (message "Continuing spelling check using %s dictionary..." (or ispell-dictionary "default"))) + (set-marker rstart reg-start) (set-marker ispell-region-end reg-end) (while (and (not ispell-quit) (< (point) ispell-region-end)) @@ -2341,25 +2438,44 @@ Return nil if spell session is quit, (if (and (marker-position skip-region-start) (<= skip-region-start (point))) (progn - (ispell-skip-region key skip-alist) ; moves pt past region. - (setq reg-start (point)) - (if (and (< reg-start ispell-region-end) - (re-search-forward skip-regexp - ispell-region-end t)) + ;; If region inside line comment, must keep comment start. + (setq in-comment (point) + in-comment + (and comment-start + (or (null comment-end) (string= "" comment-end)) + (save-excursion + (beginning-of-line) + (re-search-forward comment-start in-comment t)) + comment-start)) + ;; Can change skip-regexps (in ispell-message) + (ispell-skip-region key) ; moves pt past region. + (set-marker rstart (point)) + ;; check for saving large attachments... + (setq query-fcc (and query-fcc + (ispell-ignore-fcc skip-region-start + rstart))) + (if (and (< rstart ispell-region-end) + (re-search-forward + (ispell-begin-skip-region-regexp) + ispell-region-end t)) (progn (setq key (buffer-substring-no-properties (car (match-data)) (car (cdr (match-data))))) (set-marker skip-region-start (- (point) (length key))) - (goto-char reg-start)) + (goto-char rstart)) (set-marker skip-region-start nil)))) - (setq reg-end (if (marker-position skip-region-start) - (min skip-region-start ispell-region-end) - (marker-position ispell-region-end))) + (setq reg-end (max (point) + (if (marker-position skip-region-start) + (min skip-region-start ispell-region-end) + (marker-position ispell-region-end)))) (let* ((start (point)) (end (save-excursion (end-of-line) (min (point) reg-end))) - (string (ispell-get-line start end reg-end))) + (string (ispell-get-line start end reg-end in-comment))) + (if in-comment ; account for comment chars added + (setq start (- start (length in-comment)) + in-comment nil)) (setq end (point)) ; "end" tracks region retrieved. (if string ; there is something to spell check! ;; (special start end) @@ -2373,6 +2489,8 @@ Return nil if spell session is quit, (if (and (not (and recheckp ispell-keep-choices-win)) (get-buffer ispell-choices-buffer)) (kill-buffer ispell-choices-buffer)) + (set-marker skip-region-start nil) + (set-marker rstart nil) (if ispell-quit (progn ;; preserve or clear the region for ispell-continue. @@ -2389,48 +2507,74 @@ Return nil if spell session is quit, (if (not recheckp) (set-marker ispell-region-end nil)) ;; Only save if successful exit. (ispell-pdict-save ispell-silently-savep) - (message "Spell-checking done")))) + (message "Spell-checking done"))))) -;;; Creates the regexp for skipping a region. -;;; Makes the skip-regexp local for tex buffers adding in the -;;; tex expressions to skip as well. -;;; Call AFTER ispell-buffer-local-parsing. (defun ispell-begin-skip-region-regexp () - (let ((skip-regexp (ispell-begin-skip-region))) + "Returns a regexp of the search keys for region skipping. +Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys. +Must call after ispell-buffer-local-parsing due to dependence on mode." + ;; start with regions generic to all buffers + (let ((skip-regexp (ispell-begin-skip-region ispell-skip-region-alist))) + ;; Comments (if (and (null ispell-check-comments) comment-start) (setq skip-regexp (concat (regexp-quote comment-start) "\\|" skip-regexp))) (if (and (eq 'exclusive ispell-check-comments) comment-start) + ;; search from end of current comment to start of next comment. (setq skip-regexp (concat (if (string= "" comment-end) "^" (regexp-quote comment-end)) "\\|" skip-regexp))) + ;; tib (if ispell-skip-tib (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp))) + ;; html stuff (if ispell-skip-html - (setq skip-regexp (concat "<[cC][oO][dD][eE]\\>[^>]*>" "\\|" - "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "\\|" - "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "\\|" - "<[vV][eE][rR][bB]\\>[^>]*>" "\\|" - ;; "<[tT][tT]\\>[^>]*>" "\\|" - "<[tT][tT]/" "\\|" - "<" "\\|" - "&" "\\|" - skip-regexp))) + (setq skip-regexp (concat + (ispell-begin-skip-region ispell-html-skip-alists) + "\\|" + skip-regexp))) + ;; tex (if (eq ispell-parser 'tex) (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|" skip-regexp))) + ;; messages + (if (and ispell-checking-message + (not (eq t ispell-checking-message))) + (setq skip-regexp (concat + (mapconcat + (function (lambda (lst) (car lst))) + ispell-checking-message + "\\|") + "\\|" + skip-regexp))) + + ;; return new regexp skip-regexp)) +(defun ispell-begin-skip-region (skip-alist) + "Regular expression for start of regions to skip generated from SKIP-ALIST. +Each selection should be a key of SKIP-ALIST; +otherwise, the current line is skipped." + (mapconcat (function (lambda (lst) + (if (stringp (car lst)) + (car lst) + (eval (car lst))))) + skip-alist + "\\|")) + + (defun ispell-begin-tex-skip-regexp () "Regular expression of tex commands to skip. Generated from `ispell-tex-skip-alists'." (concat + ;; raw tex keys (mapconcat (function (lambda (lst) (car lst))) (car ispell-tex-skip-alists) "\\|") "\\|" + ;; keys wrapped in begin{} (mapconcat (function (lambda (lst) (concat "\\\\begin[ \t\n]*{[ \t\n]*" (car lst) @@ -2439,17 +2583,30 @@ Generated from `ispell-tex-skip-alists'." "\\|"))) -(defun ispell-begin-skip-region () - "Regular expression of regions to skip for all buffers. -Each selection should be a key of `ispell-skip-region-alist'; -otherwise, the current line is skipped." - (mapconcat (function (lambda (lst) (if (stringp (car lst)) (car lst) - (eval (car lst))))) - ispell-skip-region-alist - "\\|")) +(defun ispell-skip-region-list () + "Returns a list describing key and body regions to skip for this buffer. +Includes regions defined by `ispell-skip-region-alist', tex mode, +`ispell-html-skip-alists', and `ispell-checking-message'. +Manual checking must include comments and tib references. +The list is of the form described by variable `ispell-skip-region-alist'. +Must call after `ispell-buffer-local-parsing' due to dependence on mode." + (let ((skip-alist ispell-skip-region-alist)) + ;; only additional explicit region definition is tex. + (if (eq ispell-parser 'tex) + (setq case-fold-search nil + skip-alist (append (car ispell-tex-skip-alists) + (car (cdr ispell-tex-skip-alists)) + skip-alist))) + (if ispell-skip-html + (setq skip-alist (append ispell-html-skip-alists skip-alist))) + (if (and ispell-checking-message + (not (eq t ispell-checking-message))) + (setq skip-alist (append ispell-checking-message skip-alist))) + skip-alist)) (defun ispell-tex-arg-end (&optional arg) + "Skip across ARG number of braces." (condition-case nil (progn (while (looking-at "[ \t\n]*\\[") (forward-sexp)) @@ -2460,12 +2617,42 @@ otherwise, the current line is skipped." (sit-for 2)))) -;;; Skips to region-end from point, or a single line. -;;; Places point at end of region skipped. -(defun ispell-skip-region (key alist) +(defun ispell-ignore-fcc (start end) + "Deletes the Fcc: message header when large attachments are included. +Return value `nil' if file with large attachments are saved. +This can be used to avoid multiple quesitons for multiple large attachments. +Returns point to starting location afterwards." + (let ((result t)) + (if (and ispell-checking-message ispell-message-fcc-skip) + (if (< ispell-message-fcc-skip (- end start)) + (let (case-fold-search head-end) + (goto-char (point-min)) + (setq head-end + (or (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "$") + nil t) + (re-search-forward "^$" nil t) + (point-min))) + (goto-char (point-min)) + (if (re-search-forward "^Fcc:" head-end t) + (if (y-or-n-p + "Save copy of this message with large attachments? ") + (setq result nil) + (beginning-of-line) + (kill-line 1))) + (goto-char end)))) + result)) + + +(defun ispell-skip-region (key) + "Skips across KEY and then to end of region. +Key lookup determines region to skip. +Point is placed at end of skipped region." ;; move over key to begin checking. (forward-char (length key)) (let ((start (point)) + ;; Regenerate each call... This function can change region definition. + (alist (ispell-skip-region-list)) alist-key null-skip) (cond ;; what about quoted comment, or comment inside strings? @@ -2479,26 +2666,6 @@ otherwise, the current line is skipped." (search-forward comment-start ispell-region-end :end)) ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key)) (re-search-forward ispell-tib-ref-end ispell-region-end t)) - ((and ispell-skip-html (string-match "</" key)) - (search-forward ">" ispell-region-end t)) - ((and ispell-skip-html (string-match "<[cC][oO][dD][eE]\\>[^>]*>" key)) - (search-forward-regexp "</[cC][oO][dD][eE]>" ispell-region-end t)) - ((and ispell-skip-html - (string-match "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" key)) - (search-forward-regexp "</[sS][cC][rR][iI][pP][tT]>" ispell-region-end t)) - ((and ispell-skip-html - (string-match "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" key)) - (search-forward-regexp "</[aA][pP][pP][lL][eE][tT]>" ispell-region-end t)) - ((and ispell-skip-html (string-match "<[vV][eE][rR][bB]\\>[^>]*>" key)) - (search-forward-regexp "</[vV][eE][rR][bB]>" ispell-region-end t)) - ;;((and ispell-skip-html (string-match "<[tT][tT]\\>[^>]*>" key)) - ;; (search-forward-regexp "</[tT][tT]>" ispell-region-end t)) - ((and ispell-skip-html (string-match "<[tT][tT]/" key)) - (search-forward "/" ispell-region-end t)) - ((and ispell-skip-html (string-match "<" key)) - (search-forward ">" ispell-region-end t)) - ((and ispell-skip-html (string-match "&" key)) - (search-forward-regexp "[; \t\n]" ispell-region-end t)) ;; markings from alist (t (while alist @@ -2511,13 +2678,14 @@ otherwise, the current line is skipped." ((not (consp alist)) ;; Search past end of spell region to find this region end. (re-search-forward (eval alist) (point-max) t)) - ((consp alist) - (if (stringp alist) - (re-search-forward alist (point-max) t) - (setq null-skip t) ; error handling in functions! - (if (consp (cdr alist)) - (apply (car alist) (cdr alist)) - (funcall (car alist)))))) + ((and (= 1 (length alist)) + (stringp (car alist))) + (re-search-forward (car alist) (point-max) t)) + (t + (setq null-skip t) ; error handling in functions! + (if (consp (cdr alist)) + (apply (car alist) (cdr alist)) + (funcall (car alist))))) (setq alist nil)) (setq alist (cdr alist)))))) (if (and (= start (point)) (null null-skip)) @@ -2530,7 +2698,7 @@ otherwise, the current line is skipped." ;;; Grab the next line of data. ;;; Returns a string with the line data -(defun ispell-get-line (start end reg-end) +(defun ispell-get-line (start end reg-end in-comment) (let ((ispell-casechars (ispell-get-casechars)) string) (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS @@ -2540,7 +2708,8 @@ otherwise, the current line is skipped." ;; (forward-char 1)) ; not needed as quoted below. ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS - (setq string (concat "^" (buffer-substring-no-properties start end) + (setq string (concat "^" in-comment + (buffer-substring-no-properties start end) "\n")) (goto-char end)) (t (goto-char end))) ; EMPTY LINE, skip it. @@ -2592,6 +2761,7 @@ Returns the sum shift due to changes in word replacements." (ispell-horiz-scroll) (goto-char word-start) (ispell-horiz-scroll) + ;; Alignment cannot be tracked and this error will occur when ;; `query-replace' makes multiple corrections on the starting line. (if (/= (+ word-len (point)) @@ -2681,8 +2851,8 @@ Returns the sum shift due to changes in word replacements." ;; Move line-start across word... ;; new shift function does this now... ;;(set-marker line-start (+ line-start - ;; (- (length replace) - ;; (length (car poss))))) + ;; (- (length replace) + ;; (length (car poss))))) )) (if (not ispell-quit) (let (message-log-max) @@ -2831,6 +3001,23 @@ Standard ispell choices are then available." (ispell-complete-word t)) +;;;###autoload +(defun ispell () + "Interactively check a region or buffer for spelling errors. +If `transient-mark-mode' is on, and a region is active, spell-check +that region. Otherwise spell-check the buffer. + +Ispell dictionaries are not distributed with Emacs. If you are +looking for a dictionary, please see the distribution of the GNU ispell +program, or do an Internet search; there are various dictionaries +available on the net." + (interactive) + (if (and (boundp 'transient-mark-mode) transient-mark-mode + (boundp 'mark-active) mark-active) + (ispell-region (region-beginning) (region-end)) + (ispell-buffer))) + + ;;; ********************************************************************** ;;; Ispell Minor Mode ;;; ********************************************************************** @@ -2891,7 +3078,6 @@ Don't read buffer-local settings or word lists." ;;; ********************************************************************** ;;; Ispell Message ;;; ********************************************************************** -;;; Original from D. Quinlan, E. Bradford, A. Albert, and M. Ernst (defvar ispell-message-text-end @@ -2900,9 +3086,9 @@ Don't read buffer-local settings or word lists." ;; Don't spell check signatures "^-- $" ;; Matches postscript files. - "^%!PS-Adobe-[123].0" + ;;"^%!PS-Adobe-[123].0" ;; Matches uuencoded text - "^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" + ;;"^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" ;; Matches shell files (especially auto-decoding) "^#! /bin/[ck]?sh" ;; Matches context difference listing @@ -2919,6 +3105,97 @@ If it is a string, limit at first occurrence of that regular expression. Otherwise, it must be a function which is called to get the limit.") +(defun ispell-mime-multipartp (&optional limit) + "Return multipart message start boundary or nil if none." + ;; caller must ensure `case-fold-search' is set to `t' + (and + (re-search-forward + "Content-Type: *multipart/\\([^ \t\n]*;[ \t]*[\n]?[ \t]*\\)+boundary=" + limit t) + (let (boundary) + (if (looking-at "\"") + (let (start) + (forward-char) + (setq start (point)) + (while (not (looking-at "\"")) + (forward-char 1)) + (setq boundary (buffer-substring-no-properties start (point)))) + (let ((start (point))) + (while (looking-at "[-0-9a-zA-Z'()+_,./:=?]") + (forward-char)) + (setq boundary (buffer-substring-no-properties start (point))))) + (if (< (length boundary) 1) + (setq boundary nil) + (concat "--" boundary))))) + + +(defun ispell-mime-skip-part (boundary) + "Moves point across header, or entire MIME part if message is encoded. +All specified types except `7bit' `8bit' and `quoted-printable' are considered +encoded and therefore skipped. See rfc 1521, 2183, ... +If no boundary is given, then entire message is skipped. + +This starts one line ABOVE the MIME content messages, on the boundary marker, +for operation with the generic region-skipping code. +This places new MIME boundaries into variable `ispell-checking-message'." + (forward-line) ; skip over boundary to headers + (let ((save-case-fold-search case-fold-search) + (continuep t) + textp) + (setq case-fold-search t + ispell-skip-html nil) + (while continuep + (setq continuep nil) + (if (looking-at "Content-Type: *text/") + (progn + (goto-char (match-end 0)) + (if (looking-at "html") + (setq ispell-skip-html t)) + (setq textp t + continuep t) + (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t) + (forward-line))) + (if (looking-at "Content-Transfer-Encoding: *\\([^ \t\n]*\\)") + (let ((match (buffer-substring (match-beginning 1) (match-end 1)))) + (setq textp (member (upcase match) + ;; only spell check the following encodings: + '("7BIT" "8BIT" "QUOTED-PRINTABLE" "BINARY")) + continuep t) + (goto-char (match-end 0)) + (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t) + (forward-line))) + ;; hierarchical boundary definition + (if (looking-at "Content-Type: *multipart/") + (let ((new-boundary (ispell-mime-multipartp))) + (if (string-match new-boundary boundary) + (setq continuep t) + ;; first pass redefine skip function to include new boundary + ;;(re-search-backward boundary nil t) + (forward-line) + (setq ispell-checking-message + (cons + (list new-boundary 'ispell-mime-skip-part new-boundary) + (if (eq t ispell-checking-message) nil + ispell-checking-message)) + textp t + continuep t))) + ;; Skip all MIME headers that don't affect spelling + (if (looking-at "Content-[^ \t]*: *\\(.*;[ \t]*[\n]\\)*.*$") + (progn + (setq continuep t) + (goto-char (match-end 0)) + (forward-line))))) + + (setq case-fold-search save-case-fold-search) + (if textp + (point) + ;; encoded message. Skip to boundary, or entire message. + (if (not boundary) + (goto-char (point-max)) + (re-search-forward boundary nil t) + (beginning-of-line) + (point))))) + ;;;###autoload (defun ispell-message () @@ -2943,7 +3220,8 @@ You can bind this to the key C-c i in GNUS or mail by adding to (interactive) (save-excursion (goto-char (point-min)) - (let* ( + (let* (boundary mimep + (ispell-skip-region-alist-save ispell-skip-region-alist) ;; Nil when message came from outside (eg calling emacs as editor) ;; Non-nil marker of end of headers. (internal-messagep @@ -3013,7 +3291,9 @@ You can bind this to the key C-c i in GNUS or mail by adding to (progn ;; Spell check any original Subject: (goto-char (point-min)) - (setq case-fold-search t) + (setq case-fold-search t + mimep (re-search-forward "MIME-Version:" end-of-headers t)) + (goto-char (point-min)) (if (re-search-forward "^Subject: *" end-of-headers t) (progn (goto-char (match-end 0)) @@ -3027,12 +3307,38 @@ You can bind this to the key C-c i in GNUS or mail by adding to (while (looking-at "\n[ \t]") (end-of-line 2)) (point))))))) - (setq case-fold-search old-case-fold-search) - (goto-char end-of-headers) + (if mimep + (progn + (goto-char (point-min)) + (setq boundary (ispell-mime-multipartp end-of-headers)))) + ;; Adjust message limit to MIME message if necessary. + (and boundary + (re-search-forward (concat boundary "--") nil t) + (re-search-backward boundary nil t) + (< (point) (marker-position limit)) + (set-marker limit (point))) + (goto-char (point-min)) + ;; Select type or skip checking if this is a non-multipart message + ;; Point moved to end of buffer if region is encoded. + (if (and mimep (not boundary)) + (let (skip-regexp) ; protect from `ispell-mime-skip-part' + (goto-char (point-min)) + (re-search-forward "Content-[^ \t]*:" end-of-headers t) + (forward-line -1) ; following fn starts one line above + (ispell-mime-skip-part nil))) + (goto-char (max end-of-headers (point))) (forward-line 1) + (setq case-fold-search old-case-fold-search) + ;; Define MIME regions to skip. + (if boundary + (setq ispell-checking-message + (list (list boundary 'ispell-mime-skip-part boundary)))) (ispell-region (point) limit)) (set-marker end-of-headers nil) - (set-marker limit nil))))) + (set-marker limit nil) + (setq ispell-skip-region-alist ispell-skip-region-alist-save + ispell-skip-html nil + case-fold-search old-case-fold-search))))) (defun ispell-non-empty-string (string) @@ -3073,9 +3379,9 @@ Includes Latex/Nroff modes and extended character mode." (ispell-send-string "-\n")) ; set mode to normal (nroff) ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value. (if (and ispell-skip-html (not (eq ispell-skip-html t))) - (set (make-local-variable 'ispell-skip-html) - (not (null (string-match "sgml\\|html" - (downcase (symbol-name major-mode))))))) + (setq ispell-skip-html + (not (null (string-match "sgml\\|html" + (downcase (symbol-name major-mode))))))) ;; Set default extended character mode for given buffer, if any. (let ((extended-char-mode (ispell-get-extended-character-mode))) (if extended-char-mode @@ -3242,8 +3548,9 @@ Both should not be used to define a buffer-local dictionary." ; LocalWords: Francais Nederlands charset autoloaded popup nonmenu regexp num ; LocalWords: AMStex hspace includeonly nocite epsfig displaymath eqnarray reg ; LocalWords: minipage modeline pers dict unhighlight buf grep sync prev inc -; LocalWords: fn hilight oldot NB AIX msg init read's bufs pt cmd Quinlan eg +; LocalWords: fn hilight oldot NB AIX msg init read's bufs pt cmd eg multibyte ; LocalWords: uuencoded unidiff sc nn VM SGML eval IspellPersDict unsplitable -; LocalWords: lns XEmacs HTML casechars Multibyte +; LocalWords: lns XEmacs html casechars Multibyte Aug unix wp iso multiline +; LocalWords: multipart aspell Fcc regexps tib russian latin Slovakian ;;; ispell.el ends here |