]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/flyspell.el
Merge from emacs-24; up to 2012-12-17T11:17:34Z!rgm@gnu.org
[gnu-emacs] / lisp / textmodes / flyspell.el
index 24967ded154cba89d59065a8c9e634b2006e31f6..6ab3e3d3f16e34f803adff27a5be3a36bddeed7e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; flyspell.el --- on-the-fly spell checker
 
-;; Copyright (C) 1998, 2000-201 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 2000-2013 Free Software Foundation, Inc.
 
 ;; Author: Manuel Serrano <Manuel.Serrano@sophia.inria.fr>
 ;; Maintainer: FSF
@@ -63,7 +63,7 @@ Non-nil means use highlight, nil means use minibuffer messages."
   "Non-nil means Flyspell reports a repeated word as an error.
 See `flyspell-mark-duplications-exceptions' to add exceptions to this rule.
 Detection of repeated words is not implemented in
-\"large\" regions; see `flyspell-large-region'."
+\"large\" regions; see variable `flyspell-large-region'."
   :group 'flyspell
   :type 'boolean)
 
@@ -143,12 +143,12 @@ whose length is specified by `flyspell-delay'."
   :type '(repeat (symbol)))
 
 (defcustom flyspell-default-deplacement-commands
-  '(next-line
-    previous-line
+  '(next-line previous-line
+    handle-switch-frame handle-select-window
     scroll-up
     scroll-down)
   "The standard list of deplacement commands for Flyspell.
-See `flyspell-deplacement-commands'."
+See variable `flyspell-deplacement-commands'."
   :group 'flyspell
   :version "21.1"
   :type '(repeat (symbol)))
@@ -233,8 +233,8 @@ URL `http://www.gnu.org/software/auctex/'"
   :type 'boolean)
 
 (defcustom flyspell-mode-line-string " Fly"
-  "String displayed on the modeline when flyspell is active.
-Set this to nil if you don't want a modeline indicator."
+  "String displayed on the mode line when flyspell is active.
+Set this to nil if you don't want a mode line indicator."
   :group 'flyspell
   :type '(choice string (const :tag "None" nil)))
 
@@ -291,9 +291,9 @@ If this variable is nil, all regions are treated as small."
 ;;*    Mode specific options enable users to disable flyspell on        */
 ;;*    certain word depending of the emacs mode. For instance, when     */
 ;;*    using flyspell with mail-mode add the following expression       */
-;;*    in your .emacs file:                                             */
+;;*    in your init file:                                               */
 ;;*       (add-hook 'mail-mode                                          */
-;;*                 (lambda () (setq flyspell-generic-check-word-predicate    */
+;;*                 (lambda () (setq flyspell-generic-check-word-predicate     */
 ;;*                                   'mail-mode-flyspell-verify)))            */
 ;;*---------------------------------------------------------------------*/
 (defvar flyspell-generic-check-word-predicate nil
@@ -447,19 +447,23 @@ like <img alt=\"Some thing.\">."
 ;;*    Highlighting                                                     */
 ;;*---------------------------------------------------------------------*/
 (defface flyspell-incorrect
-  '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
-    (t (:bold t)))
-  "Face used for marking a misspelled word in Flyspell."
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "Red1"))
+    (t
+     :underline t :inherit error))
+  "Flyspell face for misspelled words."
+  :version "24.4"
   :group 'flyspell)
-(define-obsolete-face-alias 'flyspell-incorrect-face 'flyspell-incorrect "22.1")
 
 (defface flyspell-duplicate
-  '((((class color)) (:foreground "Gold3" :bold t :underline t))
-    (t (:bold t)))
-  "Face used for marking a misspelled word that appears twice in the buffer.
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "DarkOrange"))
+    (t
+     :underline t :inherit warning))
+  "Flyspell face for words that appear twice in a row.
 See also `flyspell-duplicate-distance'."
+  :version "24.4"
   :group 'flyspell)
-(define-obsolete-face-alias 'flyspell-duplicate-face 'flyspell-duplicate "22.1")
 
 (defvar flyspell-overlay nil)
 
@@ -495,7 +499,7 @@ invoking `ispell-change-dictionary'.
 Consider using the `ispell-parser' to check your text.  For instance
 consider adding:
 \(add-hook 'tex-mode-hook (function (lambda () (setq ispell-parser 'tex))))
-in your .emacs file.
+in your init file.
 
 \\[flyspell-region] checks all words inside a region.
 \\[flyspell-buffer] checks the whole buffer."
@@ -616,7 +620,9 @@ in your .emacs file.
   ;; the welcome message
   (if (and flyspell-issue-message-flag
           flyspell-issue-welcome-flag
-          (called-interactively-p 'interactive))
+          (if (featurep 'xemacs)
+              (interactive-p) ;; XEmacs does not have (called-interactively-p)
+            (called-interactively-p 'interactive)))
       (let ((binding (where-is-internal 'flyspell-auto-correct-word
                                        nil 'non-ascii)))
        (message "%s"
@@ -631,7 +637,7 @@ in your .emacs file.
 (defun flyspell-delay-commands ()
   "Install the standard set of Flyspell delayed commands."
   (mapc 'flyspell-delay-command flyspell-default-delayed-commands)
-  (mapcar 'flyspell-delay-command flyspell-delayed-commands))
+  (mapc 'flyspell-delay-command flyspell-delayed-commands))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-delay-command ...                                       */
@@ -639,7 +645,7 @@ in your .emacs file.
 (defun flyspell-delay-command (command)
   "Set COMMAND to be delayed, for Flyspell.
 When flyspell `post-command-hook' is invoked because a delayed command
-as been used the current word is not immediately checked.
+has been used, the current word is not immediately checked.
 It will be checked only after `flyspell-delay' seconds."
   (interactive "SDelay Flyspell after Command: ")
   (put command 'flyspell-delayed t))
@@ -650,16 +656,15 @@ It will be checked only after `flyspell-delay' seconds."
 (defun flyspell-deplacement-commands ()
   "Install the standard set of Flyspell deplacement commands."
   (mapc 'flyspell-deplacement-command flyspell-default-deplacement-commands)
-  (mapcar 'flyspell-deplacement-command flyspell-deplacement-commands))
+  (mapc 'flyspell-deplacement-command flyspell-deplacement-commands))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-deplacement-command ...                                 */
 ;;*---------------------------------------------------------------------*/
 (defun flyspell-deplacement-command (command)
   "Set COMMAND that implement cursor movements, for Flyspell.
-When flyspell `post-command-hook' is invoked because of a deplacement command
-as been used the current word is checked only if the previous command was
-not the very same deplacement command."
+When flyspell `post-command-hook' is invoked because a deplacement command
+has been used, the current word is not checked."
   (interactive "SDeplacement Flyspell after Command: ")
   (put command 'flyspell-deplacement t))
 
@@ -680,12 +685,12 @@ not the very same deplacement command."
 ;;*    post command hook, we will check, if the word at this position   */
 ;;*    has to be spell checked.                                         */
 ;;*---------------------------------------------------------------------*/
-(defvar flyspell-pre-buffer     nil)
-(defvar flyspell-pre-point      nil)
-(defvar flyspell-pre-column     nil)
+(defvar flyspell-pre-buffer     nil "Buffer current before `this-command'.")
+(defvar flyspell-pre-point      nil "Point before running `this-command'")
+(defvar flyspell-pre-column     nil "Column before running `this-command'")
 (defvar flyspell-pre-pre-buffer nil)
 (defvar flyspell-pre-pre-point  nil)
-(make-variable-buffer-local 'flyspell-pre-point)
+(make-variable-buffer-local 'flyspell-pre-point) ;Why??  --Stef
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-previous-command ...                                    */
@@ -709,18 +714,18 @@ not the very same deplacement command."
 ;;;###autoload
 (defun flyspell-mode-off ()
   "Turn Flyspell mode off."
-  ;; we remove the hooks
+  ;; We remove the hooks.
   (remove-hook 'post-command-hook (function flyspell-post-command-hook) t)
   (remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t)
   (remove-hook 'after-change-functions 'flyspell-after-change-function t)
   (remove-hook 'hack-local-variables-hook
               (function flyspell-hack-local-variables-hook) t)
-  ;; we remove all the flyspell highlightings
+  ;; We remove all the flyspell highlightings.
   (flyspell-delete-all-overlays)
-  ;; we have to erase pre cache variables
+  ;; We have to erase pre cache variables.
   (setq flyspell-pre-buffer nil)
   (setq flyspell-pre-point  nil)
-  ;; we mark the mode as killed
+  ;; We mark the mode as killed.
   (setq flyspell-mode nil))
 
 ;;*---------------------------------------------------------------------*/
@@ -730,39 +735,49 @@ not the very same deplacement command."
   "Return non-nil if we should check the word before point.
 More precisely, it applies to the word that was before point
 before the current command."
-  (cond
-   ((or (not (numberp flyspell-pre-point))
-       (not (bufferp flyspell-pre-buffer))
-       (not (buffer-live-p flyspell-pre-buffer)))
-    nil)
-   ((and (eq flyspell-pre-pre-point flyspell-pre-point)
-        (eq flyspell-pre-pre-buffer flyspell-pre-buffer))
-    nil)
-   ((or (and (= flyspell-pre-point (- (point) 1))
-            (eq (char-syntax (char-after flyspell-pre-point)) ?w))
-       (= flyspell-pre-point (point))
-       (= flyspell-pre-point (+ (point) 1)))
-    nil)
-   ((and (symbolp this-command)
-        (not executing-kbd-macro)
-        (or (get this-command 'flyspell-delayed)
-            (and (get this-command 'flyspell-deplacement)
-                 (eq flyspell-previous-command this-command)))
-        (or (= (current-column) 0)
-            (= (current-column) flyspell-pre-column)
-            ;; If other post-command-hooks change the buffer,
-            ;; flyspell-pre-point can lie past eob (bug#468).
-            (null (char-after flyspell-pre-point))
-            (eq (char-syntax (char-after flyspell-pre-point)) ?w)))
-    nil)
-   ((not (eq (current-buffer) flyspell-pre-buffer))
-    t)
-   ((not (and (numberp flyspell-word-cache-start)
-             (numberp flyspell-word-cache-end)))
-    t)
-   (t
-    (or (< flyspell-pre-point flyspell-word-cache-start)
-       (> flyspell-pre-point flyspell-word-cache-end)))))
+  (let ((ispell-otherchars (ispell-get-otherchars)))
+    (cond
+   ((not (and (numberp flyspell-pre-point)
+              (buffer-live-p flyspell-pre-buffer)))
+      nil)
+     ((and (eq flyspell-pre-pre-point flyspell-pre-point)
+          (eq flyspell-pre-pre-buffer flyspell-pre-buffer))
+      nil)
+     ((or (and (= flyspell-pre-point (- (point) 1))
+              (or (eq (char-syntax (char-after flyspell-pre-point)) ?w)
+                  (and (not (string= "" ispell-otherchars))
+                       (string-match
+                        ispell-otherchars
+                        (buffer-substring-no-properties
+                         flyspell-pre-point (1+ flyspell-pre-point))))))
+         (= flyspell-pre-point (point))
+         (= flyspell-pre-point (+ (point) 1)))
+      nil)
+     ((and (symbolp this-command)
+          (not executing-kbd-macro)
+          (or (get this-command 'flyspell-delayed)
+              (and (get this-command 'flyspell-deplacement)
+                   (eq flyspell-previous-command this-command)))
+          (or (= (current-column) 0)
+              (= (current-column) flyspell-pre-column)
+              ;; If other post-command-hooks change the buffer,
+              ;; flyspell-pre-point can lie past eob (bug#468).
+              (null (char-after flyspell-pre-point))
+              (or (eq (char-syntax (char-after flyspell-pre-point)) ?w)
+                  (and (not (string= "" ispell-otherchars))
+                       (string-match
+                        ispell-otherchars
+                        (buffer-substring-no-properties
+                         flyspell-pre-point (1+ flyspell-pre-point)))))))
+      nil)
+     ((not (eq (current-buffer) flyspell-pre-buffer))
+      t)
+     ((not (and (numberp flyspell-word-cache-start)
+               (numberp flyspell-word-cache-end)))
+      t)
+     (t
+      (or (< flyspell-pre-point flyspell-word-cache-start)
+         (> flyspell-pre-point flyspell-word-cache-end))))))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    The flyspell after-change-hook, store the change position. In    */
@@ -783,21 +798,15 @@ before the current command."
 ;;*    flyspell-check-changed-word-p ...                                */
 ;;*---------------------------------------------------------------------*/
 (defun flyspell-check-changed-word-p (start stop)
-  "Return t when the changed word has to be checked.
+  "Return non-nil when the changed word has to be checked.
 The answer depends of several criteria.
 Mostly we check word delimiters."
-  (cond
-   ((and (memq (char-after start) '(?\n ? )) (> stop start))
-    t)
-   ((not (numberp flyspell-pre-point))
-    t)
-   ((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop))
-    nil)
-   ((let ((pos (point)))
-      (or (>= pos start) (<= pos stop) (= pos (1+ stop))))
-    nil)
-   (t
-    t)))
+  (not (and (not (and (memq (char-after start) '(?\n ? )) (> stop start)))
+            (numberp flyspell-pre-point)
+            (or
+             (and (>= flyspell-pre-point start) (<= flyspell-pre-point stop))
+             (let ((pos (point)))
+               (or (>= pos start) (<= pos stop) (= pos (1+ stop))))))))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-check-word-p ...                                        */
@@ -806,30 +815,33 @@ Mostly we check word delimiters."
   "Return t when the word at `point' has to be checked.
 The answer depends of several criteria.
 Mostly we check word delimiters."
-  (cond
-   ((<= (- (point-max) 1) (point-min))
-    ;; the buffer is not filled enough
-    nil)
-   ((and (and (> (current-column) 0)
-             (not (eq (current-column) flyspell-pre-column)))
-        (save-excursion
-          (backward-char 1)
-          (and (looking-at (flyspell-get-not-casechars))
-               (or flyspell-consider-dash-as-word-delimiter-flag
-                   (not (looking-at "-"))))))
-    ;; yes because we have reached or typed a word delimiter.
-    t)
-   ((symbolp this-command)
+  (let ((ispell-otherchars (ispell-get-otherchars)))
     (cond
-     ((get this-command 'flyspell-deplacement)
-      (not (eq flyspell-previous-command this-command)))
-     ((get this-command 'flyspell-delayed)
-      ;; the current command is not delayed, that
-      ;; is that we must check the word now
-      (and (not unread-command-events)
-          (sit-for flyspell-delay)))
-     (t t)))
-   (t t)))
+     ((<= (- (point-max) 1) (point-min))
+      ;; The buffer is not filled enough.
+      nil)
+     ((and (and (> (current-column) 0)
+               (not (eq (current-column) flyspell-pre-column)))
+          (save-excursion
+            (backward-char 1)
+            (and (looking-at (flyspell-get-not-casechars))
+                 (or (string= "" ispell-otherchars)
+                     (not (looking-at ispell-otherchars)))
+                 (or flyspell-consider-dash-as-word-delimiter-flag
+                     (not (looking-at "-"))))))
+      ;; Yes because we have reached or typed a word delimiter.
+      t)
+     ((symbolp this-command)
+      (cond
+       ((get this-command 'flyspell-deplacement)
+       (not (eq flyspell-previous-command this-command)))
+       ((get this-command 'flyspell-delayed)
+       ;; The current command is not delayed, that
+       ;; is that we must check the word now.
+       (and (not unread-command-events)
+            (sit-for flyspell-delay)))
+       (t t)))
+     (t t))))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-debug-signal-no-check ...                               */
@@ -859,52 +871,55 @@ Mostly we check word delimiters."
 ;;*---------------------------------------------------------------------*/
 (defun flyspell-debug-signal-word-checked ()
   (setq debug-on-error t)
-  (let ((oldbuf (current-buffer))
+  (let ((ispell-otherchars (ispell-get-otherchars))
+       (oldbuf (current-buffer))
         (point  (point)))
     (with-current-buffer (get-buffer-create "*flyspell-debug*")
-      (insert "WORD:\n")
-      (insert (format "  this-cmd   : %S\n" this-command))
-      (insert (format "  delayed    : %S\n" (and (symbolp this-command)
-                                                (get this-command 'flyspell-delayed))))
-      (insert (format "  point      : %S\n" point))
-      (insert (format "  prev-char  : [%c] %S\n"
-                     (with-current-buffer oldbuf
-                       (let ((c (if (> (point) (point-min))
-                                    (save-excursion
-                                      (backward-char 1)
-                                      (char-after (point)))
-                                  ? )))
-                         c))
-                     (with-current-buffer oldbuf
-                       (let ((c (if (> (point) (point-min))
-                                    (save-excursion
-                                      (backward-char 1)
-                                      (and (and (looking-at (flyspell-get-not-casechars)) 1)
-                                           (and (or flyspell-consider-dash-as-word-delimiter-flag
-                                                    (not (looking-at "\\-"))) 2))))))
-                         c))))
-      (insert (format "  because    : %S\n"
-                     (cond
-                      ((not (and (symbolp this-command)
-                                 (get this-command 'flyspell-delayed)))
-                       ;; the current command is not delayed, that
-                       ;; is that we must check the word now
-                       'not-delayed)
-                      ((with-current-buffer oldbuf
-                         (let ((c (if (> (point) (point-min))
-                                      (save-excursion
-                                        (backward-char 1)
-                                        (and (looking-at (flyspell-get-not-casechars))
-                                             (or flyspell-consider-dash-as-word-delimiter-flag
-                                                 (not (looking-at "\\-"))))))))
-                           c))
-                       ;; yes because we have reached or typed a word delimiter.
-                       'separator)
-                      ((not (integerp flyspell-delay))
-                       ;; yes because the user had set up a no-delay configuration.
-                       'no-delay)
-                      (t
-                       'sit-for))))
+      (insert
+       "WORD:\n"
+       (format "  this-cmd   : %S\n" this-command)
+       (format "  delayed    : %S\n" (and (symbolp this-command)
+                                          (get this-command
+                                               'flyspell-delayed)))
+       (format "  point      : %S\n" point)
+       (format "  prev-char  : [%c] %S\n"
+               (with-current-buffer oldbuf
+                 (if (bobp) ?\  (char-before)))
+               (with-current-buffer oldbuf
+                 (if (bobp)
+                     nil
+                   (save-excursion
+                     (backward-char 1)
+                     (and (looking-at (flyspell-get-not-casechars))
+                          (or (string= "" ispell-otherchars)
+                              (not (looking-at ispell-otherchars)))
+                          (or flyspell-consider-dash-as-word-delimiter-flag
+                              (not (looking-at "\\-")))
+                          2)))))
+       (format "  because    : %S\n"
+               (cond
+                ((not (and (symbolp this-command)
+                           (get this-command 'flyspell-delayed)))
+                 ;; The current command is not delayed, that
+                 ;; is that we must check the word now.
+                 'not-delayed)
+                ((with-current-buffer oldbuf
+                   (if (bobp)
+                       nil
+                     (save-excursion
+                       (backward-char 1)
+                       (and (looking-at (flyspell-get-not-casechars))
+                            (or (string= "" ispell-otherchars)
+                                (not (looking-at ispell-otherchars)))
+                            (or flyspell-consider-dash-as-word-delimiter-flag
+                                (not (looking-at "\\-")))))))
+                 ;; Yes because we have reached or typed a word delimiter.
+                 'separator)
+                ((not (integerp flyspell-delay))
+                 ;; Yes because the user set up a no-delay configuration.
+                 'no-delay)
+                (t
+                 'sit-for))))
       (goto-char (point-max)))))
 
 ;;*---------------------------------------------------------------------*/
@@ -927,7 +942,7 @@ Mostly we check word delimiters."
 ;;*    2- the word that used to be the current word before the          */
 ;;*       THIS-COMMAND is checked if:                                   */
 ;;*        a- the previous word is different from the current word      */
-;;*        b- the previous word as not just been checked by the         */
+;;*        b- the previous word has not just been checked by the        */
 ;;*           previous FLYSPELL-POST-COMMAND-HOOK                       */
 ;;*    3- the words changed by the THIS-COMMAND that are neither the    */
 ;;*       previous word nor the current word                            */
@@ -954,7 +969,7 @@ Mostly we check word delimiters."
               ;; we remember which word we have just checked.
               ;; this will be used next time we will check a word
               ;; to compare the next current word with the word
-              ;; that as been registered in the pre-command-hook
+              ;; that has been registered in the pre-command-hook
               ;; that is these variables are used within the predicate
               ;; FLYSPELL-CHECK-PRE-WORD-P
               (setq flyspell-pre-pre-buffer (current-buffer))
@@ -1104,7 +1119,9 @@ misspelling and skips redundant spell-checking step."
                   (ispell-send-string (concat "^" word "\n"))
                   ;; we mark the ispell process so it can be killed
                   ;; when emacs is exited without query
-                  (set-process-query-on-exit-flag ispell-process nil)
+                 (if (featurep 'xemacs)
+                     (process-kill-without-query ispell-process)
+                   (set-process-query-on-exit-flag ispell-process nil))
                   ;; Wait until ispell has processed word.
                   (while (progn
                            (accept-process-output ispell-process)
@@ -1221,63 +1238,8 @@ misspelling and skips redundant spell-checking step."
                        (>= (match-end 0) b))))))
       (flyspell-math-tex-command-p)))
 
-;;*---------------------------------------------------------------------*/
-;;*    flyspell-casechars-cache ...                                     */
-;;*---------------------------------------------------------------------*/
-(defvar flyspell-casechars-cache nil)
-(defvar flyspell-ispell-casechars-cache nil)
-(make-variable-buffer-local 'flyspell-casechars-cache)
-(make-variable-buffer-local 'flyspell-ispell-casechars-cache)
-
-;;*---------------------------------------------------------------------*/
-;;*    flyspell-get-casechars ...                                       */
-;;*---------------------------------------------------------------------*/
-(defun flyspell-get-casechars ()
-  "This function builds a string that is the regexp of word chars.
-In order to avoid one useless string construction,
-this function changes the last char of the `ispell-casechars' string."
-  (let ((ispell-casechars (ispell-get-casechars)))
-    (cond
-     ((eq ispell-parser 'tex)
-      (setq flyspell-ispell-casechars-cache ispell-casechars)
-      (setq flyspell-casechars-cache
-           (concat (substring ispell-casechars
-                              0
-                              (- (length ispell-casechars) 1))
-                   "]"))
-      flyspell-casechars-cache)
-     (t
-      (setq flyspell-ispell-casechars-cache ispell-casechars)
-      (setq flyspell-casechars-cache ispell-casechars)
-      flyspell-casechars-cache))))
-
-;;*---------------------------------------------------------------------*/
-;;*    flyspell-get-not-casechars-cache ...                             */
-;;*---------------------------------------------------------------------*/
-(defvar flyspell-not-casechars-cache nil)
-(defvar flyspell-ispell-not-casechars-cache nil)
-(make-variable-buffer-local 'flyspell-not-casechars-cache)
-(make-variable-buffer-local 'flyspell-ispell-not-casechars-cache)
-
-;;*---------------------------------------------------------------------*/
-;;*    flyspell-get-not-casechars ...                                   */
-;;*---------------------------------------------------------------------*/
-(defun flyspell-get-not-casechars ()
-  "This function builds a string that is the regexp of non-word chars."
-  (let ((ispell-not-casechars (ispell-get-not-casechars)))
-    (cond
-     ((eq ispell-parser 'tex)
-      (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
-      (setq flyspell-not-casechars-cache
-           (concat (substring ispell-not-casechars
-                              0
-                              (- (length ispell-not-casechars) 1))
-                   "]"))
-      flyspell-not-casechars-cache)
-     (t
-      (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
-      (setq flyspell-not-casechars-cache ispell-not-casechars)
-      flyspell-not-casechars-cache))))
+(defalias 'flyspell-get-casechars 'ispell-get-casechars)
+(defalias 'flyspell-get-not-casechars 'ispell-get-not-casechars)
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-get-word ...                                            */
@@ -1414,7 +1376,7 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
            (goto-char buffer-scan-pos)
            (let ((keep t))
              ;; Iterate on string search until string is found as word,
-             ;; not as substring
+             ;; not as substring.
              (while keep
                (if (search-forward word
                                    flyspell-large-region-end t)
@@ -1430,13 +1392,14 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
                      (when (or
                             ;; Size matches, we really found it.
                             (= found-length misspell-length)
-                            ;; Matches as part of a boundary-char separated word
+                            ;; Matches as part of a boundary-char separated
+                            ;; word.
                             (member word
                                     (split-string found ispell-otherchars))
                             ;; Misspelling has higher length than
-                            ;; what flyspell considers the
-                            ;; word.  Caused by boundary-chars
-                            ;; mismatch.  Validating seems safe.
+                            ;; what flyspell considers the word.
+                             ;; Caused by boundary-chars mismatch.
+                             ;; Validating seems safe.
                             (< found-length misspell-length)
                             ;; ispell treats beginning of some TeX
                             ;; commands as nroff control sequences
@@ -1479,7 +1442,8 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
 ;;*    declared correct.                                                */
 ;;*---------------------------------------------------------------------*/
 (defun flyspell-process-localwords (misspellings-buffer)
-  (let (localwords case-fold-search
+  (let ((localwords ispell-buffer-session-localwords)
+       case-fold-search
        (ispell-casechars (ispell-get-casechars)))
     ;; Get localwords from the original buffer
     (save-excursion
@@ -1576,10 +1540,11 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
       (if ispell-encoding8-command
          (setq args
                (append args
-                       (list
-                        (concat ispell-encoding8-command
-                                (symbol-name
-                                 encoding))))))
+                       (if ispell-really-hunspell
+                           (list ispell-encoding8-command
+                                 (upcase (symbol-name encoding)))
+                         (list (concat ispell-encoding8-command
+                                       (symbol-name encoding)))))))
 
       (let ((process-coding-system-alist (list (cons "\\.*" encoding))))
        (setq c (apply 'ispell-call-process-region beg
@@ -1690,12 +1655,19 @@ FLYSPELL-BUFFER."
 ;;*---------------------------------------------------------------------*/
 (defun flyspell-delete-region-overlays (beg end)
   "Delete overlays used by flyspell in a given region."
-  (remove-overlays beg end 'flyspell-overlay t))
-
+  (if (featurep 'emacs)
+      (remove-overlays beg end 'flyspell-overlay t)
+    ;; XEmacs does not have `remove-overlays'
+    (let ((l (overlays-in beg end)))
+      (while (consp l)
+       (progn
+         (if (flyspell-overlay-p (car l))
+             (delete-overlay (car l)))
+         (setq l (cdr l)))))))
 
 (defun flyspell-delete-all-overlays ()
   "Delete all the overlays used by flyspell."
-  (remove-overlays (point-min) (point-max) 'flyspell-overlay t))
+  (flyspell-delete-region-overlays (point-min) (point-max)))
 
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-unhighlight-at ...                                      */
@@ -1899,11 +1871,11 @@ This command proposes various successive corrections for the current word."
   (interactive)
   (let ((pos     (point))
        (old-max (point-max)))
-    ;; use the correct dictionary
+    ;; Use the correct dictionary.
     (flyspell-accept-buffer-local-defs)
     (if (and (eq flyspell-auto-correct-pos pos)
             (consp flyspell-auto-correct-region))
-       ;; we have already been using the function at the same location
+       ;; We have already been using the function at the same location.
        (let* ((start (car flyspell-auto-correct-region))
               (len   (cdr flyspell-auto-correct-region)))
          (flyspell-unhighlight-at start)
@@ -1925,7 +1897,7 @@ This command proposes various successive corrections for the current word."
            (flyspell-display-next-corrections flyspell-auto-correct-ring))
          (flyspell-ajust-cursor-point pos (point) old-max)
          (setq flyspell-auto-correct-pos (point)))
-      ;; fetch the word to be checked
+      ;; Fetch the word to be checked.
       (let ((word (flyspell-get-word)))
        (if (consp word)
            (let ((start (car (cdr word)))
@@ -1933,30 +1905,30 @@ This command proposes various successive corrections for the current word."
                  (word (car word))
                  poss ispell-filter)
              (setq flyspell-auto-correct-word word)
-             ;; now check spelling of word.
-             (ispell-send-string "%\n") ;put in verbose mode
+             ;; Now check spelling of word..
+             (ispell-send-string "%\n") ;Put in verbose mode.
              (ispell-send-string (concat "^" word "\n"))
-              ;; wait until ispell has processed word.
+              ;; Wait until ispell has processed word.
               (while (progn
                        (accept-process-output ispell-process)
                        (not (string= "" (car ispell-filter)))))
-             ;; Remove leading empty element
+             ;; Remove leading empty element.
              (setq ispell-filter (cdr ispell-filter))
-             ;; ispell process should return something after word is sent.
-             ;; Tag word as valid (i.e., skip) otherwise
+             ;; Ispell process should return something after word is sent.
+             ;; Tag word as valid (i.e., skip) otherwise.
              (or ispell-filter
                  (setq ispell-filter '(*)))
              (if (consp ispell-filter)
                  (setq poss (ispell-parse-output (car ispell-filter))))
              (cond
               ((or (eq poss t) (stringp poss))
-               ;; don't correct word
+               ;; Don't correct word.
                t)
               ((null poss)
-               ;; ispell error
+               ;; Ispell error.
                (error "Ispell: error in Ispell process"))
               (t
-               ;; the word is incorrect, we have to propose a replacement
+               ;; The word is incorrect, we have to propose a replacement.
                (let ((replacements (if flyspell-sort-corrections
                                        (sort (car (cdr (cdr poss))) 'string<)
                                      (car (cdr (cdr poss))))))
@@ -2146,6 +2118,9 @@ If OPOINT is non-nil, restore point there after adjusting it for replacement."
         (setq ispell-pdict-modified-p '(t)))
        ((or (eq replace 'buffer) (eq replace 'session))
         (ispell-send-string (concat "@" word "\n"))
+        (add-to-list 'ispell-buffer-session-localwords word)
+        (or ispell-buffer-local-name ; session localwords might conflict
+            (setq ispell-buffer-local-name (buffer-name)))
         (flyspell-unhighlight-at cursor-location)
         (if (null ispell-pdict-modified-p)
             (setq ispell-pdict-modified-p