Function: flyspell-word

flyspell-word is an interactive and byte-compiled function defined in flyspell.el.gz.

Signature

(flyspell-word &optional FOLLOWING KNOWN-MISSPELLING)

Documentation

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. If optional argument KNOWN-MISSPELLING is non-nil considers word a misspelling and skips redundant spell-checking step.

See flyspell-get-word for details of how this finds the word to spell-check.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/textmodes/flyspell.el.gz
(defvar flyspell-word) ;Backward compatibility; some predicates made use of it!

;;*---------------------------------------------------------------------*/
;;*    flyspell-word ...                                                */
;;*---------------------------------------------------------------------*/
(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.  If
optional argument KNOWN-MISSPELLING is non-nil considers word a
misspelling and skips redundant spell-checking step.

See `flyspell-get-word' for details of how this finds the word to
spell-check."
  (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)
    (let* ((cursor-location (point))
           (flyspell-word (flyspell-get-word following))
           start end poss word ispell-filter)
      (if (or (eq flyspell-word nil)
              (and (functionp flyspell-generic-check-word-predicate)
                   (not (funcall flyspell-generic-check-word-predicate))))
	  t
	(progn
	  ;; destructure return flyspell-word info list.
	  (setq start (car (cdr flyspell-word))
		end (car (cdr (cdr flyspell-word)))
		word (car flyspell-word))
	  ;; before checking in the directory, we check for doublons.
	  (cond
	   ((and (or (not (eq ispell-parser 'tex))
		     (and (> start (point-min))
			  (not (memq (char-after (1- start)) '(?\} ?\\)))))
		 flyspell-mark-duplications-flag
		 (not (catch 'exception
			(let ((dict (or ispell-local-dictionary
					ispell-dictionary)))
			  (dolist (except flyspell-mark-duplications-exceptions)
			    (and (or (null (car except))
				     (and (stringp dict)
					  (string-match (car except) dict)))
				 (member (downcase word) (cdr except))
				 (throw 'exception t))))))
		 (save-excursion
		   (goto-char start)
		   (let* ((bound
			   (- start
			      (- end start)
			      (- (save-excursion
                                   (skip-chars-backward " \t\n\f")))))
			  (p (when (>= bound (point-min))
			       (flyspell-word-search-backward
                                word bound flyspell-case-fold-duplications))))
		     (and p (/= p start)))))
	    ;; yes, this is a doublon
	    (flyspell-highlight-incorrect-region start end 'doublon)
	    nil)
	   ((and (eq flyspell-word-cache-start start)
		 (eq flyspell-word-cache-end end)
		 (string-equal flyspell-word-cache-word word))
	    ;; this word had been already checked, we skip
	    flyspell-word-cache-result)
	   ((and (eq ispell-parser 'tex)
		 (flyspell-tex-command-p flyspell-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)
	    (setq flyspell-word-cache-end end)
	    (setq flyspell-word-cache-word word)
	    ;; now check spelling of word.
            (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.
                  (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 1 nil nil)))
	    (let ((res (cond ((eq poss t)
			      ;; correct
			      (setq flyspell-word-cache-result t)
			      (flyspell-unhighlight-at start)
			      (if (> end start)
				  (flyspell-unhighlight-at (- end 1)))
			      t)
			     ((and (stringp poss) flyspell-highlight-flag)
			      ;; correct
			      (setq flyspell-word-cache-result t)
			      (flyspell-unhighlight-at start)
			      (if (> end start)
				  (flyspell-unhighlight-at (- end 1)))
			      t)
			     ((null poss)
			      (setq flyspell-word-cache-result t)
			      (flyspell-unhighlight-at start)
			      (if (> end start)
				  (flyspell-unhighlight-at (- end 1)))
			      t)
			     ((or (and (< flyspell-duplicate-distance 0)
				       (or (save-excursion
					     (goto-char start)
					     (flyspell-word-search-backward
					      word
					      (point-min)))
					   (save-excursion
					     (goto-char end)
					     (flyspell-word-search-forward
					      word
					      (point-max)))))
				  (and (> flyspell-duplicate-distance 0)
				       (or (save-excursion
					     (goto-char start)
					     (flyspell-word-search-backward
					      word
					      (- start
						 flyspell-duplicate-distance)))
					   (save-excursion
					     (goto-char end)
					     (flyspell-word-search-forward
					      word
					      (+ end
						 flyspell-duplicate-distance))))))
			      ;; This is a misspelled word which occurs
			      ;; twice within flyspell-duplicate-distance.
			      (setq flyspell-word-cache-result nil)
			      (if flyspell-highlight-flag
				  (flyspell-highlight-duplicate-region
				   start end poss)
				(message "duplicate `%s'" word))
			      nil)
			     (t
			      (setq flyspell-word-cache-result nil)
			      ;; Highlight the location as incorrect,
			      ;; including offset specified in POSS
			      ;; and only for the length of the
			      ;; misspelled word specified by POSS.
			      (if flyspell-highlight-flag
                                  (let ((hstart start)
                                        (hend end)
                                        offset misspelled)
                                    (when (consp poss)
                                      (setq misspelled (car poss)
                                            offset (nth 1 poss))
                                      (if (integerp offset)
                                          (setq hstart (+ start offset -1)))
                                      ;; POSS includes the misspelled
                                      ;; word; use that to figure out
                                      ;; how many characters to highlight.
                                      (if (stringp misspelled)
                                          (setq hend
                                                (+ hstart
                                                   (length misspelled)))))
				    (flyspell-highlight-incorrect-region
                                     hstart hend poss))
				(flyspell-notify-misspell word poss))
			      nil))))
	      ;; return to original location
	      (goto-char cursor-location)
	      (if ispell-quit (setq ispell-quit nil))
	      res))))))))