Merge from emacs-23
[bpt/emacs.git] / lisp / textmodes / flyspell.el
index 7b77874..64f77d0 100644 (file)
@@ -199,9 +199,9 @@ Ispell's ultimate default dictionary."
 
 (defcustom flyspell-check-tex-math-command nil
   "Non-nil means check even inside TeX math environment.
-TeX math environments are discovered by the TEXMATHP that implemented
-inside the texmathp.el Emacs package.  That package may be found at:
-http://strw.leidenuniv.nl/~dominik/Tools"
+TeX math environments are discovered by `texmathp', implemented
+inside AUCTeX package.  That package may be found at
+URL `http://www.gnu.org/software/auctex/'"
   :group 'flyspell
   :type 'boolean)
 
@@ -380,7 +380,8 @@ like <img alt=\"Some thing.\">."
 
 (defun flyspell-generic-progmode-verify ()
   "Used for `flyspell-generic-check-word-predicate' in programming modes."
-  (let ((f (get-text-property (point) 'face)))
+  ;; (point) is next char after the word. Must check one char before.
+  (let ((f (get-text-property (- (point) 1) 'face)))
     (memq f flyspell-prog-text-faces)))
 
 ;;;###autoload
@@ -494,9 +495,9 @@ in your .emacs file.
   :keymap flyspell-mode-map
   :group 'flyspell
   (if flyspell-mode
-      (condition-case ()
+      (condition-case err
          (flyspell-mode-on)
-       (error (message "Enabling Flyspell mode gave an error")
+       (error (message "Error enabling Flyspell mode:\n%s" (cdr err))
               (flyspell-mode -1)))
     (flyspell-mode-off)))
 
@@ -1013,11 +1014,13 @@ Mostly we check word delimiters."
 ;;*---------------------------------------------------------------------*/
 ;;*    flyspell-word ...                                                */
 ;;*---------------------------------------------------------------------*/
-(defun flyspell-word (&optional following)
+(defun flyspell-word (&optional following known-misspelling)
   "Spell check a word.
 If the optional argument FOLLOWING, or, when called interactively
 `ispell-following-word', is non-nil, checks the following (rather
-than preceding) word when the cursor is not over a word."
+than preceding) word when the cursor is not over a word.  If
+optional argument KNOWN-MISSPELLING is non nil considers word a
+misspelling and skips redundant spell-checking step."
   (interactive (list ispell-following-word))
   (ispell-set-spellchecker-params)    ; Initialize variables and dicts alists
   (save-excursion
@@ -1078,29 +1081,35 @@ than preceding) word when the cursor is not over a word."
            (setq flyspell-word-cache-end end)
            (setq flyspell-word-cache-word word)
            ;; now check spelling of word.
-           (ispell-send-string "%\n")
-           ;; put in verbose mode
-           (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)
-           ;; Wait until ispell has processed word.  Since this code is often
-            ;; executed from post-command-hook but the ispell process may not
-            ;; be responsive, it's important to make sure we re-enable C-g.
-           (with-local-quit
-             (while (progn
-                      (accept-process-output ispell-process)
-                      (not (string= "" (car ispell-filter))))))
-           ;; (ispell-send-string "!\n")
-           ;; back to terse mode.
-           ;; 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
-           (or ispell-filter
-               (setq ispell-filter '(*)))
-           (if (consp ispell-filter)
-               (setq poss (ispell-parse-output (car ispell-filter))))
+            (if (not known-misspelling)
+                (progn
+                  (ispell-send-string "%\n")
+                  ;; put in verbose mode
+                  (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)
+                  ;; Wait until ispell has processed word.  Since this
+                  ;; code is often executed from post-command-hook but
+                  ;; the ispell process may not be responsive, it's
+                  ;; important to make sure we re-enable C-g.
+                  (with-local-quit
+                    (while (progn
+                             (accept-process-output ispell-process)
+                             (not (string= "" (car ispell-filter))))))
+                  ;; (ispell-send-string "!\n")
+                  ;; back to terse mode.
+                  ;; 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
+                  (or ispell-filter
+                      (setq ispell-filter '(*)))
+                  (if (consp ispell-filter)
+                      (setq poss (ispell-parse-output (car ispell-filter)))))
+              ;; Else, this was a known misspelling to begin with, and
+              ;; we should forge an ispell return value.
+              (setq poss (list word 0 '() '())))
            (let ((res (cond ((eq poss t)
                              ;; correct
                              (setq flyspell-word-cache-result t)
@@ -1433,7 +1442,7 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
                                        t
                                      nil))))
                        (setq keep nil)
-                       (flyspell-word)
+                       (flyspell-word nil t)
                        ;; Search for next misspelled word will begin from
                        ;; end of last validated match.
                        (setq buffer-scan-pos (point))))
@@ -1465,7 +1474,7 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
       (goto-char (point-min))
       ;; Localwords parsing copied from ispell.el.
       (while (search-forward ispell-words-keyword nil t)
-       (let ((end (save-excursion (end-of-line) (point)))
+       (let ((end (point-at-eol))
              string)
          ;; buffer-local words separated by a space, and can contain
          ;; any character other than a space.  Not rigorous enough.
@@ -1817,7 +1826,9 @@ misspelled words backwards."
                        (throw 'exit t)))))))
        (save-excursion
          (goto-char pos)
-         (ispell-word))
+         (ispell-word)
+         (setq flyspell-word-cache-word nil) ;; Force flyspell-word re-check
+         (flyspell-word))
       (error "No word to correct before point"))))
 
 ;;*---------------------------------------------------------------------*/
@@ -2352,5 +2363,4 @@ This function is meant to be added to `flyspell-incorrect-hook'."
 
 (provide 'flyspell)
 
-;; arch-tag: 05d915b9-e9cf-44fb-9137-fc28f5eaab2a
 ;;; flyspell.el ends here