diff --git a/Makefile b/Makefile index b8e8e9ccfa93f98051a5a27a8e3bd680c996f82d_TWFrZWZpbGU=..3fb0476970d675280d434564e629a8efd8786ab9_TWFrZWZpbGU= 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ # This XEmacs package contains independent single file lisp packages -VERSION = 1.12 +VERSION = 1.13 AUTHOR_VERSION = MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org> PACKAGE = text-modes diff --git a/flyspell.el b/flyspell.el index b8e8e9ccfa93f98051a5a27a8e3bd680c996f82d_Zmx5c3BlbGwuZWw=..3fb0476970d675280d434564e629a8efd8786ab9_Zmx5c3BlbGwuZWw= 100644 --- a/flyspell.el +++ b/flyspell.el @@ -26,7 +26,12 @@ ;; ;; Flyspell is a minor Emacs mode performing on-the-fly spelling ;; checking. +;; +;; To install flyspell, add this to your ~/.emacs file: +;; +;; (autoload 'flyspell-mode "flyspell" "On-the-fly spelling checking" t) +;; (autoload 'global-flyspell-mode "flyspell" "On-the-fly spelling" t) ;; ;; To enable Flyspell minor mode, type Meta-x flyspell-mode. ;; This applies only to the current buffer. ;; @@ -29,10 +34,15 @@ ;; ;; To enable Flyspell minor mode, type Meta-x flyspell-mode. ;; This applies only to the current buffer. ;; +;; Or if you want to turn Flyspell mode on in many buffers, add this to +;; you ~/.emacs file: +;; +;; (global-flyspell-mode t) +;; ;; Note: consider setting the variable ispell-parser to `tex' to ;; avoid TeX command checking; use `(setq ispell-parser 'tex)' ;; _before_ entering flyspell. ;; ;; Some user variables control the behavior of flyspell. They are ;; those defined under the `User variables' comment. @@ -33,13 +43,9 @@ ;; Note: consider setting the variable ispell-parser to `tex' to ;; avoid TeX command checking; use `(setq ispell-parser 'tex)' ;; _before_ entering flyspell. ;; ;; Some user variables control the behavior of flyspell. They are ;; those defined under the `User variables' comment. -;; -;; Note: as suggested by Yaron M. Minsky, if you use flyspell when -;; sending mails, you should add the following: -;; (add-hook 'mail-send-hook 'flyspell-mode-off) ;;; Code: (require 'ispell) @@ -51,7 +57,6 @@ "Spellchecking on the fly." :tag "FlySpell" :prefix "flyspell-" - :group 'processes - :version "20.3") + :group 'processes) ;*---------------------------------------------------------------------*/ @@ -56,6 +61,6 @@ ;*---------------------------------------------------------------------*/ -;* User variables ... */ +;* User configuration ... */ ;*---------------------------------------------------------------------*/ (defcustom flyspell-highlight-flag t "*How Flyspell should indicate misspelled words. @@ -73,7 +78,7 @@ :group 'flyspell :type 'boolean) -(defcustom flyspell-duplicate-distance 10000 +(defcustom flyspell-duplicate-distance -1 "*The maximum distance for finding duplicates of unrecognized words. This applies to the feature that when a word is not found in the dictionary, if the same spelling occurs elsewhere in the buffer, @@ -104,6 +109,7 @@ (defcustom flyspell-default-delayed-commands '(self-insert-command delete-backward-char + backward-or-forward-delete-char delete-char) "The standard list of delayed commands for Flyspell. See `flyspell-delayed-commands'." @@ -122,14 +128,9 @@ :group 'flyspell :type 'boolean) -(defcustom flyspell-consider-dash-as-word-delimiter-flag nil - "*Non-nil means that the `-' char is considered as a word delimiter." - :group 'flyspell - :type 'boolean) - (defcustom flyspell-incorrect-hook nil "*List of functions to be called when incorrect words are encountered. Each function is given two arguments: the beginning and the end of the incorrect region." :group 'flyspell) @@ -130,11 +131,13 @@ (defcustom flyspell-incorrect-hook nil "*List of functions to be called when incorrect words are encountered. Each function is given two arguments: the beginning and the end of the incorrect region." :group 'flyspell) -(defcustom flyspell-multi-language-p t - "*Non-nil means that Flyspell can be used with multiple languages. -This mode works by starting a separate Ispell process for each buffer, -so that each buffer can use its own language." +(defcustom flyspell-default-dictionary "american" + "A string that is the name of the default dictionary. +This is passed to the ispell-change-dictionary when flyspell is started. +If the variables ispell-local-dictionary or ispell-dictionary are non nil +when flyspell is started, the value of that variables is used instead +of flyspell-default-dictionary to select the default dictionary." :group 'flyspell @@ -140,5 +143,30 @@ :group 'flyspell - :type 'boolean) + :type 'string) + +(defcustom flyspell-global-modes t + "*Modes for which Flyspell mode is automagically turned on. +Global Flyspell mode is controlled by the `global-flyspell-mode' command. +If nil, means no modes have Flyspell mode automatically turned on. +If t, all modes have it automatically turned on. +If a list, it should be a list of `major-mode' symbol names for which Flyspell +mode should be automatically turned on. The sense of the list is negated if it +begins with `not'. For example: + (tex-mode mail-mode) +means that Flyspell mode is turned on for buffers in tex and mail-mode +modes only." + :type '(choice (const :tag "none" nil) + (const :tag "all" t) + (set :menu-tag "mode specific" :tag "modes" + :value (not) + (const :tag "Except" not) + (repeat :inline t (symbol :tag "mode")))) + :group 'flyspell) + +(defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter + '("francais" "deutsch8") + "List of dictionary names that consider `-' as word delimiter." + :group 'flyspell + :type '(repeat (string))) ;;;###autoload (defcustom flyspell-mode-line-string " Fly" @@ -213,7 +241,6 @@ ;*---------------------------------------------------------------------*/ ;* The minor mode declaration. */ ;*---------------------------------------------------------------------*/ -;;;###autoload (defvar flyspell-mode nil) (make-variable-buffer-local 'flyspell-mode) @@ -217,7 +244,6 @@ (defvar flyspell-mode nil) (make-variable-buffer-local 'flyspell-mode) -;;;###autoload (defvar flyspell-mode-map (make-sparse-keymap)) (defvar flyspell-mouse-map (make-sparse-keymap)) @@ -254,7 +280,16 @@ (if (string-match "19.*XEmacs" emacs-version) 'keymap 'local-map)) - + +;; dash character machinery +(defvar flyspell-consider-dash-as-word-delimiter-flag nil + "*Non-nil means that the `-' char is considered as a word delimiter.") +(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag) +(defvar flyspell-dash-dictionary nil) +(make-variable-buffer-local 'flyspell-dash-dictionary) +(defvar flyspell-dash-local-dictionary nil) +(make-variable-buffer-local 'flyspell-dash-local-dictionary) + ;*---------------------------------------------------------------------*/ ;* Highlighting */ ;*---------------------------------------------------------------------*/ @@ -284,9 +319,15 @@ With no argument, this command toggles Flyspell mode. With a prefix argument ARG, turn Flyspell minor mode on iff ARG is positive. +Alternatively, you can use Global Flyspell mode to automagically turn on +Flyspell in buffers whose major mode supports it and whose major mode is one +of `flyspell-global-modes'. For example, put in your ~/.emacs: + + (global-flyspell-mode t) + Bindings: \\[ispell-word]: correct words (using Ispell). \\[flyspell-auto-correct-word]: automatically correct word. \\[flyspell-correct-word] (or mouse-2): popup correct words. Hooks: @@ -287,10 +328,10 @@ Bindings: \\[ispell-word]: correct words (using Ispell). \\[flyspell-auto-correct-word]: automatically correct word. \\[flyspell-correct-word] (or mouse-2): popup correct words. Hooks: -flyspell-mode-hook is runner after flyspell is entered. +flyspell-mode-hook is run after flyspell is entered. Remark: `flyspell-mode' uses `ispell-mode'. Thus all Ispell options are @@ -306,16 +347,124 @@ flyspell-buffer checks the whole buffer." (interactive "P") - ;; we set the mode on or off - (setq flyspell-mode (not (or (and (null arg) flyspell-mode) - (<= (prefix-numeric-value arg) 0)))) - (if flyspell-mode - (flyspell-mode-on) - (flyspell-mode-off)) - ;; we force the modeline re-printing - (set-buffer-modified-p (buffer-modified-p))) + (let ((old-flyspell-mode flyspell-mode)) + ;; Mark the mode as on or off. + (setq flyspell-mode (not (or (and (null arg) flyspell-mode) + (<= (prefix-numeric-value arg) 0)))) + ;; Do the real work. + (unless (eq flyspell-mode old-flyspell-mode) + (if flyspell-mode + (flyspell-mode-on) + (flyspell-mode-off)) + ;; Force modeline redisplay. + (set-buffer-modified-p (buffer-modified-p))))) + +;*---------------------------------------------------------------------*/ +;* flyspell-buffers ... */ +;* ------------------------------------------------------------- */ +;* For remembering buffers running flyspell */ +;*---------------------------------------------------------------------*/ +(defvar flyspell-buffers nil) + +;*---------------------------------------------------------------------*/ +;* global-flyspell-mode ... */ +;* ------------------------------------------------------------- */ +;* I have stolen this implementation from Global Font Lock mode. */ +;* I use the exact same trick. */ +;*---------------------------------------------------------------------*/ +;;;###autoload +(defun global-flyspell-mode (&optional arg message) + "Toggle Global Flyspell mode. +With prefix ARG, turn Global Flyspell mode on if and only if ARG is positive. +Displays a message saying whether the mode is on or off if MESSAGE is non-nil. +Returns the new status of Global Flyspell mode (non-nil means on). + +When Global Flyspell mode is enabled, Flyspell mode is automagically +turned on in a buffer if its major mode is one of `flyspell-global-modes'." + (interactive "P\np") + (let ((on-p (if arg + (> (prefix-numeric-value arg) 0) + (not global-flyspell-mode)))) + (cond (on-p + (add-hook 'find-file-hooks 'turn-on-flyspell-if-enabled) + (add-hook 'first-change-hook 'turn-on-flyspell-if-enabled) + (mapcar '(lambda (buffer) + (with-current-buffer buffer + (turn-on-flyspell-if-enabled))) + (buffer-list))) + (t + (remove-hook 'find-file-hooks 'turn-on-flyspell-if-enabled) + (remove-hook 'first-change-hook 'turn-on-flyspell-if-enabled) + (mapcar '(lambda (buffer) + (with-current-buffer buffer + (when flyspell-mode + (flyspell-mode)))) + (buffer-list)))) + (when message + (message "Global Flyspell mode %s." (if on-p "enabled" "disabled"))) + (setq global-flyspell-mode on-p))) + +;*---------------------------------------------------------------------*/ +;* global-flyspell-mode ... */ +;*---------------------------------------------------------------------*/ +(defcustom global-flyspell-mode nil + "Toggle Global Flyspell mode. +When Global Flyspell mode is enabled, Flyspell mode is automagically +turned on in a buffer if its major mode is one of `flyspell-global-modes'. +You must modify via \\[customize] for this variable to have an effect." + :set (lambda (symbol value) + (global-flyspell-mode (or value 0))) + :type 'boolean + :group 'flyspell + :require 'flyspell) + +;*---------------------------------------------------------------------*/ +;* turn-on-flyspell-if-enabled ... */ +;*---------------------------------------------------------------------*/ +(defun turn-on-flyspell-if-enabled () + ;; Gross hack warning: Delicate readers should avert eyes now. + ;; Turn on Flyspell mode if it's supported by the major mode and enabled by + ;; the user. + (if (flyspell-global-mode-enabled-p (current-buffer)) + (flyspell-mode t))) + +;*---------------------------------------------------------------------*/ +;* flyspell-global-mode-enabled-p ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-global-mode-enabled-p (buffer) + "Does BUFFER need to activate Flyspell?" + (and global-flyspell-mode + (not (flyspell-minibuffer-p buffer)) + (or (eq flyspell-global-modes t) + (if (eq (car-safe flyspell-global-modes) 'not) + (not (memq major-mode (cdr flyspell-global-modes))) + (memq major-mode flyspell-global-modes))))) + +;*---------------------------------------------------------------------*/ +;* flyspell-minibuffer-p ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-minibuffer-p (buffer) + "Is BUFFER a minibuffer?" + (let ((ws (get-buffer-window-list buffer t))) + (and (consp ws) (window-minibuffer-p (car ws))))) + +;*---------------------------------------------------------------------*/ +;* flyspell-accept-buffer-local-defs ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-accept-buffer-local-defs () + (ispell-accept-buffer-local-defs) + (if (not (and (eq flyspell-dash-dictionary ispell-dictionary) + (eq flyspell-dash-local-dictionary ispell-local-dictionary))) + ;; the dictionary as changed + (progn + (setq flyspell-dash-dictionary ispell-dictionary) + (setq flyspell-dash-local-dictionary ispell-local-dictionary) + (if (member (or ispell-local-dictionary ispell-dictionary) + flyspell-dictionaries-that-consider-dash-as-word-delimiter) + (setq flyspell-consider-dash-as-word-delimiter-flag t) + (setq flyspell-consider-dash-as-word-delimiter-flag nil))))) ;*---------------------------------------------------------------------*/ ;* flyspell-mode-on ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-mode-on () @@ -317,7 +466,7 @@ ;*---------------------------------------------------------------------*/ ;* flyspell-mode-on ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-mode-on () - "Turn flyspell mode on. Do not use this; use `flyspell-mode' instead." + "Turn Flyspell mode on. Do not use this; use `flyspell-mode' instead." (setq ispell-highlight-face 'flyspell-incorrect-face) @@ -323,14 +472,12 @@ (setq ispell-highlight-face 'flyspell-incorrect-face) - ;; ispell initialization - (if flyspell-multi-language-p - (progn - (make-variable-buffer-local 'ispell-dictionary) - (make-variable-buffer-local 'ispell-process) - (make-variable-buffer-local 'ispell-filter) - (make-variable-buffer-local 'ispell-filter-continue) - (make-variable-buffer-local 'ispell-process-directory) - (make-variable-buffer-local 'ispell-parser))) - ;; We put the `flyspel-delayed' property on some commands. + ;; local dictionaries setup + (ispell-change-dictionary + (or ispell-local-dictionary flyspell-default-dictionary)) + ;; we have to force ispell to accept the local definition or + ;; otherwise it could be too late, the local dictionary may + ;; be forgotten! + (flyspell-accept-buffer-local-defs) + ;; we put the `flyspel-delayed' property on some commands (flyspell-delay-commands) ;; we bound flyspell action to post-command hook (make-local-hook 'post-command-hook) @@ -338,8 +485,11 @@ ;; we bound flyspell action to pre-command hook (make-local-hook 'pre-command-hook) (add-hook 'pre-command-hook (function flyspell-pre-command-hook) t t) - - ;; Set flyspell-generic-check-word-p based on the major mode. + ;; we bound flyspell action to after-change hook + (make-local-variable 'after-change-functions) + (setq after-change-functions + (cons 'flyspell-after-change-function after-change-functions)) + ;; set flyspell-generic-check-word-p based on the major mode (let ((mode-predicate (get major-mode 'flyspell-mode-predicate))) (if mode-predicate (setq flyspell-generic-check-word-p mode-predicate))) @@ -343,10 +493,9 @@ (let ((mode-predicate (get major-mode 'flyspell-mode-predicate))) (if mode-predicate (setq flyspell-generic-check-word-p mode-predicate))) - ;; the welcome message (if flyspell-issue-welcome-flag (let ((binding (where-is-internal 'flyspell-auto-correct-word nil 'non-ascii))) (message (if binding @@ -347,8 +496,8 @@ ;; the welcome message (if flyspell-issue-welcome-flag (let ((binding (where-is-internal 'flyspell-auto-correct-word nil 'non-ascii))) (message (if binding - (format "Welcome to flyspell. Use %s or Mouse-2 to correct words." + (format "Welcome to flyspell. Use %s or Mouse-2 to correct words." (key-description binding)) @@ -354,12 +503,5 @@ (key-description binding)) - "Welcome to flyspell. Use Mouse-2 to correct words.")))) - ;; we have to kill the flyspell process when the buffer is deleted. - ;; (thanks to Jeff Miller and Roland Rosenfeld who sent me this - ;; improvement). - (add-hook 'kill-buffer-hook - '(lambda () - (if flyspell-mode - (flyspell-mode-off)))) + "Welcome to flyspell. Use Mouse-2 to correct words.")))) ;; we end with the flyspell hooks (run-hooks 'flyspell-mode-hook)) @@ -367,7 +509,7 @@ ;* flyspell-delay-commands ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-delay-commands () - "Install the standard set of delayed commands." + "Install the standard set of Flyspell delayed commands." (mapcar 'flyspell-delay-command flyspell-default-delayed-commands) (mapcar 'flyspell-delay-command flyspell-delayed-commands)) @@ -375,7 +517,7 @@ ;* flyspell-delay-command ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-delay-command (command) - "Set COMMAND to be delayed. + "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 immediatly checked. It will be checked only after `flyspell-delay' seconds." @@ -415,8 +557,10 @@ ;* 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-buffer nil) +(defvar flyspell-pre-point nil) +(defvar flyspell-pre-pre-buffer nil) +(defvar flyspell-pre-pre-point nil) ;*---------------------------------------------------------------------*/ ;* flyspell-pre-command-hook ... */ @@ -430,4 +574,5 @@ ;*---------------------------------------------------------------------*/ ;* flyspell-mode-off ... */ ;*---------------------------------------------------------------------*/ +;;;###autoload (defun flyspell-mode-off () @@ -433,9 +578,5 @@ (defun flyspell-mode-off () - "Turn flyspell mode off. Do not use this--use `flyspell-mode' instead." - ;; If we have an Ispell process for each buffer, - ;; kill the one for this buffer. - (if flyspell-multi-language-p - (ispell-kill-ispell t)) + "Turn Flyspell mode off." ;; 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) @@ -439,6 +580,8 @@ ;; 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) + (setq after-change-functions (delq 'flyspell-after-change-function + after-change-functions)) ;; we remove all the flyspell hilightings (flyspell-delete-all-overlays) ;; we have to erase pre cache variables @@ -448,6 +591,66 @@ (setq flyspell-mode nil)) ;*---------------------------------------------------------------------*/ +;* flyspell-check-pre-word-p ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-check-pre-word-p () + "Return non-nil if we should to 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) + ((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 */ +;* the post command hook, we will check, if the word at this */ +;* position has to be spell checked. */ +;*---------------------------------------------------------------------*/ +(defvar flyspell-changes nil) + +;*---------------------------------------------------------------------*/ +;* flyspell-after-change-function ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-after-change-function (start stop len) + "Save the current buffer and point for Flyspell's post-command hook." + (interactive) + (setq flyspell-changes (cons (cons start stop) flyspell-changes))) + +;*---------------------------------------------------------------------*/ +;* flyspell-check-changed-word-p ... */ +;*---------------------------------------------------------------------*/ +(defun flyspell-check-changed-word-p (start stop) + "Return t when the changed word has to be checked. +The answer depends of several criteria. +Mostly we check word delimiters." + (cond + ((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop)) + nil) + ((let ((pos (point))) + (or (>= pos start) (<= pos stop) (= pos (1+ stop)))) + nil) + (t + t))) + +;*---------------------------------------------------------------------*/ ;* flyspell-check-word-p ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-check-word-p () @@ -479,30 +682,4 @@ (sit-for flyspell-delay 0 nil))))) ;*---------------------------------------------------------------------*/ -;* flyspell-check-pre-word-p ... */ -;*---------------------------------------------------------------------*/ -(defun flyspell-check-pre-word-p () - "Return non-nil if we should to 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) - ((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) - ((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))))) - -;*---------------------------------------------------------------------*/ ;* flyspell-post-command-hook ... */ @@ -508,5 +685,16 @@ ;* flyspell-post-command-hook ... */ +;* ------------------------------------------------------------- */ +;* It is possible that we check several words: */ +;* 1- the current word is checked if the predicate */ +;* FLYSPELL-CHECK-WORD-P is true */ +;* 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 */ +;* previous FLYSPELL-POST-COMMAND-HOOK */ +;* 3- the words changed by the THIS-COMMAND that are neither the */ +;* previous word nor the current word */ ;*---------------------------------------------------------------------*/ (defun flyspell-post-command-hook () "The `post-command-hook' used by flyspell to check a word in-the-fly." (interactive) @@ -509,11 +697,9 @@ ;*---------------------------------------------------------------------*/ (defun flyspell-post-command-hook () "The `post-command-hook' used by flyspell to check a word in-the-fly." (interactive) - (if (flyspell-check-word-p) - (flyspell-word)) (if (flyspell-check-pre-word-p) (save-excursion (set-buffer flyspell-pre-buffer) (save-excursion (goto-char flyspell-pre-point) @@ -515,9 +701,32 @@ (if (flyspell-check-pre-word-p) (save-excursion (set-buffer flyspell-pre-buffer) (save-excursion (goto-char flyspell-pre-point) - (flyspell-word))))) + (flyspell-word)))) + (if (flyspell-check-word-p) + (progn + (flyspell-word) + ;; we remember which word we have just checked. + ;; this will be use 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 is these variables are used within the predicate + ;; FLYSPELL-CHECK-PRE-WORD-P + (setq flyspell-pre-pre-buffer (current-buffer)) + (setq flyspell-pre-pre-point (point))) + (progn + (setq flyspell-pre-pre-buffer nil) + (setq flyspell-pre-pre-point nil) + (setq flyspell-word-cache-end -1))) + (while (consp flyspell-changes) + (let ((start (car (car flyspell-changes))) + (stop (cdr (car flyspell-changes)))) + (if (flyspell-check-changed-word-p start stop) + (save-excursion + (goto-char start) + (flyspell-word))) + (setq flyspell-changes (cdr flyspell-changes))))) ;*---------------------------------------------------------------------*/ ;* flyspell-word ... */ @@ -528,5 +737,5 @@ (if (interactive-p) (setq following ispell-following-word)) (save-excursion - (ispell-accept-buffer-local-defs) ; use the correct dictionary + (flyspell-accept-buffer-local-defs) ; use the correct dictionary (let ((cursor-location (point)) ; retain cursor location @@ -532,5 +741,5 @@ (let ((cursor-location (point)) ; retain cursor location - (word (flyspell-get-word following)) + (word (flyspell-get-word following 'full-tex)) start end poss) (if (or (eq word nil) (and (fboundp flyspell-generic-check-word-p) @@ -557,13 +766,6 @@ (string-equal flyspell-word-cache-word word)) ;; this word had been already checked, we skip nil) - ((and (eq ispell-parser 'tex) - (flyspell-tex-command-p word)) - ;; this is a correct word (because a tex command) - (flyspell-unhighlight-at start) - (if (> end start) - (flyspell-unhighlight-at (- end 1))) - t) (t ;; we setup the cache (setq flyspell-word-cache-start start) @@ -585,7 +787,7 @@ ;; (process-send-string ispell-process "!\n") ;; back to terse mode. (setq ispell-filter (cdr ispell-filter)) - (if (listp ispell-filter) + (if (consp ispell-filter) (setq poss (ispell-parse-output (car ispell-filter)))) (cond ((eq poss t) ;; correct @@ -642,13 +844,6 @@ (if ispell-quit (setq ispell-quit nil))))))))) ;*---------------------------------------------------------------------*/ -;* flyspell-tex-command-p ... */ -;*---------------------------------------------------------------------*/ -(defun flyspell-tex-command-p (word) - "Return t if WORD is a TeX command." - (eq (aref word 0) ?\\)) - -;*---------------------------------------------------------------------*/ ;* flyspell-casechars-cache ... */ ;*---------------------------------------------------------------------*/ (defvar flyspell-casechars-cache nil) @@ -713,5 +908,5 @@ ;*---------------------------------------------------------------------*/ ;* flyspell-get-word ... */ ;*---------------------------------------------------------------------*/ -(defun flyspell-get-word (following) +(defun flyspell-get-word (following full-tex) "Return the word for spell-checking according to Ispell syntax. @@ -717,5 +912,5 @@ "Return the word for spell-checking according to Ispell syntax. -If optional argument FOLLOWING is non-nil or if `ispell-following-word' +If argument FOLLOWING is non-nil or if `ispell-following-word' is non-nil when called interactively, then the following word \(rather than preceding\) is checked when the cursor is not over a word. Optional second argument contains otherchars that can be included in word @@ -719,7 +914,8 @@ is non-nil when called interactively, then the following word \(rather than preceding\) is checked when the cursor is not over a word. Optional second argument contains otherchars that can be included in word -many times. +many times. The argument FULL-TEX is true if we are fetching a full +TeX command and nil otherwise. Word syntax described by `ispell-dictionary-alist' (which see)." (let* ((flyspell-casechars (flyspell-get-casechars)) @@ -734,7 +930,9 @@ "+\\)" (if ispell-many-otherchars-p "*" "?"))) - (tex-prelude "[\\\\{]") - (tex-regexp (if (eq ispell-parser 'tex) + (tex-prelude (if full-tex + "\\([a-zA-Z*0-9\\]*[\\\\{]\\)" + "[\\\\{]")) + (tex-regexp (if (and full-tex (eq ispell-parser 'tex)) (concat tex-prelude "?" word-regexp "}?") word-regexp)) @@ -739,6 +937,5 @@ (concat tex-prelude "?" word-regexp "}?") word-regexp)) - did-it-once start end word) ;; find the word @@ -762,6 +959,10 @@ (if (looking-at flyspell-casechars) (re-search-backward flyspell-not-casechars (point-min) 'move) (backward-char -1)))) + ;; when in tex mode, we skip backward until we find a tex prelude + (if (and full-tex (eq ispell-parser 'tex)) + (while (and (> (point) (point-min)) (looking-at tex-prelude)) + (backward-char 1))) ;; Now mark the word and save to string. (if (eq (re-search-forward tex-regexp (point-max) t) nil) nil @@ -937,7 +1138,7 @@ to this command." (interactive "d") ;; use the correct dictionary - (ispell-accept-buffer-local-defs) + (flyspell-accept-buffer-local-defs) (if (eq flyspell-auto-correct-pos pos) ;; we have already been using the function at the same location (progn @@ -954,7 +1155,7 @@ (setq flyspell-auto-correct-pos (point))) ;; retain cursor location (let ((cursor-location pos) - (word (flyspell-get-word nil)) + (word (flyspell-get-word nil nil)) start end poss) ;; destructure return word info list. (setq start (car (cdr word)) @@ -968,7 +1169,7 @@ (accept-process-output ispell-process) (not (string= "" (car ispell-filter))))) (setq ispell-filter (cdr ispell-filter)) - (if (listp 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 @@ -1064,8 +1265,8 @@ The word checked is the word at the mouse position." (interactive "e") ;; use the correct dictionary - (ispell-accept-buffer-local-defs) + (flyspell-accept-buffer-local-defs) ;; retain cursor location (I don't know why but save-excursion here fails). (let ((save (point))) (mouse-set-point event) (let ((cursor-location (point)) @@ -1068,8 +1269,8 @@ ;; retain cursor location (I don't know why but save-excursion here fails). (let ((save (point))) (mouse-set-point event) (let ((cursor-location (point)) - (word (flyspell-get-word nil)) + (word (flyspell-get-word nil nil)) start end poss replace) ;; destructure return word info list. (setq start (car (cdr word)) @@ -1083,7 +1284,7 @@ (accept-process-output ispell-process) (not (string= "" (car ispell-filter))))) (setq ispell-filter (cdr ispell-filter)) - (if (listp 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