Spelling fixes.
[bpt/emacs.git] / lisp / textmodes / ispell.el
index ad2838a..ba7b84f 100644 (file)
@@ -1,7 +1,6 @@
 ;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2
 
-;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1994-1995, 1997-2011  Free Software Foundation, Inc.
 
 ;; Author:           Ken Stevens <k.stevens@ieee.org>
 ;; Maintainer:       Ken Stevens <k.stevens@ieee.org>
@@ -770,8 +769,8 @@ here just for backwards compatibility.")
 
 
 
-;;; The version must be 3.1 or greater for this version of ispell.el
-;;; There is an incompatibility between version 3.1.12 and lower versions.
+;; The version must be 3.1 or greater for this version of ispell.el
+;; There is an incompatibility between version 3.1.12 and lower versions.
 (defconst ispell-required-version '(3 1 12)
   "Ispell versions with which this version of ispell.el is known to work.")
 (defvar ispell-offset -1
@@ -983,19 +982,32 @@ Assumes that value contains no whitespace."
     (car (split-string (buffer-string)))))
 
 (defun ispell-aspell-find-dictionary (dict-name)
-  ;; This returns nil if the data file does not exist.
-  ;; Can someone please explain the return value format when the
-  ;; file does exist -- rms?
-  (let* ((lang ;; Strip out variant, etc.
-         (and (string-match "^[[:alpha:]_]+" dict-name)
-              (match-string 0 dict-name)))
+  "For aspell dictionary DICT-NAME, return a list of parameters if an
+  associated data file is found or nil otherwise.  List format is
+  that of `ispell-dictionary-base-alist' elements."
+  ;; Make sure `ispell-aspell-data-dir' is defined
+  (or ispell-aspell-data-dir
+      (setq ispell-aspell-data-dir
+           (ispell-get-aspell-config-value "data-dir")))
+  ;; Try finding associated datafile
+  (let* ((datafile1
+         (concat ispell-aspell-data-dir "/"
+                 ;; Strip out variant, country code, etc.
+                 (and (string-match "^[[:alpha:]]+" dict-name)
+                      (match-string 0 dict-name)) ".dat"))
+        (datafile2
+         (concat ispell-aspell-data-dir "/"
+                 ;; Strip out anything but xx_YY.
+                 (and (string-match "^[[:alpha:]_]+" dict-name)
+                      (match-string 0 dict-name)) ".dat"))
         (data-file
-         (concat (or ispell-aspell-data-dir
-                     (setq ispell-aspell-data-dir
-                           (ispell-get-aspell-config-value "data-dir")))
-                 "/" lang ".dat"))
+         (if (file-readable-p datafile1)
+             datafile1
+           (if (file-readable-p datafile2)
+               datafile2)))
         otherchars)
-    (condition-case ()
+
+    (if data-file
        (with-temp-buffer
          (insert-file-contents data-file)
          ;; There is zero or one line with special characters declarations.
@@ -1023,9 +1035,7 @@ Assumes that value contains no whitespace."
                ;; 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))
-      (file-error
-       nil))))
+               'utf-8)))))
 
 (defun ispell-aspell-add-aliases (alist)
   "Find aspell's dictionary aliases and add them to dictionary ALIST.
@@ -1106,7 +1116,7 @@ aspell is used along with Emacs).")
 
 
 (defun ispell-valid-dictionary-list ()
-  "Returns a list of valid dictionaries.
+  "Return a list of valid dictionaries.
 The variable `ispell-library-directory' defines the library location."
   ;; Initialize variables and dictionaries alists for desired spellchecker.
   ;; Make sure ispell.el is loaded to avoid some autoload loops in XEmacs
@@ -1269,9 +1279,6 @@ The variable `ispell-library-directory' defines the library location."
 
 ;;; **********************************************************************
 
-
-;;; This variable contains the current dictionary being used if the ispell
-;;; process is running.
 (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
@@ -1296,6 +1303,7 @@ Protects against bogus binding of `enable-multibyte-characters' in XEmacs."
 
 ;; Return a string decoded from Nth element of the current dictionary.
 (defun ispell-get-decoded-string (n)
+  "Get the decoded string in slot N of the descriptor of the current dict."
   (let* ((slot (or
                (assoc ispell-current-dictionary ispell-local-dictionary-alist)
                (assoc ispell-current-dictionary ispell-dictionary-alist)
@@ -1715,7 +1723,11 @@ quit          spell session exited."
                  (extent-at start)
                  (and (fboundp 'delete-extent)
                       (delete-extent (extent-at start)))))
-           ((null poss) (message "Error in ispell process"))
+           ((null poss)
+            (message "Error checking word %s using %s with %s dictionary"
+                     (funcall ispell-format-word-function word)
+                     (file-name-nondirectory ispell-program-name)
+                     (or ispell-current-dictionary "default")))
            (ispell-check-only        ; called from ispell minor mode.
             (if (fboundp 'make-extent)
                 (if (fboundp 'set-extent-property)
@@ -1906,7 +1918,7 @@ Global `ispell-quit' set to start location to continue spell session."
                    (setq line (1+ line))))
              (insert (car guess) "    ")
              (setq guess (cdr guess)))
-           (insert "\nUse option `i' to accept this spelling and put it in your private dictionary.")
+           (insert "\nUse option `i' to accept this spelling and put it in your private dictionary.\n")
            (setq line (+ line (if choices 3 2)))))
       (while (and choices
                  (< (if (> (+ 7 (current-column) (length (car choices))
@@ -2151,7 +2163,7 @@ Global `ispell-quit' set to start location to continue spell session."
   (if (and ispell-use-framepop-p (fboundp 'framepop-display-buffer))
       (progn
        (framepop-display-buffer (get-buffer ispell-choices-buffer))
-;;;    (get-buffer-window ispell-choices-buffer t)
+        ;; (get-buffer-window ispell-choices-buffer t)
        (select-window (previous-window))) ; *Choices* window
     ;; standard selection by splitting a small buffer out of this window.
     (let ((choices-window (get-buffer-window ispell-choices-buffer)))
@@ -2272,7 +2284,7 @@ Otherwise the variable `ispell-grep-command' contains the command used to
 search for the words (usually egrep).
 
 Optional second argument contains the dictionary to use; the default is
-`ispell-alternate-dictionary', overriden by `ispell-complete-word-dict'
+`ispell-alternate-dictionary', overridden by `ispell-complete-word-dict'
 if defined."
   ;; We don't use the filter for this function, rather the result is written
   ;; into a buffer.  Hence there is no need to save the filter values.
@@ -2292,48 +2304,42 @@ if defined."
         (wild-p (string-match "\\*" word))
         (look-p (and ispell-look-p     ; Only use look for an exact match.
                      (or ispell-have-new-look (not wild-p))))
-        (ispell-grep-buffer (get-buffer-create "*Ispell-Temp*")) ; result buf
         (prog (if look-p ispell-look-command ispell-grep-command))
         (args (if look-p ispell-look-options ispell-grep-options))
         status results loc)
-    (unwind-protect
-       (save-window-excursion
-         (message "Starting \"%s\" process..." (file-name-nondirectory prog))
-         (set-buffer ispell-grep-buffer)
-         (if look-p
-             nil
-           ;; convert * to .*
-           (insert "^" word "$")
-           (while (search-backward "*" nil t) (insert "."))
-           (setq word (buffer-string))
-           (erase-buffer))
-         (setq status (apply 'ispell-call-process prog nil t nil
-                             (nconc (if (and args (> (length args) 0))
-                                        (list args)
-                                      (if look-p nil
-                                        (list "-e")))
-                                    (list word)
-                                    (if lookup-dict (list lookup-dict)))))
-         ;; grep returns status 1 and no output when word not found, which
-         ;; is a perfectly normal thing.
-         (if (stringp status)
-             (setq results (cons (format "error: %s exited with signal %s"
-                                         (file-name-nondirectory prog) status)
-                                 results))
-           ;; else collect words into `results' in FIFO order
-           (goto-char (point-max))
-           ;; assure we've ended with \n
-           (or (bobp) (= (preceding-char) ?\n) (insert ?\n))
-           (while (not (bobp))
-             (setq loc (point))
-             (forward-line -1)
-             (setq results (cons (buffer-substring-no-properties (point)
-                                                                 (1- loc))
-                                 results)))))
-      ;; protected
-      (kill-buffer ispell-grep-buffer)
-      (if (and results (string-match ".+: " (car results)))
-         (error "%s error: %s" ispell-grep-command (car results))))
+    (with-temp-buffer
+      (message "Starting \"%s\" process..." (file-name-nondirectory prog))
+      (if look-p
+          nil
+        ;; Convert * to .*
+        (insert "^" word "$")
+        (while (search-backward "*" nil t) (insert "."))
+        (setq word (buffer-string))
+        (erase-buffer))
+      (setq status (apply 'ispell-call-process prog nil t nil
+                          (nconc (if (and args (> (length args) 0))
+                                     (list args)
+                                   (if look-p nil
+                                     (list "-e")))
+                                 (list word)
+                                 (if lookup-dict (list lookup-dict)))))
+      ;; `grep' returns status 1 and no output when word not found, which
+      ;; is a perfectly normal thing.
+      (if (stringp status)
+          (error "error: %s exited with signal %s"
+                 (file-name-nondirectory prog) status)
+        ;; Else collect words into `results' in FIFO order.
+        (goto-char (point-max))
+        ;; Assure we've ended with \n.
+        (or (bobp) (= (preceding-char) ?\n) (insert ?\n))
+        (while (not (bobp))
+          (setq loc (point))
+          (forward-line -1)
+          (push (buffer-substring-no-properties (point)
+                                                (1- loc))
+                results))))
+    (if (and results (string-match ".+: " (car results)))
+        (error "%s error: %s" ispell-grep-command (car results)))
     results))
 
 
@@ -2393,7 +2399,8 @@ Optional REFRESH will unhighlighted then highlight, using block cursor
           (setq start (1+ start))))    ; On block non-refresh, inc start.
   (let ((modified (buffer-modified-p)) ; don't allow this fn to modify buffer
        (buffer-read-only nil)          ; Allow highlighting read-only buffers.
-       (text (buffer-substring-no-properties start end)) ; Save hilight region
+       (text (buffer-substring-no-properties start end))
+                                       ; Save highlight region.
        (inhibit-quit t)                ; inhibit interrupt processing here.
        (buffer-undo-list t))           ; don't clutter the undo list.
     (goto-char end)
@@ -2492,7 +2499,7 @@ scrolling the current window.  Leave the new window selected."
       ;; hidden by new window, scroll it to just below new win
       ;; otherwise set top line of other win so it doesn't scroll.
       (if (< oldot top) (setq top oldot))
-      ;; if frame is unsplitable, temporarily disable that...
+      ;; if frame is unsplittable, temporarily disable that...
       (if (cdr (assq 'unsplittable (frame-parameters (selected-frame))))
          (let ((frame (selected-frame)))
            (modify-frame-parameters frame '((unsplittable . nil)))
@@ -2546,18 +2553,18 @@ Optional third arg SHIFT is an offset to apply based on previous corrections."
        (setq count (string-to-number output) ; get number of misses.
              output (substring output (1+ (string-match " " output 1)))))
       (setq offset (string-to-number output))
-      (if (eq type ?#)                 ; No miss or guess list.
-         (setq output nil)
-       (setq output (substring output (1+ (string-match " " output 1)))))
+      (setq output (if (eq type ?#)     ; No miss or guess list.
+                       nil
+                     (substring output (1+ (string-match " " output 1)))))
       (while output
        (let ((end (string-match ", \\|\\($\\)" output))) ; end of miss/guess.
          (setq cur-count (1+ cur-count))
          (if (> cur-count count)
-             (setq guess-list (cons (substring output 0 end) guess-list))
-           (setq miss-list (cons (substring output 0 end) miss-list)))
-         (if (match-end 1)             ; True only when at end of line.
-             (setq output nil)         ; no more misses or guesses
-           (setq output (substring output (+ end 2))))))
+             (push (substring output 0 end) guess-list)
+           (push (substring output 0 end) miss-list))
+         (setq output (if (match-end 1) ; True only when at end of line.
+                           nil           ; No more misses or guesses.
+                         (substring output (+ end 2))))))
       ;; return results.  Accept word if it was already accepted.
       ;; adjust offset.
       (if (member original-word accept-list)
@@ -2730,9 +2737,11 @@ Keeps argument list for future ispell invocations for no async support."
        (if extended-char-mode          ; ~ extended character mode
            (ispell-send-string (concat extended-char-mode "\n"))))
       (if ispell-async-processp
-         (if (fboundp 'set-process-query-on-exit-flag) ;; not XEmacs
+         (if (featurep 'emacs)
              (set-process-query-on-exit-flag ispell-process nil)
-           (process-kill-without-query ispell-process))))))
+           (if (fboundp 'set-process-query-on-exit-flag)
+               (set-process-query-on-exit-flag ispell-process nil)
+             (process-kill-without-query ispell-process)))))))
 
 ;;;###autoload
 (defun ispell-kill-ispell (&optional no-error)
@@ -2775,7 +2784,7 @@ By just answering RET you can find out what the current dictionary is."
               (mapcar 'list (ispell-valid-dictionary-list)))
          nil t)
         current-prefix-arg))
-  (ispell-set-spellchecker-params) ; Initilize variables and dicts alists
+  (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
   (unless arg (ispell-buffer-local-dict 'no-reload))
   (if (equal dict "default") (setq dict nil))
   ;; This relies on completing-read's bug of returning "" for no match
@@ -2818,7 +2827,11 @@ a new one will be started when needed."
       (setq ispell-current-dictionary dict
            ispell-current-personal-dictionary pdict))))
 
-;;; Spelling of comments are checked when ispell-check-comments is non-nil.
+;; Avoid error messages when compiling for these dynamic variables.
+(defvar ispell-start)
+(defvar ispell-end)
+
+;; Spelling of comments are checked when ispell-check-comments is non-nil.
 
 ;;;###autoload
 (defun ispell-region (reg-start reg-end &optional recheckp shift)
@@ -2849,8 +2862,7 @@ Return nil if spell session is quit,
              (message "searching for regions to skip"))
            (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)))
+                 (setq key (match-string-no-properties 0))
                  (set-marker skip-region-start (- (point) (length key)))
                  (goto-char reg-start)))
            (let (message-log-max)
@@ -2896,18 +2908,19 @@ Return nil if spell session is quit,
                                 (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 in-comment)))
+             (let* ((ispell-start (point))
+                    (ispell-end (min (point-at-eol) reg-end))
+                    (string (ispell-get-line
+                              ispell-start ispell-end in-comment)))
                (if in-comment          ; account for comment chars added
-                   (setq start (- start (length in-comment))
+                   (setq ispell-start (- ispell-start (length in-comment))
                          in-comment nil))
-               (setq end (point))      ; "end" tracks region retrieved.
+               (setq ispell-end (point)) ; "end" tracks region retrieved.
                (if string              ; there is something to spell check!
                    ;; (special start end)
                    (setq shift (ispell-process-line string
                                                     (and recheckp shift))))
-               (goto-char end)))))
+               (goto-char ispell-end)))))
        (if ispell-quit
            nil
          (or shift 0)))
@@ -2944,42 +2957,30 @@ Return nil if spell session is quit,
   "Return 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
-                          (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 (lambda (lst) (car lst))
-                                     ispell-checking-message
-                                     "\\|")
-                          "\\|"
-                          skip-regexp)))
-
-    ;; return new regexp
-    skip-regexp))
+  (mapconcat
+   'identity
+   (delq nil
+         (list
+          ;; messages
+          (if (and ispell-checking-message
+                   (not (eq t ispell-checking-message)))
+              (mapconcat #'car ispell-checking-message "\\|"))
+          ;; tex
+          (if (eq ispell-parser 'tex)
+              (ispell-begin-tex-skip-regexp))
+          ;; html stuff
+          (if ispell-skip-html
+              (ispell-begin-skip-region ispell-html-skip-alists))
+          ;; tib
+          (if ispell-skip-tib ispell-tib-ref-beginning)
+          ;; Comments
+          (if (and (eq 'exclusive ispell-check-comments) comment-start)
+              ;; search from end of current comment to start of next comment.
+              (if (string= "" comment-end) "^" (regexp-quote comment-end)))
+          (if (and (null ispell-check-comments) comment-start)
+              (regexp-quote comment-start))
+          (ispell-begin-skip-region ispell-skip-region-alist)))
+   "\\|"))
 
 
 (defun ispell-begin-skip-region (skip-alist)
@@ -3038,7 +3039,7 @@ Must call after `ispell-buffer-local-parsing' due to dependence on mode."
        (while (looking-at "[ \t\n]*\\[") (forward-sexp))
        (forward-sexp (or arg 1)))
     (error
-     (message "error skipping s-expressions at point %d." (point))
+     (message "Error skipping s-expressions at point %d." (point))
      (beep)
      (sit-for 2))))
 
@@ -3151,17 +3152,13 @@ Returns a string with the line data."
                                       (point) (+ (point) len))
                                      coding)))))
 
-;; Avoid error messages when compiling for these dynamic variables.
-;; FIXME: dynamically scoped vars should have an "ispell-" prefix.
-(defvar start)
-(defvar end)
-
 (defun ispell-process-line (string shift)
   "Send STRING, a line of text, to ispell and processes the result.
 This will modify the buffer for spelling errors.
-Requires variables START and END to be defined in its lexical scope.
+Requires variables ISPELL-START and ISPELL-END to be defined in its
+dynamic scope.
 Returns the sum SHIFT due to changes in word replacements."
-  ;;(declare special start end)
+  ;;(declare special ispell-start ispell-end)
   (let (poss accept-list)
     (if (not (numberp shift))
        (setq shift 0))
@@ -3184,10 +3181,10 @@ Returns the sum SHIFT due to changes in word replacements."
          ;; Markers can move with highlighting!  This destroys
          ;; end of region markers line-end and ispell-region-end
          (let ((word-start
-                (copy-marker (+ start ispell-offset (car (cdr poss)))))
+                (copy-marker (+ ispell-start ispell-offset (car (cdr poss)))))
                (word-len (length (car poss)))
-               (line-end (copy-marker end))
-               (line-start (copy-marker start))
+               (line-end (copy-marker ispell-end))
+               (line-start (copy-marker ispell-start))
                recheck-region replace)
            (goto-char word-start)
            ;; Adjust the horizontal scroll & point
@@ -3294,11 +3291,12 @@ Returns the sum SHIFT due to changes in word replacements."
                    (file-name-nondirectory ispell-program-name)
                    (or ispell-current-dictionary "default"))))
            (sit-for 0)
-           (setq start (marker-position line-start)
-                 end (marker-position line-end))
+           (setq ispell-start (marker-position line-start)
+                 ispell-end (marker-position line-end))
            ;; Adjust markers when end of region lost from highlighting.
-           (if (and (not recheck-region) (< end (+ word-start word-len)))
-               (setq end (+ word-start word-len)))
+           (if (and (not recheck-region)
+                     (< ispell-end (+ word-start word-len)))
+               (setq ispell-end (+ word-start word-len)))
            (if (= word-start ispell-region-end)
                (set-marker ispell-region-end (+ word-start word-len)))
            ;; going out of scope - unneeded
@@ -3456,15 +3454,6 @@ available on the net."
 ;;;                    Ispell Minor Mode
 ;;; **********************************************************************
 
-(defvar ispell-minor-mode nil
-  "Non-nil if Ispell minor mode is enabled.")
-;; Variable indicating that ispell minor mode is active.
-(make-variable-buffer-local 'ispell-minor-mode)
-
-(or (assq 'ispell-minor-mode minor-mode-alist)
-    (setq minor-mode-alist
-          (cons '(ispell-minor-mode " Spell") minor-mode-alist)))
-
 (defvar ispell-minor-keymap
   (let ((map (make-sparse-keymap)))
     (define-key map " " 'ispell-minor-check)
@@ -3472,28 +3461,24 @@ available on the net."
     map)
   "Keymap used for Ispell minor mode.")
 
-(or (not (boundp 'minor-mode-map-alist))
-    (assoc 'ispell-minor-mode minor-mode-map-alist)
-    (setq minor-mode-map-alist
-          (cons (cons 'ispell-minor-mode ispell-minor-keymap)
-                minor-mode-map-alist)))
-
 ;;;###autoload
-(defun ispell-minor-mode (&optional arg)
-  "Toggle Ispell minor mode.
-With prefix argument ARG, turn Ispell minor mode on if ARG is positive,
-otherwise turn it off.
+(define-minor-mode ispell-minor-mode
+  "Toggle last-word spell checking (Ispell minor mode).
+With a prefix argument ARG, enable Ispell minor mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
 
-In Ispell minor mode, pressing SPC or RET
-warns you if the previous word is incorrectly spelled.
+Ispell minor mode is a buffer-local mior mode.  When enabled,
+typing SPC or RET warns you if the previous word is incorrectly
+spelled.
 
-All the buffer-local variables and dictionaries are ignored -- to read
-them into the running ispell process, type \\[ispell-word] SPC."
-  (interactive "P")
-  (setq ispell-minor-mode
-       (not (or (and (null arg) ispell-minor-mode)
-                (<= (prefix-numeric-value arg) 0))))
-  (force-mode-line-update))
+All the buffer-local variables and dictionaries are ignored.  To
+read them into the running ispell process, type \\[ispell-word]
+SPC.
+
+For spell-checking \"on the fly\", not just after typing SPC or
+RET, use `flyspell-mode'."
+  nil " Spell" ispell-minor-keymap)
 
 (defun ispell-minor-check ()
   "Check previous word then continue with the normal binding of this key.
@@ -3519,7 +3504,7 @@ Don't read buffer-local settings or word lists."
             '(
               ;; Don't spell check signatures
               "^-- $"
-              ;; Matches postscript files.
+              ;; Matches PostScript files.
               ;;"^%!PS-Adobe-[123].0"
               ;; Matches uuencoded text
               ;;"^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM"
@@ -3759,15 +3744,14 @@ You can bind this to the key C-c i in GNUS or mail by adding to
            (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'
+           (when (and mimep (not boundary))
                  (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)
                  ;; if message-text-end region, limit may be less than point.
                  (if (> (point) limit)
-                     (set-marker limit (point)))))
+                  (set-marker limit (point))))
            (goto-char (max end-of-headers (point)))
            (forward-line 1)
            (setq case-fold-search old-case-fold-search)
@@ -3833,7 +3817,7 @@ Includes Latex/Nroff modes and extended character mode."
     (goto-char (point-max))
     ;; Uses last occurrence of ispell-parsing-keyword
     (if (search-backward ispell-parsing-keyword nil t)
-       (let ((end (save-excursion (end-of-line) (point)))
+       (let ((end (point-at-eol))
              string)
          (search-forward ispell-parsing-keyword)
          (while (re-search-forward " *\\([^ \"]+\\)" end t)
@@ -3850,7 +3834,7 @@ Includes Latex/Nroff modes and extended character mode."
                     (sit-for 2))))))))
 
 
-;;; Can kill the current ispell process
+;; Can kill the current ispell process
 
 (defun ispell-buffer-local-dict (&optional no-reload)
   "Initializes local dictionary and local personal dictionary.
@@ -3869,7 +3853,7 @@ Both should not be used to define a buffer-local dictionary."
        (if (search-backward ispell-dictionary-keyword nil t)
            (progn
              (search-forward ispell-dictionary-keyword)
-             (setq end (save-excursion (end-of-line) (point)))
+             (setq end (point-at-eol))
              (if (re-search-forward " *\\([^ \"]+\\)" end t)
                  (setq ispell-local-dictionary
                        (match-string-no-properties 1))))))
@@ -3877,7 +3861,7 @@ Both should not be used to define a buffer-local dictionary."
       (if (search-backward ispell-pdict-keyword nil t)
          (progn
            (search-forward ispell-pdict-keyword)
-           (setq end (save-excursion (end-of-line) (point)))
+           (setq end (point-at-eol))
            (if (re-search-forward " *\\([^ \"]+\\)" end t)
                (setq ispell-local-pdict
                      (match-string-no-properties 1)))))))
@@ -3901,7 +3885,7 @@ Both should not be used to define a buffer-local dictionary."
     (while (search-forward ispell-words-keyword nil t)
       (or ispell-buffer-local-name
          (setq ispell-buffer-local-name (buffer-name)))
-      (let ((end (save-excursion (end-of-line) (point)))
+      (let ((end (point-at-eol))
            (ispell-casechars (ispell-get-casechars))
            string)
        ;; buffer-local words separated by a space, and can contain
@@ -3917,22 +3901,23 @@ Both should not be used to define a buffer-local dictionary."
 
 ;;; returns optionally adjusted region-end-point.
 
+;; If comment-padright is defined, newcomment must be loaded.
+(declare-function comment-add "newcomment" (arg))
+
 (defun ispell-add-per-file-word-list (word)
   "Add WORD to the per-file word list."
   (or ispell-buffer-local-name
       (setq ispell-buffer-local-name (buffer-name)))
   (save-excursion
     (goto-char (point-min))
-    (let ((old-case-fold-search case-fold-search)
-         line-okay search done found)
+    (let (line-okay search done found)
       (while (not done)
-       (setq case-fold-search nil
-             search (search-forward ispell-words-keyword nil 'move)
+        (let ((case-fold-search nil))
+          (setq search (search-forward ispell-words-keyword nil 'move)
              found (or found search)
              line-okay (< (+ (length word) 1 ; 1 for space after word..
                              (progn (end-of-line) (current-column)))
-                          80)
-             case-fold-search old-case-fold-search)
+                             fill-column)))
        (if (or (and search line-okay)
                (null search))
            (progn
@@ -3941,8 +3926,18 @@ Both should not be used to define a buffer-local dictionary."
                  (progn
                    (open-line 1)
                    (unless found (newline))
-                   (insert (concat comment-start " " ispell-words-keyword))
-                   (if (> (length comment-end) 0)
+                   (insert (if comment-start
+                                (concat
+                                  (if (fboundp 'comment-padright)
+                                      ;; Try and use the proper comment marker,
+                                      ;; e.g. ";;" rather than ";".
+                                      (comment-padright comment-start
+                                                        (comment-add nil))
+                                    comment-start)
+                                  " ")
+                              "")
+                            ispell-words-keyword)
+                    (if (and comment-end (> (length comment-end) 0))
                        (save-excursion
                          (newline)
                          (insert comment-end)))))
@@ -3983,9 +3978,8 @@ 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:  uuencoded unidiff sc nn VM SGML eval IspellPersDict unsplitable
+; LocalWords:  fn oldot NB AIX msg init read's bufs pt cmd Quinlan eg
+; LocalWords:  uuencoded unidiff sc nn VM SGML eval IspellPersDict
 ; LocalWords:  lns XEmacs HTML casechars Multibyte
 
-;; arch-tag: 4941b9f9-3b7c-4a76-a4ed-5fa8b6010ef5
 ;;; ispell.el ends here