| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
(require 'ispell) |
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
(defgroup flyspell nil |
|---|
| 53 |
"Spell checking on the fly." |
|---|
| 54 |
:tag "FlySpell" |
|---|
| 55 |
:prefix "flyspell-" |
|---|
| 56 |
:group 'ispell |
|---|
| 57 |
:group 'processes) |
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
(defcustom flyspell-highlight-flag t |
|---|
| 63 |
"How Flyspell should indicate misspelled words. |
|---|
| 64 |
Non-nil means use highlight, nil means use minibuffer messages." |
|---|
| 65 |
:group 'flyspell |
|---|
| 66 |
:type 'boolean) |
|---|
| 67 |
|
|---|
| 68 |
(defcustom flyspell-mark-duplications-flag t |
|---|
| 69 |
"Non-nil means Flyspell reports a repeated word as an error. |
|---|
| 70 |
Detection of repeated words is not implemented in |
|---|
| 71 |
\"large\" regions; see `flyspell-large-region'." |
|---|
| 72 |
:group 'flyspell |
|---|
| 73 |
:type 'boolean) |
|---|
| 74 |
|
|---|
| 75 |
(defcustom flyspell-sort-corrections nil |
|---|
| 76 |
"Non-nil means, sort the corrections alphabetically before popping them." |
|---|
| 77 |
:group 'flyspell |
|---|
| 78 |
:version "21.1" |
|---|
| 79 |
:type 'boolean) |
|---|
| 80 |
|
|---|
| 81 |
(defcustom flyspell-duplicate-distance -1 |
|---|
| 82 |
"The maximum distance for finding duplicates of unrecognized words. |
|---|
| 83 |
This applies to the feature that when a word is not found in the dictionary, |
|---|
| 84 |
if the same spelling occurs elsewhere in the buffer, |
|---|
| 85 |
Flyspell uses a different face (`flyspell-duplicate') to highlight it. |
|---|
| 86 |
This variable specifies how far to search to find such a duplicate. |
|---|
| 87 |
-1 means no limit (search the whole buffer). |
|---|
| 88 |
0 means do not search for duplicate unrecognized spellings." |
|---|
| 89 |
:group 'flyspell |
|---|
| 90 |
:version "21.1" |
|---|
| 91 |
:type 'number) |
|---|
| 92 |
|
|---|
| 93 |
(defcustom flyspell-delay 3 |
|---|
| 94 |
"The number of seconds to wait before checking, after a \"delayed\" command." |
|---|
| 95 |
:group 'flyspell |
|---|
| 96 |
:type 'number) |
|---|
| 97 |
|
|---|
| 98 |
(defcustom flyspell-persistent-highlight t |
|---|
| 99 |
"Non-nil means misspelled words remain highlighted until corrected. |
|---|
| 100 |
If this variable is nil, only the most recently detected misspelled word |
|---|
| 101 |
is highlighted." |
|---|
| 102 |
:group 'flyspell |
|---|
| 103 |
:type 'boolean) |
|---|
| 104 |
|
|---|
| 105 |
(defcustom flyspell-highlight-properties t |
|---|
| 106 |
"Non-nil means highlight incorrect words even if a property exists for this word." |
|---|
| 107 |
:group 'flyspell |
|---|
| 108 |
:type 'boolean) |
|---|
| 109 |
|
|---|
| 110 |
(defcustom flyspell-default-delayed-commands |
|---|
| 111 |
'(self-insert-command |
|---|
| 112 |
delete-backward-char |
|---|
| 113 |
backward-or-forward-delete-char |
|---|
| 114 |
delete-char |
|---|
| 115 |
scrollbar-vertical-drag |
|---|
| 116 |
backward-delete-char-untabify) |
|---|
| 117 |
"The standard list of delayed commands for Flyspell. |
|---|
| 118 |
See `flyspell-delayed-commands'." |
|---|
| 119 |
:group 'flyspell |
|---|
| 120 |
:version "21.1" |
|---|
| 121 |
:type '(repeat (symbol))) |
|---|
| 122 |
|
|---|
| 123 |
(defcustom flyspell-delayed-commands nil |
|---|
| 124 |
"List of commands that are \"delayed\" for Flyspell mode. |
|---|
| 125 |
After these commands, Flyspell checking is delayed for a short time, |
|---|
| 126 |
whose length is specified by `flyspell-delay'." |
|---|
| 127 |
:group 'flyspell |
|---|
| 128 |
:type '(repeat (symbol))) |
|---|
| 129 |
|
|---|
| 130 |
(defcustom flyspell-default-deplacement-commands |
|---|
| 131 |
'(next-line |
|---|
| 132 |
previous-line |
|---|
| 133 |
scroll-up |
|---|
| 134 |
scroll-down) |
|---|
| 135 |
"The standard list of deplacement commands for Flyspell. |
|---|
| 136 |
See `flyspell-deplacement-commands'." |
|---|
| 137 |
:group 'flyspell |
|---|
| 138 |
:version "21.1" |
|---|
| 139 |
:type '(repeat (symbol))) |
|---|
| 140 |
|
|---|
| 141 |
(defcustom flyspell-deplacement-commands nil |
|---|
| 142 |
"List of commands that are \"deplacement\" for Flyspell mode. |
|---|
| 143 |
After these commands, Flyspell checking is performed only if the previous |
|---|
| 144 |
command was not the very same command." |
|---|
| 145 |
:group 'flyspell |
|---|
| 146 |
:version "21.1" |
|---|
| 147 |
:type '(repeat (symbol))) |
|---|
| 148 |
|
|---|
| 149 |
(defcustom flyspell-issue-welcome-flag t |
|---|
| 150 |
"Non-nil means that Flyspell should display a welcome message when started." |
|---|
| 151 |
:group 'flyspell |
|---|
| 152 |
:type 'boolean) |
|---|
| 153 |
|
|---|
| 154 |
(defcustom flyspell-issue-message-flag t |
|---|
| 155 |
"Non-nil means that Flyspell emits messages when checking words." |
|---|
| 156 |
:group 'flyspell |
|---|
| 157 |
:type 'boolean) |
|---|
| 158 |
|
|---|
| 159 |
(defcustom flyspell-incorrect-hook nil |
|---|
| 160 |
"List of functions to be called when incorrect words are encountered. |
|---|
| 161 |
Each function is given three arguments. The first two |
|---|
| 162 |
arguments are the beginning and the end of the incorrect region. |
|---|
| 163 |
The third is either the symbol `doublon' or the list |
|---|
| 164 |
of possible corrections as returned by `ispell-parse-output'. |
|---|
| 165 |
|
|---|
| 166 |
If any of the functions return non-nil, the word is not highlighted as |
|---|
| 167 |
incorrect." |
|---|
| 168 |
:group 'flyspell |
|---|
| 169 |
:version "21.1" |
|---|
| 170 |
:type 'hook) |
|---|
| 171 |
|
|---|
| 172 |
(defcustom flyspell-default-dictionary nil |
|---|
| 173 |
"A string that is the name of the default dictionary. |
|---|
| 174 |
This is passed to the `ispell-change-dictionary' when flyspell is started. |
|---|
| 175 |
If the variable `ispell-local-dictionary' or `ispell-dictionary' is non-nil |
|---|
| 176 |
when flyspell is started, the value of that variable is used instead |
|---|
| 177 |
of `flyspell-default-dictionary' to select the default dictionary. |
|---|
| 178 |
Otherwise, if `flyspell-default-dictionary' is nil, it means to use |
|---|
| 179 |
Ispell's ultimate default dictionary." |
|---|
| 180 |
:group 'flyspell |
|---|
| 181 |
:version "21.1" |
|---|
| 182 |
:type '(choice string (const :tag "Default" nil))) |
|---|
| 183 |
|
|---|
| 184 |
(defcustom flyspell-tex-command-regexp |
|---|
| 185 |
"\\(\\(begin\\|end\\)[ \t]*{\\|\\(cite[a-z*]*\\|label\\|ref\\|eqref\\|usepackage\\|documentclass\\)[ \t]*\\(\\[[^]]*\\]\\)?{[^{}]*\\)" |
|---|
| 186 |
"A string that is the regular expression that matches TeX commands." |
|---|
| 187 |
:group 'flyspell |
|---|
| 188 |
:version "21.1" |
|---|
| 189 |
:type 'string) |
|---|
| 190 |
|
|---|
| 191 |
(defcustom flyspell-check-tex-math-command nil |
|---|
| 192 |
"Non-nil means check even inside TeX math environment. |
|---|
| 193 |
TeX math environments are discovered by the TEXMATHP that implemented |
|---|
| 194 |
inside the texmathp.el Emacs package. That package may be found at: |
|---|
| 195 |
http://strw.leidenuniv.nl/~dominik/Tools" |
|---|
| 196 |
:group 'flyspell |
|---|
| 197 |
:type 'boolean) |
|---|
| 198 |
|
|---|
| 199 |
(defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter |
|---|
| 200 |
'("francais" "deutsch8" "norsk") |
|---|
| 201 |
"List of dictionary names that consider `-' as word delimiter." |
|---|
| 202 |
:group 'flyspell |
|---|
| 203 |
:version "21.1" |
|---|
| 204 |
:type '(repeat (string))) |
|---|
| 205 |
|
|---|
| 206 |
(defcustom flyspell-abbrev-p |
|---|
| 207 |
nil |
|---|
| 208 |
"If non-nil, add correction to abbreviation table." |
|---|
| 209 |
:group 'flyspell |
|---|
| 210 |
:version "21.1" |
|---|
| 211 |
:type 'boolean) |
|---|
| 212 |
|
|---|
| 213 |
(defcustom flyspell-use-global-abbrev-table-p |
|---|
| 214 |
nil |
|---|
| 215 |
"If non-nil, prefer global abbrev table to local abbrev table." |
|---|
| 216 |
:group 'flyspell |
|---|
| 217 |
:version "21.1" |
|---|
| 218 |
:type 'boolean) |
|---|
| 219 |
|
|---|
| 220 |
(defcustom flyspell-mode-line-string " Fly" |
|---|
| 221 |
"String displayed on the modeline when flyspell is active. |
|---|
| 222 |
Set this to nil if you don't want a modeline indicator." |
|---|
| 223 |
:group 'flyspell |
|---|
| 224 |
:type '(choice string (const :tag "None" nil))) |
|---|
| 225 |
|
|---|
| 226 |
(defcustom flyspell-large-region 1000 |
|---|
| 227 |
"The threshold that determines if a region is small. |
|---|
| 228 |
If the region is smaller than this number of characters, |
|---|
| 229 |
`flyspell-region' checks the words sequentially using regular |
|---|
| 230 |
flyspell methods. Else, if the region is large, a new Ispell process is |
|---|
| 231 |
spawned for speed. |
|---|
| 232 |
|
|---|
| 233 |
Doubled words are not detected in a large region, because Ispell |
|---|
| 234 |
does not check for them. |
|---|
| 235 |
|
|---|
| 236 |
If `flyspell-large-region' is nil, all regions are treated as small." |
|---|
| 237 |
:group 'flyspell |
|---|
| 238 |
:version "21.1" |
|---|
| 239 |
:type '(choice number (const :tag "All small" nil))) |
|---|
| 240 |
|
|---|
| 241 |
(defcustom flyspell-insert-function (function insert) |
|---|
| 242 |
"Function for inserting word by flyspell upon correction." |
|---|
| 243 |
:group 'flyspell |
|---|
| 244 |
:type 'function) |
|---|
| 245 |
|
|---|
| 246 |
(defcustom flyspell-before-incorrect-word-string nil |
|---|
| 247 |
"String used to indicate an incorrect word starting." |
|---|
| 248 |
:group 'flyspell |
|---|
| 249 |
:type '(choice string (const nil))) |
|---|
| 250 |
|
|---|
| 251 |
(defcustom flyspell-after-incorrect-word-string nil |
|---|
| 252 |
"String used to indicate an incorrect word ending." |
|---|
| 253 |
:group 'flyspell |
|---|
| 254 |
:type '(choice string (const nil))) |
|---|
| 255 |
|
|---|
| 256 |
(defcustom flyspell-use-meta-tab t |
|---|
| 257 |
"Non-nil means that flyspell uses M-TAB to correct word." |
|---|
| 258 |
:group 'flyspell |
|---|
| 259 |
:type 'boolean) |
|---|
| 260 |
|
|---|
| 261 |
(defcustom flyspell-auto-correct-binding |
|---|
| 262 |
[(control ?\ |
|---|
| 263 |
"The key binding for flyspell auto correction." |
|---|
| 264 |
:group 'flyspell) |
|---|
| 265 |
|
|---|
| 266 |
|
|---|
| 267 |
|
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 |
|
|---|
| 271 |
|
|---|
| 272 |
|
|---|
| 273 |
|
|---|
| 274 |
|
|---|
| 275 |
|
|---|
| 276 |
|
|---|
| 277 |
(defvar flyspell-generic-check-word-predicate nil |
|---|
| 278 |
"Function providing per-mode customization over which words are flyspelled. |
|---|
| 279 |
Returns t to continue checking, nil otherwise. |
|---|
| 280 |
Flyspell mode sets this variable to whatever is the `flyspell-mode-predicate' |
|---|
| 281 |
property of the major mode name.") |
|---|
| 282 |
(make-variable-buffer-local 'flyspell-generic-check-word-predicate) |
|---|
| 283 |
(defvaralias 'flyspell-generic-check-word-p |
|---|
| 284 |
'flyspell-generic-check-word-predicate) |
|---|
| 285 |
|
|---|
| 286 |
|
|---|
| 287 |
(put 'mail-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify) |
|---|
| 288 |
(put 'message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify) |
|---|
| 289 |
(defun mail-mode-flyspell-verify () |
|---|
| 290 |
"Function used for `flyspell-generic-check-word-predicate' in Mail mode." |
|---|
| 291 |
(let ((header-end (save-excursion |
|---|
| 292 |
(goto-char (point-min)) |
|---|
| 293 |
(re-search-forward |
|---|
| 294 |
(concat "^" |
|---|
| 295 |
(regexp-quote mail-header-separator) |
|---|
| 296 |
"$") |
|---|
| 297 |
nil t) |
|---|
| 298 |
(point))) |
|---|
| 299 |
(signature-begin (save-excursion |
|---|
| 300 |
(goto-char (point-max)) |
|---|
| 301 |
(re-search-backward message-signature-separator |
|---|
| 302 |
nil t) |
|---|
| 303 |
(point)))) |
|---|
| 304 |
(cond ((< (point) header-end) |
|---|
| 305 |
(and (save-excursion (beginning-of-line) |
|---|
| 306 |
(looking-at "^Subject:")) |
|---|
| 307 |
(> (point) (match-end 0)))) |
|---|
| 308 |
((> (point) signature-begin) |
|---|
| 309 |
nil) |
|---|
| 310 |
(t |
|---|
| 311 |
(save-excursion |
|---|
| 312 |
(beginning-of-line) |
|---|
| 313 |
(not (looking-at "[>}|]\\|To:"))))))) |
|---|
| 314 |
|
|---|
| 315 |
|
|---|
| 316 |
(put 'texinfo-mode 'flyspell-mode-predicate 'texinfo-mode-flyspell-verify) |
|---|
| 317 |
(defun texinfo-mode-flyspell-verify () |
|---|
| 318 |
"Function used for `flyspell-generic-check-word-predicate' in Texinfo mode." |
|---|
| 319 |
(save-excursion |
|---|
| 320 |
(forward-word -1) |
|---|
| 321 |
(not (looking-at "@")))) |
|---|
| 322 |
|
|---|
| 323 |
|
|---|
| 324 |
(put 'tex-mode 'flyspell-mode-predicate 'tex-mode-flyspell-verify) |
|---|
| 325 |
(defun tex-mode-flyspell-verify () |
|---|
| 326 |
"Function used for `flyspell-generic-check-word-predicate' in LaTeX mode." |
|---|
| 327 |
(and |
|---|
| 328 |
(not (save-excursion |
|---|
| 329 |
(re-search-backward "^[ \t]*%%%[ \t]+Local" nil t))) |
|---|
| 330 |
(not (save-excursion |
|---|
| 331 |
(let ((this (point-marker)) |
|---|
| 332 |
(e (progn (end-of-line) (point-marker)))) |
|---|
| 333 |
(beginning-of-line) |
|---|
| 334 |
(if (re-search-forward "\\\\\\(cite\\|label\\|ref\\){[^}]*}" e t) |
|---|
| 335 |
(and (>= this (match-beginning 0)) |
|---|
| 336 |
(<= this (match-end 0)) ))))))) |
|---|
| 337 |
|
|---|
| 338 |
|
|---|
| 339 |
(put 'sgml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify) |
|---|
| 340 |
(put 'html-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify) |
|---|
| 341 |
|
|---|
| 342 |
(defun sgml-mode-flyspell-verify () |
|---|
| 343 |
"Function used for `flyspell-generic-check-word-predicate' in SGML mode." |
|---|
| 344 |
(not (save-excursion |
|---|
| 345 |
(let ((this (point-marker)) |
|---|
| 346 |
(s (progn (beginning-of-line) (point-marker))) |
|---|
| 347 |
(e (progn (end-of-line) (point-marker)))) |
|---|
| 348 |
(or (progn |
|---|
| 349 |
(goto-char this) |
|---|
| 350 |
(and (re-search-forward "[^<]*>" e t) |
|---|
| 351 |
(= (match-beginning 0) this))) |
|---|
| 352 |
(progn |
|---|
| 353 |
(goto-char this) |
|---|
| 354 |
(and (re-search-backward "<[^>]*" s t) |
|---|
| 355 |
(= (match-end 0) this))) |
|---|
| 356 |
(and (progn |
|---|
| 357 |
(goto-char this) |
|---|
| 358 |
(and (re-search-forward "[^&]*;" e t) |
|---|
| 359 |
(= (match-beginning 0) this))) |
|---|
| 360 |
(progn |
|---|
| 361 |
(goto-char this) |
|---|
| 362 |
(and (re-search-backward "&[^;]*" s t) |
|---|
| 363 |
(= (match-end 0) this))))))))) |
|---|
| 364 |
|
|---|
| 365 |
|
|---|
| 366 |
|
|---|
| 367 |
|
|---|
| 368 |
(defvar flyspell-prog-text-faces |
|---|
| 369 |
'(font-lock-string-face font-lock-comment-face font-lock-doc-face) |
|---|
| 370 |
"Faces corresponding to text in programming-mode buffers.") |
|---|
| 371 |
|
|---|
| 372 |
(defun flyspell-generic-progmode-verify () |
|---|
| 373 |
"Used for `flyspell-generic-check-word-predicate' in programming modes." |
|---|
| 374 |
(let ((f (get-text-property (point) 'face))) |
|---|
| 375 |
(memq f flyspell-prog-text-faces))) |
|---|
| 376 |
|
|---|
| 377 |
|
|---|
| 378 |
(defun flyspell-prog-mode () |
|---|
| 379 |
"Turn on `flyspell-mode' for comments and strings." |
|---|
| 380 |
(interactive) |
|---|
| 381 |
(setq flyspell-generic-check-word-predicate |
|---|
| 382 |
'flyspell-generic-progmode-verify) |
|---|
| 383 |
(flyspell-mode 1) |
|---|
| 384 |
(run-hooks 'flyspell-prog-mode-hook)) |
|---|
| 385 |
|
|---|
| 386 |
|
|---|
| 387 |
|
|---|
| 388 |
|
|---|
| 389 |
(autoload 'make-overlay "overlay" "Overlay compatibility kit." t) |
|---|
| 390 |
(autoload 'overlayp "overlay" "Overlay compatibility kit." t) |
|---|
| 391 |
(autoload 'overlays-in "overlay" "Overlay compatibility kit." t) |
|---|
| 392 |
(autoload 'delete-overlay "overlay" "Overlay compatibility kit." t) |
|---|
| 393 |
(autoload 'overlays-at "overlay" "Overlay compatibility kit." t) |
|---|
| 394 |
(autoload 'overlay-put "overlay" "Overlay compatibility kit." t) |
|---|
| 395 |
(autoload 'overlay-get "overlay" "Overlay compatibility kit." t) |
|---|
| 396 |
(autoload 'previous-overlay-change "overlay" "Overlay compatibility kit." t) |
|---|
| 397 |
|
|---|
| 398 |
|
|---|
| 399 |
|
|---|
| 400 |
|
|---|
| 401 |
(defvar flyspell-mouse-map |
|---|
| 402 |
(let ((map (make-sparse-keymap))) |
|---|
| 403 |
(define-key map (if (featurep 'xemacs) [button2] [down-mouse-2]) |
|---|
| 404 |
#'flyspell-correct-word) |
|---|
| 405 |
map) |
|---|
| 406 |
"Keymap for Flyspell to put on erroneous words.") |
|---|
| 407 |
|
|---|
| 408 |
(defvar flyspell-mode-map |
|---|
| 409 |
(let ((map (make-sparse-keymap))) |
|---|
| 410 |
(if flyspell-use-meta-tab |
|---|
| 411 |
(define-key map "\M-\t" 'flyspell-auto-correct-word)) |
|---|
| 412 |
(define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word) |
|---|
| 413 |
(define-key map [(control ?\,)] 'flyspell-goto-next-error) |
|---|
| 414 |
(define-key map [(control ?\.)] 'flyspell-auto-correct-word) |
|---|
| 415 |
(define-key map [?\C-c ?$] 'flyspell-correct-word-before-point) |
|---|
| 416 |
map) |
|---|
| 417 |
"Minor mode keymap for Flyspell mode--for the whole buffer.") |
|---|
| 418 |
|
|---|
| 419 |
|
|---|
| 420 |
(defvar flyspell-consider-dash-as-word-delimiter-flag nil |
|---|
| 421 |
"*Non-nil means that the `-' char is considered as a word delimiter.") |
|---|
| 422 |
(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag) |
|---|
| 423 |
(defvar flyspell-dash-dictionary nil) |
|---|
| 424 |
(make-variable-buffer-local 'flyspell-dash-dictionary) |
|---|
| 425 |
(defvar flyspell-dash-local-dictionary nil) |
|---|
| 426 |
(make-variable-buffer-local 'flyspell-dash-local-dictionary) |
|---|
| 427 |
|
|---|
| 428 |
|
|---|
| 429 |
|
|---|
| 430 |
|
|---|
| 431 |
(defface flyspell-incorrect |
|---|
| 432 |
'((((class color)) (:foreground "OrangeRed" :bold t :underline t)) |
|---|
| 433 |
(t (:bold t))) |
|---|
| 434 |
"Face used for marking a misspelled word in Flyspell." |
|---|
| 435 |
:group 'flyspell) |
|---|
| 436 |
|
|---|
| 437 |
(put 'flyspell-incorrect-face 'face-alias 'flyspell-incorrect) |
|---|
| 438 |
|
|---|
| 439 |
(defface flyspell-duplicate |
|---|
| 440 |
'((((class color)) (:foreground "Gold3" :bold t :underline t)) |
|---|
| 441 |
(t (:bold t))) |
|---|
| 442 |
"Face used for marking a misspelled word that appears twice in the buffer. |
|---|
| 443 |
See also `flyspell-duplicate-distance'." |
|---|
| 444 |
:group 'flyspell) |
|---|
| 445 |
|
|---|
| 446 |
(put 'flyspell-duplicate-face 'face-alias 'flyspell-duplicate) |
|---|
| 447 |
|
|---|
| 448 |
(defvar flyspell-overlay nil) |
|---|
| 449 |
|
|---|
| 450 |
|
|---|
| 451 |
|
|---|
| 452 |
|
|---|
| 453 |
|
|---|
| 454 |
|
|---|
| 455 |
(define-minor-mode flyspell-mode |
|---|
| 456 |
"Minor mode performing on-the-fly spelling checking. |
|---|
| 457 |
This spawns a single Ispell process and checks each word. |
|---|
| 458 |
The default flyspell behavior is to highlight incorrect words. |
|---|
| 459 |
With no argument, this command toggles Flyspell mode. |
|---|
| 460 |
With a prefix argument ARG, turn Flyspell minor mode on if ARG is positive, |
|---|
| 461 |
otherwise turn it off. |
|---|
| 462 |
|
|---|
| 463 |
Bindings: |
|---|
| 464 |
\\[ispell-word]: correct words (using Ispell). |
|---|
| 465 |
\\[flyspell-auto-correct-word]: automatically correct word. |
|---|
| 466 |
\\[flyspell-auto-correct-previous-word]: automatically correct the last misspelled word. |
|---|
| 467 |
\\[flyspell-correct-word] (or down-mouse-2): popup correct words. |
|---|
| 468 |
|
|---|
| 469 |
Hooks: |
|---|
| 470 |
This runs `flyspell-mode-hook' after flyspell is entered. |
|---|
| 471 |
|
|---|
| 472 |
Remark: |
|---|
| 473 |
`flyspell-mode' uses `ispell-mode'. Thus all Ispell options are |
|---|
| 474 |
valid. For instance, a personal dictionary can be used by |
|---|
| 475 |
invoking `ispell-change-dictionary'. |
|---|
| 476 |
|
|---|
| 477 |
Consider using the `ispell-parser' to check your text. For instance |
|---|
| 478 |
consider adding: |
|---|
| 479 |
\(add-hook 'tex-mode-hook (function (lambda () (setq ispell-parser 'tex)))) |
|---|
| 480 |
in your .emacs file. |
|---|
| 481 |
|
|---|
| 482 |
\\[flyspell-region] checks all words inside a region. |
|---|
| 483 |
\\[flyspell-buffer] checks the whole buffer." |
|---|
| 484 |
:lighter flyspell-mode-line-string |
|---|
| 485 |
:keymap flyspell-mode-map |
|---|
| 486 |
:group 'flyspell |
|---|
| 487 |
(if flyspell-mode |
|---|
| 488 |
(condition-case () |
|---|
| 489 |
(flyspell-mode-on) |
|---|
| 490 |
(error (message "Enabling Flyspell mode gave an error") |
|---|
| 491 |
(flyspell-mode -1))) |
|---|
| 492 |
(flyspell-mode-off))) |
|---|
| 493 |
|
|---|
| 494 |
|
|---|
| 495 |
(defun turn-on-flyspell () |
|---|
| 496 |
"Unconditionally turn on Flyspell mode." |
|---|
| 497 |
(flyspell-mode 1)) |
|---|
| 498 |
|
|---|
| 499 |
|
|---|
| 500 |
(defun turn-off-flyspell () |
|---|
| 501 |
"Unconditionally turn off Flyspell mode." |
|---|
| 502 |
(flyspell-mode -1)) |
|---|
| 503 |
|
|---|
| 504 |
(custom-add-option 'text-mode-hook 'turn-on-flyspell) |
|---|
| 505 |
|
|---|
| 506 |
|
|---|
| 507 |
|
|---|
| 508 |
|
|---|
| 509 |
|
|---|
| 510 |
|
|---|
| 511 |
(defvar flyspell-buffers nil) |
|---|
| 512 |
|
|---|
| 513 |
|
|---|
| 514 |
|
|---|
| 515 |
|
|---|
| 516 |
(defun flyspell-minibuffer-p (buffer) |
|---|
| 517 |
"Is BUFFER a minibuffer?" |
|---|
| 518 |
(let ((ws (get-buffer-window-list buffer t))) |
|---|
| 519 |
(and (consp ws) (window-minibuffer-p (car ws))))) |
|---|
| 520 |
|
|---|
| 521 |
|
|---|
| 522 |
|
|---|
| 523 |
|
|---|
| 524 |
(defvar flyspell-last-buffer nil |
|---|
| 525 |
"The buffer in which the last flyspell operation took place.") |
|---|
| 526 |
|
|---|
| 527 |
(defun flyspell-accept-buffer-local-defs (&optional force) |
|---|
| 528 |
|
|---|
| 529 |
|
|---|
| 530 |
|
|---|
| 531 |
(when (or force (not (eq flyspell-last-buffer (current-buffer)))) |
|---|
| 532 |
(setq flyspell-last-buffer (current-buffer)) |
|---|
| 533 |
|
|---|
| 534 |
|
|---|
| 535 |
|
|---|
| 536 |
|
|---|
| 537 |
(save-current-buffer |
|---|
| 538 |
(ispell-accept-buffer-local-defs)) |
|---|
| 539 |
(unless (and (eq flyspell-dash-dictionary ispell-dictionary) |
|---|
| 540 |
(eq flyspell-dash-local-dictionary ispell-local-dictionary)) |
|---|
| 541 |
|
|---|
| 542 |
(setq flyspell-dash-dictionary ispell-dictionary) |
|---|
| 543 |
(setq flyspell-dash-local-dictionary ispell-local-dictionary) |
|---|
| 544 |
(setq flyspell-consider-dash-as-word-delimiter-flag |
|---|
| 545 |
(member (or ispell-local-dictionary ispell-dictionary) |
|---|
| 546 |
flyspell-dictionaries-that-consider-dash-as-word-delimiter))))) |
|---|
| 547 |
|
|---|
| 548 |
(defun flyspell-hack-local-variables-hook () |
|---|
| 549 |
|
|---|
| 550 |
|
|---|
| 551 |
(flyspell-accept-buffer-local-defs 'force)) |
|---|
| 552 |
|
|---|
| 553 |
(defun flyspell-kill-ispell-hook () |
|---|
| 554 |
(setq flyspell-last-buffer nil) |
|---|
| 555 |
(dolist (buf (buffer-list)) |
|---|
| 556 |
(with-current-buffer buf |
|---|
| 557 |
(kill-local-variable 'flyspell-word-cache-word)))) |
|---|
| 558 |
|
|---|
| 559 |
|
|---|
| 560 |
|
|---|
| 561 |
|
|---|
| 562 |
(add-hook 'ispell-kill-ispell-hook 'flyspell-kill-ispell-hook) |
|---|
| 563 |
|
|---|
| 564 |
|
|---|
| 565 |
|
|---|
| 566 |
|
|---|
| 567 |
(defun flyspell-mode-on () |
|---|
| 568 |
"Turn Flyspell mode on. Do not use this; use `flyspell-mode' instead." |
|---|
| 569 |
(ispell-maybe-find-aspell-dictionaries) |
|---|
| 570 |
(setq ispell-highlight-face 'flyspell-incorrect) |
|---|
| 571 |
|
|---|
| 572 |
(or ispell-local-dictionary ispell-dictionary |
|---|
| 573 |
(if flyspell-default-dictionary |
|---|
| 574 |
(ispell-change-dictionary flyspell-default-dictionary))) |
|---|
| 575 |
|
|---|
| 576 |
|
|---|
| 577 |
|
|---|
| 578 |
|
|---|
| 579 |
|
|---|
| 580 |
(flyspell-accept-buffer-local-defs 'force) |
|---|
| 581 |
|
|---|
| 582 |
(flyspell-delay-commands) |
|---|
| 583 |
|
|---|
| 584 |
(flyspell-deplacement-commands) |
|---|
| 585 |
|
|---|
| 586 |
(add-hook 'post-command-hook (function flyspell-post-command-hook) t t) |
|---|
| 587 |
|
|---|
| 588 |
(add-hook 'pre-command-hook (function flyspell-pre-command-hook) t t) |
|---|
| 589 |
|
|---|
| 590 |
(add-hook 'after-change-functions 'flyspell-after-change-function nil t) |
|---|
| 591 |
|
|---|
| 592 |
(add-hook 'hack-local-variables-hook |
|---|
| 593 |
(function flyspell-hack-local-variables-hook) t t) |
|---|
| 594 |
|
|---|
| 595 |
(let ((mode-predicate (get major-mode 'flyspell-mode-predicate))) |
|---|
| 596 |
(if mode-predicate |
|---|
| 597 |
(setq flyspell-generic-check-word-predicate mode-predicate))) |
|---|
| 598 |
|
|---|
| 599 |
(if (and flyspell-issue-message-flag |
|---|
| 600 |
flyspell-issue-welcome-flag |
|---|
| 601 |
(interactive-p)) |
|---|
| 602 |
(let ((binding (where-is-internal 'flyspell-auto-correct-word |
|---|
| 603 |
nil 'non-ascii))) |
|---|
| 604 |
(message "%s" |
|---|
| 605 |
(if binding |
|---|
| 606 |
(format "Welcome to flyspell. Use %s or Mouse-2 to correct words." |
|---|
| 607 |
(key-description binding)) |
|---|
| 608 |
"Welcome to flyspell. Use Mouse-2 to correct words.")))) |
|---|
| 609 |
|
|---|
| 610 |
(run-hooks 'flyspell-mode-hook)) |
|---|
| 611 |
|
|---|
| 612 |
|
|---|
| 613 |
|
|---|
| 614 |
|
|---|
| 615 |
(defun flyspell-delay-commands () |
|---|
| 616 |
"Install the standard set of Flyspell delayed commands." |
|---|
| 617 |
(mapcar 'flyspell-delay-command flyspell-default-delayed-commands) |
|---|
| 618 |
(mapcar 'flyspell-delay-command flyspell-delayed-commands)) |
|---|
| 619 |
|
|---|
| 620 |
|
|---|
| 621 |
|
|---|
| 622 |
|
|---|
| 623 |
(defun flyspell-delay-command (command) |
|---|
| 624 |
"Set COMMAND to be delayed, for Flyspell. |
|---|
| 625 |
When flyspell `post-command-hook' is invoked because a delayed command |
|---|
| 626 |
as been used the current word is not immediately checked. |
|---|
| 627 |
It will be checked only after `flyspell-delay' seconds." |
|---|
| 628 |
(interactive "SDelay Flyspell after Command: ") |
|---|
| 629 |
(put command 'flyspell-delayed t)) |
|---|
| 630 |
|
|---|
| 631 |
|
|---|
| 632 |
|
|---|
| 633 |
|
|---|
| 634 |
(defun flyspell-deplacement-commands () |
|---|
| 635 |
"Install the standard set of Flyspell deplacement commands." |
|---|
| 636 |
(mapcar 'flyspell-deplacement-command flyspell-default-deplacement-commands) |
|---|
| 637 |
(mapcar 'flyspell-deplacement-command flyspell-deplacement-commands)) |
|---|
| 638 |
|
|---|
| 639 |
|
|---|
| 640 |
|
|---|
| 641 |
|
|---|
| 642 |
(defun flyspell-deplacement-command (command) |
|---|
| 643 |
"Set COMMAND that implement cursor movements, for Flyspell. |
|---|
| 644 |
When flyspell `post-command-hook' is invoked because of a deplacement command |
|---|
| 645 |
as been used the current word is checked only if the previous command was |
|---|
| 646 |
not the very same deplacement command." |
|---|
| 647 |
(interactive "SDeplacement Flyspell after Command: ") |
|---|
| 648 |
(put command 'flyspell-deplacement t)) |
|---|
| 649 |
|
|---|
| 650 |
|
|---|
| 651 |
|
|---|
| 652 |
|
|---|
| 653 |
(defvar flyspell-word-cache-start nil) |
|---|
| 654 |
(defvar flyspell-word-cache-end nil) |
|---|
| 655 |
(defvar flyspell-word-cache-word nil) |
|---|
| 656 |
(defvar flyspell-word-cache-result '_) |
|---|
| 657 |
(make-variable-buffer-local 'flyspell-word-cache-start) |
|---|
| 658 |
(make-variable-buffer-local 'flyspell-word-cache-end) |
|---|
| 659 |
(make-variable-buffer-local 'flyspell-word-cache-word) |
|---|
| 660 |
(make-variable-buffer-local 'flyspell-word-cache-result) |
|---|
| 661 |
|
|---|
| 662 |
|
|---|
| 663 |
|
|---|
| 664 |
|
|---|
| 665 |
|
|---|
| 666 |
|
|---|
| 667 |
(defvar flyspell-pre-buffer nil) |
|---|
| 668 |
(defvar flyspell-pre-point nil) |
|---|
| 669 |
(defvar flyspell-pre-column nil) |
|---|
| 670 |
(defvar flyspell-pre-pre-buffer nil) |
|---|
| 671 |
(defvar flyspell-pre-pre-point nil) |
|---|
| 672 |
|
|---|
| 673 |
|
|---|
| 674 |
|
|---|
| 675 |
|
|---|
| 676 |
(defvar flyspell-previous-command nil |
|---|
| 677 |
"The last interactive command checked by Flyspell.") |
|---|
| 678 |
|
|---|
| 679 |
|
|---|
| 680 |
|
|---|
| 681 |
|
|---|
| 682 |
(defun flyspell-pre-command-hook () |
|---|
| 683 |
"Save the current buffer and point for Flyspell's post-command hook." |
|---|
| 684 |
(interactive) |
|---|
| 685 |
(setq flyspell-pre-buffer (current-buffer)) |
|---|
| 686 |
(setq flyspell-pre-point (point)) |
|---|
| 687 |
(setq flyspell-pre-column (current-column))) |
|---|
| 688 |
|
|---|
| 689 |
|
|---|
| 690 |
|
|---|
| 691 |
|
|---|
| 692 |
|
|---|
| 693 |
(defun flyspell-mode-off () |
|---|
| 694 |
"Turn Flyspell mode off." |
|---|
| 695 |
|
|---|
| 696 |
(remove-hook 'post-command-hook (function flyspell-post-command-hook) t) |
|---|
| 697 |
(remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t) |
|---|
| 698 |
(remove-hook 'after-change-functions 'flyspell-after-change-function t) |
|---|
| 699 |
(remove-hook 'hack-local-variables-hook |
|---|
| 700 |
(function flyspell-hack-local-variables-hook) t) |
|---|
| 701 |
|
|---|
| 702 |
(flyspell-delete-all-overlays) |
|---|
| 703 |
|
|---|
| 704 |
(setq flyspell-pre-buffer nil) |
|---|
| 705 |
(setq flyspell-pre-point nil) |
|---|
| 706 |
|
|---|
| 707 |
(setq flyspell-mode nil)) |
|---|
| 708 |
|
|---|
| 709 |
|
|---|
| 710 |
|
|---|
| 711 |
|
|---|
| 712 |
(defun flyspell-check-pre-word-p () |
|---|
| 713 |
"Return non-nil if we should check the word before point. |
|---|
| 714 |
More precisely, it applies to the word that was before point |
|---|
| 715 |
before the current command." |
|---|
| 716 |
(cond |
|---|
| 717 |
((or (not (numberp flyspell-pre-point)) |
|---|
| 718 |
(not (bufferp flyspell-pre-buffer)) |
|---|
| 719 |
(not (buffer-live-p flyspell-pre-buffer))) |
|---|
| 720 |
nil) |
|---|
| 721 |
((and (eq flyspell-pre-pre-point flyspell-pre-point) |
|---|
| 722 |
(eq flyspell-pre-pre-buffer flyspell-pre-buffer)) |
|---|
| 723 |
nil) |
|---|
| 724 |
((or (and (= flyspell-pre-point (- (point) 1)) |
|---|
| 725 |
(eq (char-syntax (char-after flyspell-pre-point)) ?w)) |
|---|
| 726 |
(= flyspell-pre-point (point)) |
|---|
| 727 |
(= flyspell-pre-point (+ (point) 1))) |
|---|
| 728 |
nil) |
|---|
| 729 |
((and (symbolp this-command) |
|---|
| 730 |
(not executing-kbd-macro) |
|---|
| 731 |
(or (get this-command 'flyspell-delayed) |
|---|
| 732 |
(and (get this-command 'flyspell-deplacement) |
|---|
| 733 |
(eq flyspell-previous-command this-command))) |
|---|
| 734 |
(or (= (current-column) 0) |
|---|
| 735 |
(= (current-column) flyspell-pre-column) |
|---|
| 736 |
(eq (char-syntax (char-after flyspell-pre-point)) ?w))) |
|---|
| 737 |
nil) |
|---|
| 738 |
((not (eq (current-buffer) flyspell-pre-buffer)) |
|---|
| 739 |
t) |
|---|
| 740 |
((not (and (numberp flyspell-word-cache-start) |
|---|
| 741 |
(numberp flyspell-word-cache-end))) |
|---|
| 742 |
t) |
|---|
| 743 |
(t |
|---|
| 744 |
(or (< flyspell-pre-point flyspell-word-cache-start) |
|---|
| 745 |
(> flyspell-pre-point flyspell-word-cache-end))))) |
|---|
| 746 |
|
|---|
| 747 |
|
|---|
| 748 |
|
|---|
| 749 |
|
|---|
| 750 |
|
|---|
| 751 |
|
|---|
| 752 |
(defvar flyspell-changes nil) |
|---|
| 753 |
(make-variable-buffer-local 'flyspell-changes) |
|---|
| 754 |
|
|---|
| 755 |
|
|---|
| 756 |
|
|---|
| 757 |
|
|---|
| 758 |
(defun flyspell-after-change-function (start stop len) |
|---|
| 759 |
"Save the current buffer and point for Flyspell's post-command hook." |
|---|
| 760 |
(push (cons start stop) flyspell-changes)) |
|---|
| 761 |
|
|---|
| 762 |
|
|---|
| 763 |
|
|---|
| 764 |
|
|---|
| 765 |
(defun flyspell-check-changed-word-p (start stop) |
|---|
| 766 |
"Return t when the changed word has to be checked. |
|---|
| 767 |
The answer depends of several criteria. |
|---|
| 768 |
Mostly we check word delimiters." |
|---|
| 769 |
(cond |
|---|
| 770 |
((and (memq (char-after start) '(?\n ? )) (> stop start)) |
|---|
| 771 |
t) |
|---|
| 772 |
((not (numberp flyspell-pre-point)) |
|---|
| 773 |
t) |
|---|
| 774 |
((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop)) |
|---|
| 775 |
nil) |
|---|
| 776 |
((let ((pos (point))) |
|---|
| 777 |
(or (>= pos start) (<= pos stop) (= pos (1+ stop)))) |
|---|
| 778 |
nil) |
|---|
| 779 |
(t |
|---|
| 780 |
t))) |
|---|
| 781 |
|
|---|
| 782 |
|
|---|
| 783 |
|
|---|
| 784 |
|
|---|
| 785 |
(defun flyspell-check-word-p () |
|---|
| 786 |
"Return t when the word at `point' has to be checked. |
|---|
| 787 |
The answer depends of several criteria. |
|---|
| 788 |
Mostly we check word delimiters." |
|---|
| 789 |
(cond |
|---|
| 790 |
((<= (- (point-max) 1) (point-min)) |
|---|
| 791 |
|
|---|
| 792 |
nil) |
|---|
| 793 |
((and (and (> (current-column) 0) |
|---|
| 794 |
(not (eq (current-column) flyspell-pre-column))) |
|---|
| 795 |
(save-excursion |
|---|
| 796 |
(backward-char 1) |
|---|
| 797 |
(and (looking-at (flyspell-get-not-casechars)) |
|---|
| 798 |
(or flyspell-consider-dash-as-word-delimiter-flag |
|---|
| 799 |
(not (looking-at "-")))))) |
|---|
|