;;; flyspell.el --- on-the-fly spell checker
;; Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007 Free Software Foundation, Inc.
+;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Author: Manuel Serrano <Manuel.Serrano@sophia.inria.fr>
;; Maintainer: FSF
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
(defcustom flyspell-mark-duplications-flag t
"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'."
:group 'flyspell
:type 'boolean)
+(defcustom flyspell-mark-duplications-exceptions
+ '(("francais" . ("nous" "vous")))
+ "A list of exceptions for duplicated words.
+It should be a list of (LANGUAGE . EXCEPTION-LIST). LANGUAGE is matched
+against the current dictionary and EXCEPTION-LIST is a list of strings.
+The duplicated word is downcased before it is compared with the exceptions."
+ :group 'flyspell
+ :type '(alist :key-type string :value-type (repeat string)))
+
(defcustom flyspell-sort-corrections nil
"Non-nil means, sort the corrections alphabetically before popping them."
:group 'flyspell
0 means do not search for duplicate unrecognized spellings."
:group 'flyspell
:version "21.1"
- :type 'number)
+ :type '(choice (const :tag "no limit" -1)
+ number))
(defcustom flyspell-delay 3
"The number of seconds to wait before checking, after a \"delayed\" command."
;;*--- mail mode -------------------------------------------------------*/
(put 'mail-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
(put 'message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
+(defvar message-signature-separator)
(defun mail-mode-flyspell-verify ()
"Function used for `flyspell-generic-check-word-predicate' in Mail mode."
(let ((header-end (save-excursion
;;*--- sgml mode -------------------------------------------------------*/
(put 'sgml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
(put 'html-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
+(put 'nxml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
(defun sgml-mode-flyspell-verify ()
"Function used for `flyspell-generic-check-word-predicate' in SGML mode."
This spawns a single Ispell process and checks each word.
The default flyspell behavior is to highlight incorrect words.
With no argument, this command toggles Flyspell mode.
-With a prefix argument ARG, turn Flyspell minor mode on iff ARG is positive.
+With a prefix argument ARG, turn Flyspell minor mode on if ARG is positive,
+otherwise turn it off.
Bindings:
\\[ispell-word]: correct words (using Ispell).
\\[flyspell-correct-word] (or down-mouse-2): popup correct words.
Hooks:
-This runs `flyspell-mode-hook' after flyspell is entered.
+This runs `flyspell-mode-hook' after flyspell mode is entered or exit.
Remark:
`flyspell-mode' uses `ispell-mode'. Thus all Ispell options are
:keymap flyspell-mode-map
:group 'flyspell
(if flyspell-mode
- (flyspell-mode-on)
+ (condition-case ()
+ (flyspell-mode-on)
+ (error (message "Enabling Flyspell mode gave an error")
+ (flyspell-mode -1)))
(flyspell-mode-off)))
;;;###autoload
;;*---------------------------------------------------------------------*/
(defun flyspell-mode-on ()
"Turn Flyspell mode on. Do not use this; use `flyspell-mode' instead."
- (ispell-maybe-find-aspell-dictionaries)
+ (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
(setq ispell-highlight-face 'flyspell-incorrect)
;; local dictionaries setup
(or ispell-local-dictionary ispell-dictionary
(if binding
(format "Welcome to flyspell. Use %s or Mouse-2 to correct words."
(key-description binding))
- "Welcome to flyspell. Use Mouse-2 to correct words."))))
- ;; we end with the flyspell hooks
- (run-hooks 'flyspell-mode-hook))
+ "Welcome to flyspell. Use Mouse-2 to correct words.")))))
;;*---------------------------------------------------------------------*/
;;* flyspell-delay-commands ... */
;;*---------------------------------------------------------------------*/
(defun flyspell-delay-commands ()
"Install the standard set of Flyspell delayed commands."
- (mapcar 'flyspell-delay-command flyspell-default-delayed-commands)
+ (mapc 'flyspell-delay-command flyspell-default-delayed-commands)
(mapcar 'flyspell-delay-command flyspell-delayed-commands))
;;*---------------------------------------------------------------------*/
;;*---------------------------------------------------------------------*/
(defun flyspell-deplacement-commands ()
"Install the standard set of Flyspell deplacement commands."
- (mapcar 'flyspell-deplacement-command flyspell-default-deplacement-commands)
+ (mapc 'flyspell-deplacement-command flyspell-default-deplacement-commands)
(mapcar 'flyspell-deplacement-command flyspell-deplacement-commands))
;;*---------------------------------------------------------------------*/
(defun flyspell-word (&optional following)
"Spell check a word."
(interactive (list ispell-following-word))
+ (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
(save-excursion
;; use the correct dictionary
(flyspell-accept-buffer-local-defs)
(and (> start (point-min))
(not (memq (char-after (1- start)) '(?\} ?\\)))))
flyspell-mark-duplications-flag
+ (not (catch 'exception
+ (dolist (except flyspell-mark-duplications-exceptions)
+ (and (string= (or ispell-local-dictionary
+ ispell-dictionary)
+ (car except))
+ (member (downcase word) (cdr except))
+ (throw 'exception t)))))
(save-excursion
(goto-char start)
(let* ((bound
;; this is done, we can start checking...
(if flyspell-issue-message-flag (message "Checking region..."))
(set-buffer curbuf)
- (ispell-check-version)
- (let ((c (apply 'ispell-call-process-region beg
- end
- ispell-program-name
- nil
- buffer
- nil
- (if ispell-really-aspell "list" "-l")
- (let (args)
- ;; Local dictionary becomes the global dictionary in use.
- (if ispell-local-dictionary
- (setq ispell-dictionary ispell-local-dictionary))
- (setq args (ispell-get-ispell-args))
- (if ispell-dictionary ; use specified dictionary
- (setq args
- (append (list "-d" ispell-dictionary) args)))
- (if ispell-personal-dictionary ; use specified pers dict
- (setq args
- (append args
- (list "-p"
- (expand-file-name
- ispell-personal-dictionary)))))
- (setq args (append args ispell-extra-args))
- args))))
+ (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
+ ;; Local dictionary becomes the global dictionary in use.
+ (setq ispell-current-dictionary
+ (or ispell-local-dictionary ispell-dictionary))
+ (setq ispell-current-personal-dictionary
+ (or ispell-local-pdict ispell-personal-dictionary))
+ (let ((args (ispell-get-ispell-args))
+ (encoding (ispell-get-coding-system))
+ c)
+ (if (and ispell-current-dictionary ; use specified dictionary
+ (not (member "-d" args))) ; only define if not overridden
+ (setq args
+ (append (list "-d" ispell-current-dictionary) args)))
+ (if ispell-current-personal-dictionary ; use specified pers dict
+ (setq args
+ (append args
+ (list "-p"
+ (expand-file-name
+ ispell-current-personal-dictionary)))))
+ (setq args (append args ispell-extra-args))
+ (if (and ispell-really-aspell
+ ispell-aspell-supports-utf8)
+ (setq args
+ (append args
+ (list
+ (concat "--encoding="
+ (symbol-name
+ encoding))))))
+ (let ((process-coding-system-alist (list (cons "\\.*" encoding))))
+ (setq c (apply 'ispell-call-process-region beg
+ end
+ ispell-program-name
+ nil
+ buffer
+ nil
+ (if ispell-really-aspell "list" "-l")
+ args)))
(if (eq c 0)
(progn
(flyspell-process-localwords buffer)
(defun flyspell-region (beg end)
"Flyspell text between BEG and END."
(interactive "r")
+ (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
(if (= beg end)
()
(save-excursion
;;* flyspell-overlay-p ... */
;;*---------------------------------------------------------------------*/
(defun flyspell-overlay-p (o)
- "A predicate that return true iff O is an overlay used by flyspell."
+ "Return true if O is an overlay used by flyspell."
(and (overlayp o) (overlay-get o 'flyspell-overlay)))
;;*---------------------------------------------------------------------*/
But don't look beyond what's visible on the screen."
(interactive "d")
- (let (top bot)
- (save-excursion
- (move-to-window-line 0)
- (setq top (point))
- (move-to-window-line -1)
- (setq bot (point)))
+ (let ((top (window-start))
+ (bot (window-end)))
(save-excursion
(save-restriction
(narrow-to-region top bot)
(error "Pop-up menus do not work on this terminal"))
;; use the correct dictionary
(flyspell-accept-buffer-local-defs)
+ (or opoint (setq opoint (point-marker)))
(let ((cursor-location (point))
(word (flyspell-get-word nil)))
(if (consp word)
;;*---------------------------------------------------------------------*/
(defun flyspell-emacs-popup (event poss word)
"The Emacs popup menu."
+ (unless window-system
+ (error "This command requires pop-up dialogs"))
(if (not event)
(let* ((mouse-pos (mouse-position))
(mouse-pos (if (nth 1 mouse-pos)