1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: emacs-lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;; |
---|
2 | ;;; GNU EMACS interface for International Ispell Version 3.1 by Geoff Kuenning. |
---|
3 | ;;; |
---|
4 | ;;; |
---|
5 | ;;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. |
---|
6 | ;;; |
---|
7 | ;;; |
---|
8 | ;;; Authors : Ken Stevens <k.stevens@ieee.org> |
---|
9 | ;;; Last Modified On: Tue Jun 13 12:05:28 EDT 1995 |
---|
10 | ;;; Update Revision : 2.37 |
---|
11 | ;;; Syntax : emacs-lisp |
---|
12 | ;;; Status : Release with 3.1.12+ ispell. |
---|
13 | ;;; Version : International Ispell Version 3.1 by Geoff Kuenning. |
---|
14 | ;;; Bug Reports : ispell-el-bugs@itcorp.com |
---|
15 | ;;; |
---|
16 | ;;; Note: version numbers and time stamp are not updated |
---|
17 | ;;; when this file is edited for release with GNU emacs. |
---|
18 | ;;; |
---|
19 | ;;; This file is part of GNU Emacs. |
---|
20 | ;;; |
---|
21 | ;;; GNU Emacs is free software; you can redistribute it and/or modify |
---|
22 | ;;; it under the terms of the GNU General Public License as published by |
---|
23 | ;;; the Free Software Foundation; either version 2, or (at your option) |
---|
24 | ;;; any later version. |
---|
25 | ;;; |
---|
26 | ;;; GNU Emacs is distributed in the hope that it will be useful, |
---|
27 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
28 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
29 | ;;; GNU General Public License for more details. |
---|
30 | ;;; |
---|
31 | ;;; You should have received a copy of the GNU General Public License |
---|
32 | ;;; along with GNU Emacs; see the file COPYING. If not, write to |
---|
33 | ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
34 | ;;; |
---|
35 | ;;; Commentary: |
---|
36 | ;;; |
---|
37 | ;;; INSTRUCTIONS |
---|
38 | ;;; |
---|
39 | ;;; This code contains a section of user-settable variables that you should |
---|
40 | ;;; inspect prior to installation. Look past the end of the history list. |
---|
41 | ;;; Set them up for your locale and the preferences of the majority of the |
---|
42 | ;;; users. Otherwise the users may need to set a number of variables |
---|
43 | ;;; themselves. |
---|
44 | ;;; You particularly may want to change the default dictionary for your |
---|
45 | ;;; country and language. |
---|
46 | ;;; |
---|
47 | ;;; |
---|
48 | ;;; To fully install this, add this file to your Emacs Lisp directory and |
---|
49 | ;;; compile it with M-X byte-compile-file. Then add the following to the |
---|
50 | ;;; appropriate init file: |
---|
51 | ;;; |
---|
52 | ;;; (autoload 'ispell-word "ispell" |
---|
53 | ;;; "Check the spelling of word in buffer." t) |
---|
54 | ;;; (global-set-key "\e$" 'ispell-word) |
---|
55 | ;;; (autoload 'ispell-region "ispell" |
---|
56 | ;;; "Check the spelling of region." t) |
---|
57 | ;;; (autoload 'ispell-buffer "ispell" |
---|
58 | ;;; "Check the spelling of buffer." t) |
---|
59 | ;;; (autoload 'ispell-complete-word "ispell" |
---|
60 | ;;; "Look up current word in dictionary and try to complete it." t) |
---|
61 | ;;; (autoload 'ispell-change-dictionary "ispell" |
---|
62 | ;;; "Change ispell dictionary." t) |
---|
63 | ;;; (autoload 'ispell-message "ispell" |
---|
64 | ;;; "Check spelling of mail message or news post.") |
---|
65 | ;;; |
---|
66 | ;;; Depending on the mail system you use, you may want to include these: |
---|
67 | ;;; |
---|
68 | ;;; (add-hook 'news-inews-hook 'ispell-message) |
---|
69 | ;;; (add-hook 'mail-send-hook 'ispell-message) |
---|
70 | ;;; (add-hook 'mh-before-send-letter-hook 'ispell-message) |
---|
71 | ;;; |
---|
72 | ;;; |
---|
73 | ;;; Ispell has a TeX parser and a nroff parser (the default). |
---|
74 | ;;; The parsing is controlled by the variable ispell-parser. Currently |
---|
75 | ;;; it is just a "toggle" between TeX and nroff, but if more parsers are |
---|
76 | ;;; added it will be updated. See the variable description for more info. |
---|
77 | ;;; |
---|
78 | ;;; |
---|
79 | ;;; TABLE OF CONTENTS |
---|
80 | ;;; |
---|
81 | ;;; ispell-word |
---|
82 | ;;; ispell-region |
---|
83 | ;;; ispell-buffer |
---|
84 | ;;; ispell-message |
---|
85 | ;;; ispell-continue |
---|
86 | ;;; ispell-complete-word |
---|
87 | ;;; ispell-complete-word-interior-frag |
---|
88 | ;;; ispell-change-dictionary |
---|
89 | ;;; ispell-kill-ispell |
---|
90 | ;;; ispell-pdict-save |
---|
91 | ;;; |
---|
92 | ;;; |
---|
93 | ;;; Commands in ispell-region: |
---|
94 | ;;; Character replacement: Replace word with choice. May query-replace. |
---|
95 | ;;; ' ': Accept word this time. |
---|
96 | ;;; 'i': Accept word and insert into private dictionary. |
---|
97 | ;;; 'a': Accept word for this session. |
---|
98 | ;;; 'A': Accept word and place in buffer-local dictionary. |
---|
99 | ;;; 'r': Replace word with typed-in value. Rechecked. |
---|
100 | ;;; 'R': Replace word with typed-in value. Query-replaced in buffer. Rechecked. |
---|
101 | ;;; '?': Show these commands |
---|
102 | ;;; 'x': Exit spelling buffer. Move cursor to original point. |
---|
103 | ;;; 'X': Exit spelling buffer. Leave cursor at the current point. |
---|
104 | ;;; 'q': Quit spelling session (Kills ispell process). |
---|
105 | ;;; 'l': Look up typed-in replacement in alternate dictionary. Wildcards okay. |
---|
106 | ;;; 'u': Like 'i', but the word is lower-cased first. |
---|
107 | ;;; 'm': Like 'i', but allows one to include dictionary completion info. |
---|
108 | ;;; 'C-l': redraws screen |
---|
109 | ;;; 'C-r': recursive edit |
---|
110 | ;;; 'C-z': suspend emacs or iconify frame |
---|
111 | ;;; |
---|
112 | ;;; Buffer-Local features: |
---|
113 | ;;; There are a number of buffer-local features that can be used to customize |
---|
114 | ;;; ispell for the current buffer. This includes language dictionaries, |
---|
115 | ;;; personal dictionaries, parsing, and local word spellings. Each of these |
---|
116 | ;;; local customizations are done either through local variables, or by |
---|
117 | ;;; including the keyword and argument(s) at the end of the buffer (usually |
---|
118 | ;;; prefixed by the comment characters). See the end of this file for |
---|
119 | ;;; examples. The local keywords and variables are: |
---|
120 | ;;; |
---|
121 | ;;; ispell-dictionary-keyword language-dictionary |
---|
122 | ;;; uses local variable ispell-local-dictionary |
---|
123 | ;;; ispell-pdict-keyword personal-dictionary |
---|
124 | ;;; uses local variable ispell-local-pdict |
---|
125 | ;;; ispell-parsing-keyword mode-arg extended-char-arg |
---|
126 | ;;; ispell-words-keyword any number of local word spellings |
---|
127 | ;;; |
---|
128 | ;;; |
---|
129 | ;;; BUGS: |
---|
130 | ;;; Highlighting in version 19 still doesn't work on tty's. |
---|
131 | ;;; On some versions of emacs, growing the minibuffer fails. |
---|
132 | ;;; |
---|
133 | ;;; HISTORY |
---|
134 | ;;; |
---|
135 | ;;; Revision 2.37 1995/6/13 12:05:28 stevens |
---|
136 | ;;; Removed autoload from ispell-dictionary-alist. *choices* mode-line shows |
---|
137 | ;;; misspelled word. Block skip for pgp & forwarded messages added. |
---|
138 | ;;; |
---|
139 | ;;; Revision 2.36 1995/2/6 17:39:38 stevens |
---|
140 | ;;; Properly adjust screen with different ispell-choices-win-default-height |
---|
141 | ;;; settings. Skips SGML entity references. |
---|
142 | ;;; |
---|
143 | ;;; Revision 2.35 1995/1/13 14:16:46 stevens |
---|
144 | ;;; Skips SGML tags, ispell-change-dictionary fix for add-hook, assure personal |
---|
145 | ;;; dictionary is saved when called from the menu |
---|
146 | ;;; |
---|
147 | ;;; Revision 2.34 1994/12/08 13:17:41 stevens |
---|
148 | ;;; Interaction corrected to function with all 3.1 ispell versions. |
---|
149 | ;;; |
---|
150 | ;;; Revision 2.33 1994/11/24 02:31:20 stevens |
---|
151 | ;;; Repaired bug introduced in 2.32 that corrupts buffers when correcting. |
---|
152 | ;;; Improved buffer scrolling. Nondestructive buffer selections allowed. |
---|
153 | ;;; |
---|
154 | ;;; Revision 2.32 1994/10/31 21:10:08 geoff |
---|
155 | ;;; Many revisions accepted from RMS/FSF. I think (though I don't know) that |
---|
156 | ;;; this represents an 'official' version. |
---|
157 | ;;; |
---|
158 | ;;; Revision 2.31 1994/5/31 10:18:17 stevens |
---|
159 | ;;; Repaired comments. buffer-local commands executed in `ispell-word' now. |
---|
160 | ;;; German dictionary described for extended character mode. Dict messages. |
---|
161 | ;;; |
---|
162 | ;;; Revision 2.30 1994/5/20 22:18:36 stevens |
---|
163 | ;;; Continue ispell from ispell-word, C-z functionality fixed. |
---|
164 | ;;; |
---|
165 | ;;; Revision 2.29 1994/5/12 09:44:33 stevens |
---|
166 | ;;; Restored ispell-use-ptys-p, ispell-message aborts sends with interrupt. |
---|
167 | ;;; defined fn ispell |
---|
168 | ;;; |
---|
169 | ;;; Revision 2.28 1994/4/28 16:24:40 stevens |
---|
170 | ;;; Window checking when ispell-message put on gnus-inews-article-hook jwz. |
---|
171 | ;;; prefixed ispell- to highlight functions and horiz-scroll fn. |
---|
172 | ;;; Try and respect case of word in ispell-complete-word. |
---|
173 | ;;; Ignore non-char events. Ispell-use-ptys-p commented out. Lucid menu. |
---|
174 | ;;; Better interrupt handling. ispell-message improvements from Ethan. |
---|
175 | ;;; |
---|
176 | ;;; Revision 2.27 |
---|
177 | ;;; version 18 explicit C-g handling disabled as it didn't work. Added |
---|
178 | ;;; ispell-extra-args for ispell customization (jwz) |
---|
179 | ;;; |
---|
180 | ;;; Revision 2.26 1994/2/15 16:11:14 stevens |
---|
181 | ;;; name changes for copyright assignment. Added word-frags in complete-word. |
---|
182 | ;;; Horizontal scroll (John Conover). Query-replace matches words now. bugs. |
---|
183 | ;;; |
---|
184 | ;;; Revision 2.25 |
---|
185 | ;;; minor mods, upgraded ispell-message |
---|
186 | ;;; |
---|
187 | ;;; Revision 2.24 |
---|
188 | ;;; query-replace more robust, messages, defaults, ispell-change-dict. |
---|
189 | ;;; |
---|
190 | ;;; Revision 2.23 1993/11/22 23:47:03 stevens |
---|
191 | ;;; ispell-message, Fixed highlighting, added menu-bar, fixed ispell-help, ... |
---|
192 | ;;; |
---|
193 | ;;; Revision 2.22 |
---|
194 | ;;; Added 'u' command. Fixed default in ispell-local-dictionary. |
---|
195 | ;;; fixed affix rules display. Tib skipping more robust. Contributions by |
---|
196 | ;;; Per Abraham (parser selection), Denis Howe, and Eberhard Mattes. |
---|
197 | ;;; |
---|
198 | ;;; Revision 2.21 1993/06/30 14:09:04 stevens |
---|
199 | ;;; minor bugs. (nroff word skipping fixed) |
---|
200 | ;;; |
---|
201 | ;;; Revision 2.20 1993/06/30 14:09:04 stevens |
---|
202 | ;;; |
---|
203 | ;;; Debugging and contributions by: Boris Aronov, Rik Faith, Chris Moore, |
---|
204 | ;;; Kevin Rodgers, Malcolm Davis. |
---|
205 | ;;; Particular thanks to Michael Lipp, Jamie Zawinski, Phil Queinnec |
---|
206 | ;;; and John Heidemann for suggestions and code. |
---|
207 | ;;; Major update including many tweaks. |
---|
208 | ;;; Many changes were integrations of suggestions. |
---|
209 | ;;; lookup-words rehacked to use call-process (Jamie). |
---|
210 | ;;; ispell-complete-word rehacked to be compatible with the rest of the |
---|
211 | ;;; system for word searching and to include multiple wildcards, |
---|
212 | ;;; and it's own dictionary. |
---|
213 | ;;; query-replace capability added. New options 'X', 'R', and 'A'. |
---|
214 | ;;; buffer-local modes for dictionary, word-spelling, and formatter-parsing. |
---|
215 | ;;; Many random bugs, like commented comments being skipped, fix to |
---|
216 | ;;; keep-choices-win, fix for math mode, added pipe mode choice, |
---|
217 | ;;; fixed 'q' command, ispell-word checks previous word and leave cursor |
---|
218 | ;;; in same location. Fixed tib code which could drop spelling regions. |
---|
219 | ;;; Cleaned up setq calls for efficiency. Gave more context on window overlays. |
---|
220 | ;;; Assure context on ispell-command-loop. Window lossage in look cmd fixed. |
---|
221 | ;;; Due to pervasive opinion, common-lisp package syntax removed. Display |
---|
222 | ;;; problem when not highlighting. |
---|
223 | ;;; |
---|
224 | ;;; Revision 2.19 1992/01/10 10:54:08 geoff |
---|
225 | ;;; Make another attempt at fixing the "Bogus, dude" problem. This one is |
---|
226 | ;;; less elegant, but has the advantage of working. |
---|
227 | ;;; |
---|
228 | ;;; Revision 2.18 1992/01/07 10:04:52 geoff |
---|
229 | ;;; Fix the "Bogus, Dude" problem in ispell-word. |
---|
230 | ;;; |
---|
231 | ;;; Revision 2.17 1991/09/12 00:01:42 geoff |
---|
232 | ;;; Add some changes to make ispell-complete-word work better, though |
---|
233 | ;;; still not perfectly. |
---|
234 | ;;; |
---|
235 | ;;; Revision 2.16 91/09/04 18:00:52 geoff |
---|
236 | ;;; More updates from Sebastian, to make the multiple-dictionary support |
---|
237 | ;;; more flexible. |
---|
238 | ;;; |
---|
239 | ;;; Revision 2.15 91/09/04 17:30:02 geoff |
---|
240 | ;;; Sebastian Kremer's tib support |
---|
241 | ;;; |
---|
242 | ;;; Revision 2.14 91/09/04 16:19:37 geoff |
---|
243 | ;;; Don't do set-window-start if the move-to-window-line moved us |
---|
244 | ;;; downward, rather than upward. This prevents getting the buffer all |
---|
245 | ;;; confused. Also, don't use the "not-modified" function to clear the |
---|
246 | ;;; modification flag; instead use set-buffer-modified-p. This prevents |
---|
247 | ;;; extra messages from flashing. |
---|
248 | ;;; |
---|
249 | ;;; Revision 2.13 91/09/04 14:35:41 geoff |
---|
250 | ;;; Fix a spelling error in a comment. Add code to handshake with the |
---|
251 | ;;; ispell process before sending anything to it. |
---|
252 | ;;; |
---|
253 | ;;; Revision 2.12 91/09/03 20:14:21 geoff |
---|
254 | ;;; Add Sebastian Kremer's multiple-language support. |
---|
255 | ;;; |
---|
256 | ;;; |
---|
257 | ;;; Walt Buehring |
---|
258 | ;;; Texas Instruments - Computer Science Center |
---|
259 | ;;; ARPA: Buehring%TI-CSL@CSNet-Relay |
---|
260 | ;;; UUCP: {smu, texsun, im4u, rice} ! ti-csl ! buehring |
---|
261 | ;;; |
---|
262 | ;;; ispell-region and associated routines added by |
---|
263 | ;;; Perry Smith |
---|
264 | ;;; pedz@bobkat |
---|
265 | ;;; Tue Jan 13 20:18:02 CST 1987 |
---|
266 | ;;; |
---|
267 | ;;; extensively modified by Mark Davies and Andrew Vignaux |
---|
268 | ;;; {mark,andrew}@vuwcomp |
---|
269 | ;;; Sun May 10 11:45:04 NZST 1987 |
---|
270 | ;;; |
---|
271 | ;;; Ken Stevens ARPA: k.stevens@ieee.org |
---|
272 | ;;; Tue Jan 3 16:59:07 PST 1989 |
---|
273 | ;;; This file has overgone a major overhaul to be compatible with ispell |
---|
274 | ;;; version 2.1. Most of the functions have been totally rewritten, and |
---|
275 | ;;; many user-accessible variables have been added. The syntax table has |
---|
276 | ;;; been removed since it didn't work properly anyway, and a filter is |
---|
277 | ;;; used rather than a buffer. Regular expressions are used based on |
---|
278 | ;;; ispell's internal definition of characters (see ispell(4)). |
---|
279 | ;;; Some new updates: |
---|
280 | ;;; - Updated to version 3.0 to include terse processing. |
---|
281 | ;;; - Added a variable for the look command. |
---|
282 | ;;; - Fixed a bug in ispell-word when cursor is far away from the word |
---|
283 | ;;; that is to be checked. |
---|
284 | ;;; - Ispell places the incorrect word or guess in the minibuffer now. |
---|
285 | ;;; - fixed a bug with 'l' option when multiple windows are on the screen. |
---|
286 | ;;; - lookup-words just didn't work with the process filter. Fixed. |
---|
287 | ;;; - Rewrote the process filter to make it cleaner and more robust |
---|
288 | ;;; in the event of a continued line not being completed. |
---|
289 | ;;; - Made ispell-init-process more robust in handling errors. |
---|
290 | ;;; - Fixed bug in continuation location after a region has been modified by |
---|
291 | ;;; correcting a misspelling. |
---|
292 | ;;; Mon 17 Sept 1990 |
---|
293 | ;;; |
---|
294 | ;;; Sebastian Kremer <sk@thp.uni-koeln.de> |
---|
295 | ;;; Wed Aug 7 14:02:17 MET DST 1991 |
---|
296 | ;;; - Ported ispell-complete-word from Ispell 2 to Ispell 3. |
---|
297 | ;;; - Added ispell-kill-ispell command. |
---|
298 | ;;; - Added ispell-dictionary and ispell-dictionary-alist variables to |
---|
299 | ;;; support other than default language. See their docstrings and |
---|
300 | ;;; command ispell-change-dictionary. |
---|
301 | ;;; - (ispelled it :-) |
---|
302 | ;;; - Added ispell-skip-tib variable to support the tib bibliography |
---|
303 | ;;; program. |
---|
304 | ;;; |
---|
305 | ;;; |
---|
306 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
---|
307 | |
---|
308 | |
---|
309 | |
---|
310 | ;;; ********************************************************************** |
---|
311 | ;;; The following variables should be set according to personal preference |
---|
312 | ;;; and location of binaries: |
---|
313 | ;;; ********************************************************************** |
---|
314 | |
---|
315 | |
---|
316 | ;;; ******* THIS FILE IS WRITTEN FOR ISPELL VERSION 3.1 |
---|
317 | ;;; Code: |
---|
318 | |
---|
319 | (defvar ispell-highlight-p t |
---|
320 | "*Highlight spelling errors when non-nil.") |
---|
321 | |
---|
322 | (defvar ispell-highlight-face 'highlight |
---|
323 | "*The face used for Ispell highlighting. For Emacses with overlays. |
---|
324 | Possible values are `highlight', `modeline', `secondary-selection', |
---|
325 | `region', and `underline'. |
---|
326 | This variable can be set by the user to whatever face they desire. |
---|
327 | It's most convenient if the cursor color and highlight color are |
---|
328 | slightly different.") |
---|
329 | |
---|
330 | (defvar ispell-check-comments nil |
---|
331 | "*Spelling of comments checked when non-nil.") |
---|
332 | |
---|
333 | (defvar ispell-query-replace-choices nil |
---|
334 | "*Corrections made throughout region when non-nil. |
---|
335 | Uses `query-replace' (\\[query-replace]) for corrections.") |
---|
336 | |
---|
337 | (defvar ispell-skip-tib nil |
---|
338 | "*Does not spell check `tib' bibliography references when non-nil. |
---|
339 | Skips any text between strings matching regular expressions |
---|
340 | `ispell-tib-ref-beginning' and `ispell-tib-ref-end'. |
---|
341 | |
---|
342 | TeX users beware: Any field starting with [. will skip until a .] -- even |
---|
343 | your whole buffer -- unless you set `ispell-skip-tib' to nil. That includes |
---|
344 | a [.5mm] type of number....") |
---|
345 | |
---|
346 | (defvar ispell-tib-ref-beginning "[[<]\\." |
---|
347 | "Regexp matching the beginning of a Tib reference.") |
---|
348 | |
---|
349 | (defvar ispell-tib-ref-end "\\.[]>]" |
---|
350 | "Regexp matching the end of a Tib reference.") |
---|
351 | |
---|
352 | (defvar ispell-keep-choices-win t |
---|
353 | "*When not nil, the `*Choices*' window remains for spelling session. |
---|
354 | This minimizes redisplay thrashing.") |
---|
355 | |
---|
356 | (defvar ispell-choices-win-default-height 2 |
---|
357 | "*The default size of the `*Choices*' window, including status line. |
---|
358 | Must be greater than 1.") |
---|
359 | |
---|
360 | (defvar ispell-program-name "ispell" |
---|
361 | "Program invoked by \\[ispell-word] and \\[ispell-region] commands.") |
---|
362 | |
---|
363 | (defvar ispell-alternate-dictionary |
---|
364 | (cond ((file-exists-p "/usr/dict/web2") "/usr/dict/web2") |
---|
365 | ((file-exists-p "/usr/share/dict/web2") "/usr/share/dict/web2") |
---|
366 | ((file-exists-p "/usr/dict/words") "/usr/dict/words") |
---|
367 | ((file-exists-p "/usr/lib/dict/words") "/usr/lib/dict/words") |
---|
368 | ((file-exists-p "/usr/share/dict/words") "/usr/share/dict/words") |
---|
369 | ((file-exists-p "/sys/dict") "/sys/dict") |
---|
370 | (t "/usr/dict/words")) |
---|
371 | "*Alternate dictionary for spelling help.") |
---|
372 | |
---|
373 | (defvar ispell-complete-word-dict ispell-alternate-dictionary |
---|
374 | "*Dictionary used for word completion.") |
---|
375 | |
---|
376 | (defvar ispell-grep-command "egrep" |
---|
377 | "Name of the grep command for search processes.") |
---|
378 | |
---|
379 | (defvar ispell-grep-options "-i" |
---|
380 | "String of options to use when running the program in `ispell-grep-command'. |
---|
381 | Should probably be \"-i\" or \"-e\". |
---|
382 | Some machines (like the NeXT) don't support \"-i\"") |
---|
383 | |
---|
384 | (defvar ispell-look-command "look" |
---|
385 | "Name of the look command for search processes. |
---|
386 | This must be an absolute file name.") |
---|
387 | |
---|
388 | (defvar ispell-look-p (file-exists-p ispell-look-command) |
---|
389 | "*Non-nil means use `look' rather than `grep'. |
---|
390 | Default is based on whether `look' seems to be available.") |
---|
391 | |
---|
392 | (defvar ispell-have-new-look nil |
---|
393 | "*Non-nil means use the `-r' option (regexp) when running `look'.") |
---|
394 | |
---|
395 | (defvar ispell-look-options (if ispell-have-new-look "-dfr" "-df") |
---|
396 | "String of command options for `ispell-look-command'.") |
---|
397 | |
---|
398 | (defvar ispell-use-ptys-p nil |
---|
399 | "When non-nil, Emacs uses ptys to communicate with Ispell. |
---|
400 | When nil, Emacs uses pipes.") |
---|
401 | |
---|
402 | (defvar ispell-following-word nil |
---|
403 | "*Non-nil means `ispell-word' checks the word around or after point. |
---|
404 | Otherwise `ispell-word' checks the preceding word.") |
---|
405 | |
---|
406 | (defvar ispell-help-in-bufferp nil |
---|
407 | "*Non-nil means display interactive keymap help in a buffer. |
---|
408 | Otherwise use the minibuffer.") |
---|
409 | |
---|
410 | (defvar ispell-quietly nil |
---|
411 | "*Non-nil means suppress messages in `ispell-word'.") |
---|
412 | |
---|
413 | (defvar ispell-format-word (function upcase) |
---|
414 | "*Formatting function for displaying word being spell checked. |
---|
415 | The function must take one string argument and return a string.") |
---|
416 | |
---|
417 | (defvar ispell-personal-dictionary nil |
---|
418 | "*File name of your personal spelling dictionary, or nil. |
---|
419 | If nil, the default personal dictionary, \"~/.ispell_DICTNAME\" is used, |
---|
420 | where DICTNAME is the name of your default dictionary.") |
---|
421 | |
---|
422 | (defvar ispell-silently-savep nil |
---|
423 | "*When non-nil, save the personal dictionary without confirmation.") |
---|
424 | |
---|
425 | ;;; This variable contains the current dictionary being used if the ispell |
---|
426 | ;;; process is running. Otherwise it contains the global default. |
---|
427 | (defvar ispell-dictionary nil |
---|
428 | "If non-nil, a dictionary to use instead of the default one. |
---|
429 | This is passed to the ispell process using the `-d' switch and is |
---|
430 | used as key in `ispell-dictionary-alist' (which see). |
---|
431 | |
---|
432 | You should set this variable before your first use of Emacs spell-checking |
---|
433 | commands in the Emacs session, or else use the \\[ispell-change-dictionary] |
---|
434 | command to change it. Otherwise, this variable only takes effect in a newly |
---|
435 | started Ispell process.") |
---|
436 | |
---|
437 | (defvar ispell-extra-args nil |
---|
438 | "*If non-nil, a list of extra switches to pass to the Ispell program. |
---|
439 | For example, '(\"-W\" \"3\") to cause it to accept all 1-3 character |
---|
440 | words as correct. See also `ispell-dictionary-alist', which may be used |
---|
441 | for language-specific arguments.") |
---|
442 | |
---|
443 | ;;; ispell-dictionary-alist is set up from two subvariables above |
---|
444 | ;;; to avoid having very long lines in loaddefs.el. |
---|
445 | (defvar ispell-dictionary-alist |
---|
446 | |
---|
447 | '((nil ; default (english.aff) |
---|
448 | "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil) |
---|
449 | ("english" ; make english explicitly selectable |
---|
450 | "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil) |
---|
451 | ("british" ; british version |
---|
452 | "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B" "-d" "british") nil) |
---|
453 | ("deutsch" ; deutsch.aff |
---|
454 | "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex") |
---|
455 | ("deutsch8" |
---|
456 | "[a-zA-Z\304\326\334\344\366\337\374]" |
---|
457 | "[^a-zA-Z\304\326\334\344\366\337\374]" |
---|
458 | "[']" t ("-C" "-d" "deutsch") "~latin1") |
---|
459 | ("nederlands" ; nederlands.aff |
---|
460 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
---|
461 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
---|
462 | "[']" t ("-C") nil) |
---|
463 | ("nederlands8" ; dutch8.aff |
---|
464 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
---|
465 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
---|
466 | "[']" t ("-C") nil) |
---|
467 | ("svenska" ;7 bit swedish mode |
---|
468 | "[A-Za-z}{|\\133\\135\\\\]" "[^A-Za-z}{|\\133\\135\\\\]" |
---|
469 | "[']" nil ("-C") nil) |
---|
470 | ("svenska8" ;8 bit swedish mode |
---|
471 | "[A-Za-z\345\344\366\305\304\366]" "[^A-Za-z\345\344\366\305\304\366]" |
---|
472 | "[']" nil ("-C" "-d" "svenska") "~list") ; Add `"-T" "list"' instead? |
---|
473 | ("francais7" |
---|
474 | "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil) |
---|
475 | ("francais" ; francais.aff |
---|
476 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" |
---|
477 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" |
---|
478 | "[---']" t nil "~list") |
---|
479 | ("francais-tex" ; francais.aff |
---|
480 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" |
---|
481 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" |
---|
482 | "[---'^`\"]" t nil "~tex") |
---|
483 | ("dansk" ; dansk.aff |
---|
484 | "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]" |
---|
485 | "" nil ("-C") nil) |
---|
486 | ) |
---|
487 | |
---|
488 | "An alist of dictionaries and their associated parameters. |
---|
489 | |
---|
490 | Each element of this list is also a list: |
---|
491 | |
---|
492 | \(DICTIONARY-NAME CASECHARS NOT-CASECHARS OTHERCHARS MANY-OTHERCHARS-P |
---|
493 | ISPELL-ARGS EXTENDED-CHARACTER-MODE\) |
---|
494 | |
---|
495 | DICTIONARY-NAME is a possible value of variable `ispell-dictionary', nil |
---|
496 | means the default dictionary. |
---|
497 | |
---|
498 | CASECHARS is a regular expression of valid characters that comprise a |
---|
499 | word. |
---|
500 | |
---|
501 | NOT-CASECHARS is the opposite regexp of CASECHARS. |
---|
502 | |
---|
503 | OTHERCHARS is a regular expression of other characters that are valid |
---|
504 | in word constructs. Otherchars cannot be adjacent to each other in a |
---|
505 | word, nor can they begin or end a word. This implies we can't check |
---|
506 | \"Stevens'\" as a correct possessive and other correct formations. |
---|
507 | |
---|
508 | Hint: regexp syntax requires the hyphen to be declared first here. |
---|
509 | |
---|
510 | MANY-OTHERCHARS-P is non-nil if many otherchars are to be allowed in a |
---|
511 | word instead of only one. |
---|
512 | |
---|
513 | ISPELL-ARGS is a list of additional arguments passed to the ispell |
---|
514 | subprocess. |
---|
515 | |
---|
516 | EXTENDED-CHARACTER-MODE should be used when dictionaries are used which |
---|
517 | have been configured in an Ispell affix file. (For example, umlauts |
---|
518 | can be encoded as \\\"a, a\\\", \"a, ...) Defaults are ~tex and ~nroff |
---|
519 | in English. This has the same effect as the command-line `-T' option. |
---|
520 | The buffer Major Mode controls Ispell's parsing in tex or nroff mode, |
---|
521 | but the dictionary can control the extended character mode. |
---|
522 | Both defaults can be overruled in a buffer-local fashion. See |
---|
523 | `ispell-parsing-keyword' for details on this. |
---|
524 | |
---|
525 | Note that the CASECHARS and OTHERCHARS slots of the alist should |
---|
526 | contain the same character set as casechars and otherchars in the |
---|
527 | language.aff file \(e.g., english.aff\).") |
---|
528 | |
---|
529 | |
---|
530 | (defvar ispell-menu-map nil "Key map for ispell menu") |
---|
531 | |
---|
532 | (defvar ispell-menu-lucid nil "Spelling menu for Lucid Emacs.") |
---|
533 | |
---|
534 | ;;; Break out lucid menu and split into several calls to avoid having |
---|
535 | ;;; long lines in loaddefs.el. Detect need off following constant. |
---|
536 | |
---|
537 | (defconst ispell-menu-map-needed ; make sure this is not Lucid Emacs |
---|
538 | (and (not ispell-menu-map) |
---|
539 | (string-lessp "19" emacs-version) |
---|
540 | ;; make sure this isn't Lucid Emacs |
---|
541 | (not (string-match "Lucid" emacs-version)))) |
---|
542 | |
---|
543 | |
---|
544 | ;;; setup dictionary |
---|
545 | (if ispell-menu-map-needed |
---|
546 | (let ((dicts (reverse (cons (cons "default" nil) ispell-dictionary-alist))) |
---|
547 | name) |
---|
548 | (setq ispell-menu-map (make-sparse-keymap "Spell")) |
---|
549 | ;; add the dictionaries to the bottom of the list. |
---|
550 | (while dicts |
---|
551 | (setq name (car (car dicts)) |
---|
552 | dicts (cdr dicts)) |
---|
553 | (if (stringp name) |
---|
554 | (define-key ispell-menu-map (vector (intern name)) |
---|
555 | (cons (concat "Select " (capitalize name)) |
---|
556 | (list 'lambda () '(interactive) |
---|
557 | (list 'ispell-change-dictionary name)))))))) |
---|
558 | |
---|
559 | ;;; define commands in menu in opposite order you want them to appear. |
---|
560 | (if ispell-menu-map-needed |
---|
561 | (progn |
---|
562 | (define-key ispell-menu-map [ispell-change-dictionary] |
---|
563 | '("Change Dictionary" . ispell-change-dictionary)) |
---|
564 | (define-key ispell-menu-map [ispell-kill-ispell] |
---|
565 | '("Kill Process" . ispell-kill-ispell)) |
---|
566 | (define-key ispell-menu-map [ispell-pdict-save] |
---|
567 | '("Save Dictionary" . (lambda () (interactive) (ispell-pdict-save t t)))) |
---|
568 | (define-key ispell-menu-map [ispell-complete-word] |
---|
569 | '("Complete Word" . ispell-complete-word)) |
---|
570 | (define-key ispell-menu-map [ispell-complete-word-interior-frag] |
---|
571 | '("Complete Word Frag" . ispell-complete-word-interior-frag)))) |
---|
572 | |
---|
573 | (if ispell-menu-map-needed |
---|
574 | (progn |
---|
575 | (define-key ispell-menu-map [ispell-continue] |
---|
576 | '("Continue Check" . ispell-continue)) |
---|
577 | (define-key ispell-menu-map [ispell-word] |
---|
578 | '("Check Word" . ispell-word)) |
---|
579 | (define-key ispell-menu-map [ispell-region] |
---|
580 | '("Check Region" . ispell-region)) |
---|
581 | (define-key ispell-menu-map [ispell-buffer] |
---|
582 | '("Check Buffer" . ispell-buffer)))) |
---|
583 | |
---|
584 | (if ispell-menu-map-needed |
---|
585 | (progn |
---|
586 | (define-key ispell-menu-map [ispell-message] |
---|
587 | '("Check Message" . ispell-message)) |
---|
588 | (define-key ispell-menu-map [ispell-help] |
---|
589 | ;; use (x-popup-menu last-nonmenu-event(list "" ispell-help-list)) ? |
---|
590 | '("Help" . (lambda () (interactive) (describe-function 'ispell-help)))) |
---|
591 | (put 'ispell-region 'menu-enable 'mark-active) |
---|
592 | (fset 'ispell-menu-map (symbol-value 'ispell-menu-map)))) |
---|
593 | |
---|
594 | ;;; Xemacs version 19 |
---|
595 | (if (and (string-lessp "19" emacs-version) |
---|
596 | (string-match "Lucid" emacs-version)) |
---|
597 | (let ((dicts (cons (cons "default" nil) ispell-dictionary-alist)) |
---|
598 | (current-menubar (or current-menubar default-menubar)) |
---|
599 | (menu |
---|
600 | '(["Help" (describe-function 'ispell-help) t] |
---|
601 | ;;["Help" (popup-menu ispell-help-list) t] |
---|
602 | ["Check Message" ispell-message t] |
---|
603 | ["Check Buffer" ispell-buffer t] |
---|
604 | ["Check Word" ispell-word t] |
---|
605 | ["Check Region" ispell-region (or (not zmacs-regions) (mark))] |
---|
606 | ["Continue Check" ispell-continue t] |
---|
607 | ["Complete Word Frag"ispell-complete-word-interior-frag t] |
---|
608 | ["Complete Word" ispell-complete-word t] |
---|
609 | ["Kill Process" ispell-kill-ispell t] |
---|
610 | "-" |
---|
611 | ["Save Dictionary" (ispell-pdict-save t t) t] |
---|
612 | ["Change Dictionary" ispell-change-dictionary t])) |
---|
613 | name) |
---|
614 | (while dicts |
---|
615 | (setq name (car (car dicts)) |
---|
616 | dicts (cdr dicts)) |
---|
617 | (if (stringp name) |
---|
618 | (setq menu (append menu |
---|
619 | (list |
---|
620 | (vector (concat "Select " (capitalize name)) |
---|
621 | (list 'ispell-change-dictionary name) |
---|
622 | t)))))) |
---|
623 | (setq ispell-menu-lucid menu) |
---|
624 | (if current-menubar |
---|
625 | (progn |
---|
626 | (delete-menu-item '("Edit" "Spell")) ; in case already defined |
---|
627 | (add-menu '("Edit") "Spell" ispell-menu-lucid))))) |
---|
628 | |
---|
629 | |
---|
630 | ;;; ********************************************************************** |
---|
631 | ;;; The following are used by ispell, and should not be changed. |
---|
632 | ;;; ********************************************************************** |
---|
633 | |
---|
634 | |
---|
635 | ;;; The version must be 3.1 or greater for this version of ispell.el |
---|
636 | ;;; There is an incompatibility between version 3.1.12 and lower versions. |
---|
637 | (defconst ispell-required-version '("3.1." 12) |
---|
638 | "Ispell versions with which this version of ispell.el is known to work.") |
---|
639 | (defvar ispell-offset 1 |
---|
640 | "Offset that maps protocol differences between ispell 3.1 versions.") |
---|
641 | |
---|
642 | (defun ispell-get-casechars () |
---|
643 | (nth 1 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
644 | (defun ispell-get-not-casechars () |
---|
645 | (nth 2 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
646 | (defun ispell-get-otherchars () |
---|
647 | (nth 3 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
648 | (defun ispell-get-many-otherchars-p () |
---|
649 | (nth 4 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
650 | (defun ispell-get-ispell-args () |
---|
651 | (nth 5 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
652 | (defun ispell-get-extended-character-mode () |
---|
653 | (nth 6 (assoc ispell-dictionary ispell-dictionary-alist))) |
---|
654 | |
---|
655 | (defvar ispell-process nil |
---|
656 | "The process object for Ispell.") |
---|
657 | |
---|
658 | (defvar ispell-pdict-modified-p nil |
---|
659 | "Non-nil means personal dictionary has modifications to be saved.") |
---|
660 | |
---|
661 | ;;; If you want to save the dictionary when quitting, must do so explicitly. |
---|
662 | ;;; When non-nil, the spell session is terminated. |
---|
663 | ;;; When numeric, contains cursor location in buffer, and cursor remains there. |
---|
664 | (defvar ispell-quit nil) |
---|
665 | |
---|
666 | (defvar ispell-filter nil |
---|
667 | "Output filter from piped calls to Ispell.") |
---|
668 | |
---|
669 | (defvar ispell-filter-continue nil |
---|
670 | "Control variable for Ispell filter function.") |
---|
671 | |
---|
672 | (defvar ispell-process-directory nil |
---|
673 | "The directory where `ispell-process' was started.") |
---|
674 | |
---|
675 | (defvar ispell-query-replace-marker (make-marker) |
---|
676 | "Marker for `query-replace' processing.") |
---|
677 | |
---|
678 | (defvar ispell-checking-message nil |
---|
679 | "Non-nil when we're checking a mail message") |
---|
680 | |
---|
681 | (defconst ispell-choices-buffer "*Choices*") |
---|
682 | |
---|
683 | (defvar ispell-overlay nil "Overlay variable for Ispell highlighting.") |
---|
684 | |
---|
685 | ;;; *** Buffer Local Definitions *** |
---|
686 | |
---|
687 | ;;; This is the local dictionary to use. When nil the default dictionary will |
---|
688 | ;;; be used. Do not redefine default value or it will override the global! |
---|
689 | (defvar ispell-local-dictionary nil |
---|
690 | "If non-nil, a dictionary to use for Ispell commands in this buffer. |
---|
691 | The value must be a string dictionary name in `ispell-dictionary-alist'. |
---|
692 | This variable becomes buffer-local when set in any fashion. |
---|
693 | |
---|
694 | Setting ispell-local-dictionary to a value has the same effect as |
---|
695 | calling \\[ispell-change-dictionary] with that value. This variable |
---|
696 | is automatically set when defined in the file with either |
---|
697 | `ispell-dictionary-keyword' or the Local Variable syntax.") |
---|
698 | |
---|
699 | (make-variable-buffer-local 'ispell-local-dictionary) |
---|
700 | |
---|
701 | ;; Use default directory, unless locally set. |
---|
702 | (set-default 'ispell-local-dictionary nil) |
---|
703 | |
---|
704 | (defconst ispell-words-keyword "LocalWords: " |
---|
705 | "The keyword for local oddly-spelled words to accept. |
---|
706 | The keyword will be followed by any number of local word spellings. |
---|
707 | There can be multiple of these keywords in the file.") |
---|
708 | |
---|
709 | (defconst ispell-dictionary-keyword "Local IspellDict: " |
---|
710 | "The keyword for local dictionary definitions. |
---|
711 | There should be only one dictionary keyword definition per file, and it |
---|
712 | should be followed by a correct dictionary name in `ispell-dictionary-alist'.") |
---|
713 | |
---|
714 | (defconst ispell-parsing-keyword "Local IspellParsing: " |
---|
715 | "The keyword for overriding default Ispell parsing. |
---|
716 | Determined by the buffer's major mode and extended-character mode as well as |
---|
717 | the default dictionary. |
---|
718 | |
---|
719 | The above keyword string should be followed by `latex-mode' or |
---|
720 | `nroff-mode' to put the current buffer into the desired parsing mode. |
---|
721 | |
---|
722 | Extended character mode can be changed for this buffer by placing |
---|
723 | a `~' followed by an extended-character mode -- such as `~.tex'.") |
---|
724 | |
---|
725 | (defvar ispell-skip-sgml nil |
---|
726 | "Skips spell checking of SGML tags and entity references when non-nil. |
---|
727 | This variable is set when major-mode is sgml-mode or html-mode.") |
---|
728 | |
---|
729 | (defvar ispell-local-pdict ispell-personal-dictionary |
---|
730 | "A buffer local variable containing the current personal dictionary. |
---|
731 | If non-nil, the value must be a string, which is a file name. |
---|
732 | |
---|
733 | If you specify a personal dictionary for the current buffer which is |
---|
734 | different from the current personal dictionary, the effect is similar |
---|
735 | to calling \\[ispell-change-dictionary]. This variable is automatically |
---|
736 | set when defined in the file with either `ispell-pdict-keyword' or the |
---|
737 | local variable syntax.") |
---|
738 | |
---|
739 | (make-variable-buffer-local 'ispell-local-pdict) |
---|
740 | |
---|
741 | (defconst ispell-pdict-keyword "Local IspellPersDict: " |
---|
742 | "The keyword for defining buffer local dictionaries.") |
---|
743 | |
---|
744 | (defvar ispell-buffer-local-name nil |
---|
745 | "Contains the buffer name if local word definitions were used. |
---|
746 | Ispell is then restarted because the local words could conflict.") |
---|
747 | |
---|
748 | (defvar ispell-parser 'use-mode-name |
---|
749 | "*Indicates whether ispell should parse the current buffer as TeX Code. |
---|
750 | Special value `use-mode-name' tries to guess using the name of major-mode. |
---|
751 | Default parser is 'nroff. |
---|
752 | Currently the only other valid parser is 'tex. |
---|
753 | |
---|
754 | You can set this variable in hooks in your init file -- eg: |
---|
755 | |
---|
756 | (add-hook 'tex-mode-hook (function (lambda () (setq ispell-parser 'tex))))") |
---|
757 | |
---|
758 | (defvar ispell-region-end (make-marker) |
---|
759 | "Marker that allows spelling continuations.") |
---|
760 | |
---|
761 | (defvar ispell-check-only nil |
---|
762 | "If non-nil, `ispell-word' does not try to correct the word.") |
---|
763 | |
---|
764 | |
---|
765 | ;;; ********************************************************************** |
---|
766 | ;;; ********************************************************************** |
---|
767 | |
---|
768 | |
---|
769 | (and (string-lessp "19" emacs-version) |
---|
770 | (not (boundp 'epoch::version)) |
---|
771 | (defalias 'ispell 'ispell-buffer)) |
---|
772 | |
---|
773 | ;;;###autoload |
---|
774 | (define-key global-map "\M-$" 'ispell-word) |
---|
775 | |
---|
776 | ;;;###autoload |
---|
777 | (defun ispell-word (&optional following quietly continue) |
---|
778 | "Check spelling of word under or before the cursor. |
---|
779 | If the word is not found in dictionary, display possible corrections |
---|
780 | in a window allowing you to choose one. |
---|
781 | |
---|
782 | With a prefix argument (or if CONTINUE is non-nil), |
---|
783 | resume interrupted spell-checking of a buffer or region. |
---|
784 | |
---|
785 | If optional argument FOLLOWING is non-nil or if `ispell-following-word' |
---|
786 | is non-nil when called interactively, then the following word |
---|
787 | \(rather than preceding\) is checked when the cursor is not over a word. |
---|
788 | When the optional argument QUIETLY is non-nil or `ispell-quietly' is non-nil |
---|
789 | when called interactively, non-corrective messages are suppressed. |
---|
790 | |
---|
791 | Word syntax described by `ispell-dictionary-alist' (which see). |
---|
792 | |
---|
793 | This will check or reload the dictionary. Use \\[ispell-change-dictionary] |
---|
794 | or \\[ispell-region] to update the Ispell process." |
---|
795 | (interactive (list nil nil current-prefix-arg)) |
---|
796 | (if continue |
---|
797 | (ispell-continue) |
---|
798 | (if (interactive-p) |
---|
799 | (setq following ispell-following-word |
---|
800 | quietly ispell-quietly)) |
---|
801 | (ispell-accept-buffer-local-defs) ; use the correct dictionary |
---|
802 | (let ((cursor-location (point)) ; retain cursor location |
---|
803 | (word (ispell-get-word following)) |
---|
804 | start end poss replace) |
---|
805 | ;; destructure return word info list. |
---|
806 | (setq start (car (cdr word)) |
---|
807 | end (car (cdr (cdr word))) |
---|
808 | word (car word)) |
---|
809 | |
---|
810 | ;; now check spelling of word. |
---|
811 | (or quietly |
---|
812 | (message "Checking spelling of %s..." |
---|
813 | (funcall ispell-format-word word))) |
---|
814 | (process-send-string ispell-process "%\n") ;put in verbose mode |
---|
815 | (process-send-string ispell-process (concat "^" word "\n")) |
---|
816 | ;; wait until ispell has processed word |
---|
817 | (while (progn |
---|
818 | (accept-process-output ispell-process) |
---|
819 | (not (string= "" (car ispell-filter))))) |
---|
820 | ;;(process-send-string ispell-process "!\n") ;back to terse mode. |
---|
821 | (setq ispell-filter (cdr ispell-filter)) |
---|
822 | (if (listp ispell-filter) |
---|
823 | (setq poss (ispell-parse-output (car ispell-filter)))) |
---|
824 | (cond ((eq poss t) |
---|
825 | (or quietly |
---|
826 | (message "%s is correct" (funcall ispell-format-word word)))) |
---|
827 | ((stringp poss) |
---|
828 | (or quietly |
---|
829 | (message "%s is correct because of root %s" |
---|
830 | (funcall ispell-format-word word) |
---|
831 | (funcall ispell-format-word poss)))) |
---|
832 | ((null poss) (message "Error in ispell process")) |
---|
833 | (ispell-check-only ; called from ispell minor mode. |
---|
834 | (beep)) |
---|
835 | (t ; prompt for correct word. |
---|
836 | (save-window-excursion |
---|
837 | (setq replace (ispell-command-loop |
---|
838 | (car (cdr (cdr poss))) |
---|
839 | (car (cdr (cdr (cdr poss)))) |
---|
840 | (car poss) start end))) |
---|
841 | (cond ((equal 0 replace) |
---|
842 | (ispell-add-per-file-word-list (car poss))) |
---|
843 | (replace |
---|
844 | (setq word (if (atom replace) replace (car replace)) |
---|
845 | cursor-location (+ (- (length word) (- end start)) |
---|
846 | cursor-location)) |
---|
847 | (if (not (equal word (car poss))) |
---|
848 | (progn |
---|
849 | (delete-region start end) |
---|
850 | (insert word))) |
---|
851 | (if (not (atom replace)) ; recheck spelling of replacement |
---|
852 | (progn |
---|
853 | (goto-char cursor-location) |
---|
854 | (ispell-word following quietly))))) |
---|
855 | (if (get-buffer ispell-choices-buffer) |
---|
856 | (kill-buffer ispell-choices-buffer)))) |
---|
857 | (goto-char cursor-location) ; return to original location |
---|
858 | (ispell-pdict-save ispell-silently-savep) |
---|
859 | (if ispell-quit (setq ispell-quit nil))))) |
---|
860 | |
---|
861 | |
---|
862 | (defun ispell-get-word (following &optional extra-otherchars) |
---|
863 | "Return the word for spell-checking according to ispell syntax. |
---|
864 | If optional argument FOLLOWING is non-nil or if `ispell-following-word' |
---|
865 | is non-nil when called interactively, then the following word |
---|
866 | \(rather than preceding\) is checked when the cursor is not over a word. |
---|
867 | Optional second argument contains otherchars that can be included in word |
---|
868 | many times. |
---|
869 | |
---|
870 | Word syntax described by `ispell-dictionary-alist' (which see)." |
---|
871 | (let* ((ispell-casechars (ispell-get-casechars)) |
---|
872 | (ispell-not-casechars (ispell-get-not-casechars)) |
---|
873 | (ispell-otherchars (ispell-get-otherchars)) |
---|
874 | (ispell-many-otherchars-p (ispell-get-many-otherchars-p)) |
---|
875 | (word-regexp (concat ispell-casechars |
---|
876 | "+\\(" |
---|
877 | ispell-otherchars |
---|
878 | "?" |
---|
879 | (if extra-otherchars |
---|
880 | (concat extra-otherchars "?")) |
---|
881 | ispell-casechars |
---|
882 | "+\\)" |
---|
883 | (if (or ispell-many-otherchars-p |
---|
884 | extra-otherchars) |
---|
885 | "*" "?"))) |
---|
886 | did-it-once |
---|
887 | start end word) |
---|
888 | ;; find the word |
---|
889 | (if (not (looking-at ispell-casechars)) |
---|
890 | (if following |
---|
891 | (re-search-forward ispell-casechars (point-max) t) |
---|
892 | (re-search-backward ispell-casechars (point-min) t))) |
---|
893 | ;; move to front of word |
---|
894 | (re-search-backward ispell-not-casechars (point-min) 'start) |
---|
895 | (while (and (or (looking-at ispell-otherchars) |
---|
896 | (and extra-otherchars (looking-at extra-otherchars))) |
---|
897 | (not (bobp)) |
---|
898 | (or (not did-it-once) |
---|
899 | ispell-many-otherchars-p)) |
---|
900 | (if (and extra-otherchars (looking-at extra-otherchars)) |
---|
901 | (progn |
---|
902 | (backward-char 1) |
---|
903 | (if (looking-at ispell-casechars) |
---|
904 | (re-search-backward ispell-not-casechars (point-min) 'move))) |
---|
905 | (setq did-it-once t) |
---|
906 | (backward-char 1) |
---|
907 | (if (looking-at ispell-casechars) |
---|
908 | (re-search-backward ispell-not-casechars (point-min) 'move) |
---|
909 | (backward-char -1)))) |
---|
910 | ;; Now mark the word and save to string. |
---|
911 | (or (re-search-forward word-regexp (point-max) t) |
---|
912 | (error "No word found to check!")) |
---|
913 | (setq start (match-beginning 0) |
---|
914 | end (point) |
---|
915 | word (buffer-substring start end)) |
---|
916 | (list word start end))) |
---|
917 | |
---|
918 | |
---|
919 | ;;; Global ispell-pdict-modified-p is set by ispell-command-loop and |
---|
920 | ;;; tracks changes in the dictionary. The global may either be |
---|
921 | ;;; a value or a list, whose value is the state of whether the |
---|
922 | ;;; dictionary needs to be saved. |
---|
923 | |
---|
924 | (defun ispell-pdict-save (&optional no-query force-save) |
---|
925 | "Check to see if the personal dictionary has been modified. |
---|
926 | If so, ask if it needs to be saved." |
---|
927 | (interactive (list ispell-silently-savep t)) |
---|
928 | (if (and ispell-pdict-modified-p (listp ispell-pdict-modified-p)) |
---|
929 | (setq ispell-pdict-modified-p (car ispell-pdict-modified-p))) |
---|
930 | (if (or ispell-pdict-modified-p force-save) |
---|
931 | (if (or no-query (y-or-n-p "Personal dictionary modified. Save? ")) |
---|
932 | (progn |
---|
933 | (process-send-string ispell-process "#\n") |
---|
934 | (message "Personal dictionary saved.")))) |
---|
935 | ;; unassert variable, even if not saved to avoid questioning. |
---|
936 | (setq ispell-pdict-modified-p nil)) |
---|
937 | |
---|
938 | |
---|
939 | (defun ispell-command-loop (miss guess word start end) |
---|
940 | "Display possible corrections from list MISS. |
---|
941 | GUESS lists possibly valid affix construction of WORD. |
---|
942 | Returns nil to keep word. |
---|
943 | Returns 0 to insert locally into buffer-local dictionary. |
---|
944 | Returns string for new chosen word. |
---|
945 | Returns list for new replacement word (will be rechecked). |
---|
946 | Highlights the word, which is assumed to run from START to END. |
---|
947 | Global `ispell-pdict-modified-p' becomes a list where the only value |
---|
948 | indicates whether the dictionary has been modified when option `a' or `i' is |
---|
949 | used." |
---|
950 | (let ((textbuf (current-buffer)) |
---|
951 | (count ?0) |
---|
952 | (line 2) |
---|
953 | (max-lines (- (window-height) 4)) ; assure 4 context lines. |
---|
954 | (choices miss) |
---|
955 | (window-min-height (min window-min-height |
---|
956 | ispell-choices-win-default-height)) |
---|
957 | (command-characters '( ? ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m )) |
---|
958 | (skipped 0) |
---|
959 | char num result textwin highlighted) |
---|
960 | |
---|
961 | ;; setup the *Choices* buffer with valid data. |
---|
962 | (save-excursion |
---|
963 | (set-buffer (get-buffer-create ispell-choices-buffer)) |
---|
964 | (setq mode-line-format (concat "-- %b -- word: " word)) |
---|
965 | (erase-buffer) |
---|
966 | (if guess |
---|
967 | (progn |
---|
968 | (insert "Affix rules generate and capitalize " |
---|
969 | "this word as shown below:\n\t") |
---|
970 | (while guess |
---|
971 | (if (> (+ 4 (current-column) (length (car guess))) |
---|
972 | (window-width)) |
---|
973 | (progn |
---|
974 | (insert "\n\t") |
---|
975 | (setq line (1+ line)))) |
---|
976 | (insert (car guess) " ") |
---|
977 | (setq guess (cdr guess))) |
---|
978 | (insert "\nUse option `i' if this is a correct composition" |
---|
979 | " from the derivative root.\n") |
---|
980 | (setq line (+ line (if choices 3 2))))) |
---|
981 | (while (and choices |
---|
982 | (< (if (> (+ 7 (current-column) (length (car choices)) |
---|
983 | (if (> count ?~) 3 0)) |
---|
984 | (window-width)) |
---|
985 | (progn |
---|
986 | (insert "\n") |
---|
987 | (setq line (1+ line))) |
---|
988 | line) |
---|
989 | max-lines)) |
---|
990 | ;; not so good if there are over 20 or 30 options, but then, if |
---|
991 | ;; there are that many you don't want to scan them all anyway... |
---|
992 | (while (memq count command-characters) ; skip command characters. |
---|
993 | (setq count (1+ count) |
---|
994 | skipped (1+ skipped))) |
---|
995 | (insert "(" count ") " (car choices) " ") |
---|
996 | (setq choices (cdr choices) |
---|
997 | count (1+ count))) |
---|
998 | (setq count (- count ?0 skipped))) |
---|
999 | |
---|
1000 | ;; Assure word is visible |
---|
1001 | (if (not (pos-visible-in-window-p end)) |
---|
1002 | (sit-for 0)) |
---|
1003 | ;; Display choices for misspelled word. |
---|
1004 | (let ((choices-window (get-buffer-window ispell-choices-buffer))) |
---|
1005 | (if choices-window |
---|
1006 | (if (= line (window-height choices-window)) |
---|
1007 | (select-window choices-window) |
---|
1008 | ;; *Choices* window changed size. Adjust the choices window |
---|
1009 | ;; without scrolling the spelled window when possible |
---|
1010 | (let ((window-line (- line (window-height choices-window))) |
---|
1011 | (visible (progn (forward-line -1) (point)))) |
---|
1012 | (if (< line ispell-choices-win-default-height) |
---|
1013 | (setq window-line (+ window-line |
---|
1014 | (- ispell-choices-win-default-height |
---|
1015 | line)))) |
---|
1016 | (move-to-window-line 0) |
---|
1017 | (forward-line window-line) |
---|
1018 | (set-window-start (selected-window) |
---|
1019 | (if (> (point) visible) visible (point))) |
---|
1020 | (goto-char end) |
---|
1021 | (select-window (previous-window)) ; *Choices* window |
---|
1022 | (enlarge-window window-line))) |
---|
1023 | ;; Overlay *Choices* window when it isn't showing |
---|
1024 | (ispell-overlay-window (max line ispell-choices-win-default-height))) |
---|
1025 | (switch-to-buffer ispell-choices-buffer) |
---|
1026 | (goto-char (point-min))) |
---|
1027 | |
---|
1028 | (select-window (setq textwin (next-window))) |
---|
1029 | |
---|
1030 | ;; highlight word, protecting current buffer status |
---|
1031 | (unwind-protect |
---|
1032 | (progn |
---|
1033 | (if ispell-highlight-p |
---|
1034 | (ispell-highlight-spelling-error start end t)) |
---|
1035 | ;; Loop until a valid choice is made. |
---|
1036 | (while |
---|
1037 | (eq |
---|
1038 | t |
---|
1039 | (setq |
---|
1040 | result |
---|
1041 | (progn |
---|
1042 | (undo-boundary) |
---|
1043 | (message (concat "C-h or ? for more options; SPC to leave " |
---|
1044 | "unchanged, Character to replace word")) |
---|
1045 | (let ((inhibit-quit t)) |
---|
1046 | (setq char (if (fboundp 'read-char-exclusive) |
---|
1047 | (read-char-exclusive) |
---|
1048 | (read-char)) |
---|
1049 | skipped 0) |
---|
1050 | (if (or quit-flag (= char ?\C-g)) ; C-g is like typing X |
---|
1051 | (setq char ?X |
---|
1052 | quit-flag nil))) |
---|
1053 | ;; Adjust num to array offset skipping command characters. |
---|
1054 | (let ((com-chars command-characters)) |
---|
1055 | (while com-chars |
---|
1056 | (if (and (> (car com-chars) ?0) (< (car com-chars) char)) |
---|
1057 | (setq skipped (1+ skipped))) |
---|
1058 | (setq com-chars (cdr com-chars))) |
---|
1059 | (setq num (- char ?0 skipped))) |
---|
1060 | |
---|
1061 | (cond |
---|
1062 | ((= char ? ) nil) ; accept word this time only |
---|
1063 | ((= char ?i) ; accept and insert word into pers dict |
---|
1064 | (process-send-string ispell-process (concat "*" word "\n")) |
---|
1065 | (setq ispell-pdict-modified-p '(t)) ; dictionary modified! |
---|
1066 | nil) |
---|
1067 | ((or (= char ?a) (= char ?A)) ; accept word without insert |
---|
1068 | (process-send-string ispell-process (concat "@" word "\n")) |
---|
1069 | (if (null ispell-pdict-modified-p) |
---|
1070 | (setq ispell-pdict-modified-p |
---|
1071 | (list ispell-pdict-modified-p))) |
---|
1072 | (if (= char ?A) 0)) ; return 0 for ispell-add buffer-local |
---|
1073 | ((or (= char ?r) (= char ?R)) ; type in replacement |
---|
1074 | (if (or (= char ?R) ispell-query-replace-choices) |
---|
1075 | (list (read-string "Query-replacement for: " word) t) |
---|
1076 | (cons (read-string "Replacement for: " word) nil))) |
---|
1077 | ((or (= char ??) (= char help-char) (= char ?\C-h)) |
---|
1078 | (ispell-help) |
---|
1079 | t) |
---|
1080 | ;; Quit and move point back. |
---|
1081 | ((= char ?x) |
---|
1082 | (ispell-pdict-save ispell-silently-savep) |
---|
1083 | (message "Exited spell-checking") |
---|
1084 | (setq ispell-quit t) |
---|
1085 | nil) |
---|
1086 | ;; Quit and preserve point. |
---|
1087 | ((= char ?X) |
---|
1088 | (ispell-pdict-save ispell-silently-savep) |
---|
1089 | (message |
---|
1090 | (substitute-command-keys |
---|
1091 | (concat "Spell-checking suspended;" |
---|
1092 | " use C-u \\[ispell-word] to resume"))) |
---|
1093 | (setq ispell-quit (max (point-min) |
---|
1094 | (- (point) (length word)))) |
---|
1095 | nil) |
---|
1096 | ((= char ?q) |
---|
1097 | (if (y-or-n-p "Really kill Ispell process? ") |
---|
1098 | (progn |
---|
1099 | (ispell-kill-ispell t) ; terminate process. |
---|
1100 | (setq ispell-quit (or (not ispell-checking-message) |
---|
1101 | (point)) |
---|
1102 | ispell-pdict-modified-p nil)) |
---|
1103 | t)) ; continue if they don't quit. |
---|
1104 | ((= char ?l) |
---|
1105 | (let ((new-word (read-string |
---|
1106 | "Lookup string (`*' is wildcard): " |
---|
1107 | word)) |
---|
1108 | (new-line 2)) |
---|
1109 | (if new-word |
---|
1110 | (progn |
---|
1111 | (save-excursion |
---|
1112 | (set-buffer (get-buffer-create |
---|
1113 | ispell-choices-buffer)) |
---|
1114 | (erase-buffer) |
---|
1115 | (setq count ?0 |
---|
1116 | skipped 0 |
---|
1117 | mode-line-format (concat |
---|
1118 | "-- %b -- word: " |
---|
1119 | new-word) |
---|
1120 | miss (lookup-words new-word) |
---|
1121 | choices miss) |
---|
1122 | (while (and choices ; adjust choices window. |
---|
1123 | (< (if (> (+ 7 (current-column) |
---|
1124 | (length (car choices)) |
---|
1125 | (if (> count ?~) 3 0)) |
---|
1126 | (window-width)) |
---|
1127 | (progn |
---|
1128 | (insert "\n") |
---|
1129 | (setq new-line |
---|
1130 | (1+ new-line))) |
---|
1131 | new-line) |
---|
1132 | max-lines)) |
---|
1133 | (while (memq count command-characters) |
---|
1134 | (setq count (1+ count) |
---|
1135 | skipped (1+ skipped))) |
---|
1136 | (insert "(" count ") " (car choices) " ") |
---|
1137 | (setq choices (cdr choices) |
---|
1138 | count (1+ count))) |
---|
1139 | (setq count (- count ?0 skipped))) |
---|
1140 | (select-window (previous-window)) |
---|
1141 | (if (and (/= new-line line) |
---|
1142 | (> (max line new-line) |
---|
1143 | ispell-choices-win-default-height)) |
---|
1144 | (let* ((minh ispell-choices-win-default-height) |
---|
1145 | (gr-bl (if (< line minh) ; blanks |
---|
1146 | (- minh line) |
---|
1147 | 0)) |
---|
1148 | (shr-bl (if (< new-line minh) ; blanks |
---|
1149 | (- minh new-line) |
---|
1150 | 0))) |
---|
1151 | (if (> new-line line) |
---|
1152 | (enlarge-window (- new-line line gr-bl)) |
---|
1153 | (shrink-window (- line new-line shr-bl))) |
---|
1154 | (setq line new-line))) |
---|
1155 | (select-window (next-window))))) |
---|
1156 | t) ; reselect from new choices |
---|
1157 | ((= char ?u) |
---|
1158 | (process-send-string ispell-process |
---|
1159 | (concat "*" (downcase word) "\n")) |
---|
1160 | (setq ispell-pdict-modified-p '(t)) ; dictionary modified! |
---|
1161 | nil) |
---|
1162 | ((= char ?m) ; type in what to insert |
---|
1163 | (process-send-string |
---|
1164 | ispell-process (concat "*" (read-string "Insert: " word) |
---|
1165 | "\n")) |
---|
1166 | (setq ispell-pdict-modified-p '(t)) |
---|
1167 | (cons word nil)) |
---|
1168 | ((and (>= num 0) (< num count)) |
---|
1169 | (if ispell-query-replace-choices ; Query replace flag |
---|
1170 | (list (nth num miss) 'query-replace) |
---|
1171 | (nth num miss))) |
---|
1172 | ((= char ?\C-l) |
---|
1173 | (redraw-display) t) |
---|
1174 | ((= char ?\C-r) |
---|
1175 | (save-window-excursion (recursive-edit)) t) |
---|
1176 | ((= char ?\C-z) |
---|
1177 | (funcall (key-binding "\C-z")) |
---|
1178 | t) |
---|
1179 | (t (ding) t)))))) |
---|
1180 | result) |
---|
1181 | ;; protected |
---|
1182 | (if ispell-highlight-p ; unhighlight |
---|
1183 | (save-window-excursion |
---|
1184 | (select-window textwin) |
---|
1185 | (ispell-highlight-spelling-error start end)))))) |
---|
1186 | |
---|
1187 | |
---|
1188 | ;;;###autoload |
---|
1189 | (defun ispell-help () |
---|
1190 | "Display a list of the options available when a misspelling is encountered. |
---|
1191 | |
---|
1192 | Selections are: |
---|
1193 | |
---|
1194 | DIGIT: Replace the word with a digit offered in the *Choices* buffer. |
---|
1195 | SPC: Accept word this time. |
---|
1196 | `i': Accept word and insert into private dictionary. |
---|
1197 | `a': Accept word for this session. |
---|
1198 | `A': Accept word and place in `buffer-local dictionary'. |
---|
1199 | `r': Replace word with typed-in value. Rechecked. |
---|
1200 | `R': Replace word with typed-in value. Query-replaced in buffer. Rechecked. |
---|
1201 | `?': Show these commands. |
---|
1202 | `x': Exit spelling buffer. Move cursor to original point. |
---|
1203 | `X': Exit spelling buffer. Leaves cursor at the current point, and permits |
---|
1204 | the aborted check to be completed later. |
---|
1205 | `q': Quit spelling session (Kills ispell process). |
---|
1206 | `l': Look up typed-in replacement in alternate dictionary. Wildcards okay. |
---|
1207 | `u': Like `i', but the word is lower-cased first. |
---|
1208 | `m': Like `i', but allows one to include dictionary completion information. |
---|
1209 | `C-l': redraws screen |
---|
1210 | `C-r': recursive edit |
---|
1211 | `C-z': suspend emacs or iconify frame" |
---|
1212 | |
---|
1213 | (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; " |
---|
1214 | "[i]nsert into private dictionary")) |
---|
1215 | (help-2 (concat "[l]ook a word up in alternate dictionary; " |
---|
1216 | "e[x/X]it; [q]uit session")) |
---|
1217 | (help-3 (concat "[u]ncapitalized insert into dictionary. " |
---|
1218 | "Type 'C-h d ispell-help' for more help"))) |
---|
1219 | (save-window-excursion |
---|
1220 | (if ispell-help-in-bufferp |
---|
1221 | (progn |
---|
1222 | (ispell-overlay-window 4) |
---|
1223 | (switch-to-buffer (get-buffer-create "*Ispell Help*")) |
---|
1224 | (insert (concat help-1 "\n" help-2 "\n" help-3)) |
---|
1225 | (sit-for 5) |
---|
1226 | (kill-buffer "*Ispell Help*")) |
---|
1227 | (select-window (minibuffer-window)) |
---|
1228 | ;;(enlarge-window 2) |
---|
1229 | (erase-buffer) |
---|
1230 | (cond ((string-match "Lucid" emacs-version) |
---|
1231 | (message help-3) |
---|
1232 | (enlarge-window 1) |
---|
1233 | (message help-2) |
---|
1234 | (enlarge-window 1) |
---|
1235 | (message help-1) |
---|
1236 | (goto-char (point-min))) |
---|
1237 | (t |
---|
1238 | (if (string-lessp "19" emacs-version) |
---|
1239 | (message nil)) |
---|
1240 | (enlarge-window 2) |
---|
1241 | (insert (concat help-1 "\n" help-2 "\n" help-3)))) |
---|
1242 | (sit-for 5) |
---|
1243 | (erase-buffer))))) |
---|
1244 | |
---|
1245 | |
---|
1246 | (defun lookup-words (word &optional lookup-dict) |
---|
1247 | "Look up word in word-list dictionary. |
---|
1248 | A `*' serves as a wild card. If no wild cards, `look' is used if it exists. |
---|
1249 | Otherwise the variable `ispell-grep-command' contains the command used to |
---|
1250 | search for the words (usually egrep). |
---|
1251 | |
---|
1252 | Optional second argument contains the dictionary to use; the default is |
---|
1253 | `ispell-alternate-dictionary'." |
---|
1254 | ;; We don't use the filter for this function, rather the result is written |
---|
1255 | ;; into a buffer. Hence there is no need to save the filter values. |
---|
1256 | (if (null lookup-dict) |
---|
1257 | (setq lookup-dict ispell-alternate-dictionary)) |
---|
1258 | |
---|
1259 | (let* ((process-connection-type ispell-use-ptys-p) |
---|
1260 | (wild-p (string-match "\\*" word)) |
---|
1261 | (look-p (and ispell-look-p ; Only use look for an exact match. |
---|
1262 | (or ispell-have-new-look (not wild-p)))) |
---|
1263 | (ispell-grep-buffer (get-buffer-create "*Ispell-Temp*")) ; result buf |
---|
1264 | (prog (if look-p ispell-look-command ispell-grep-command)) |
---|
1265 | (args (if look-p ispell-look-options ispell-grep-options)) |
---|
1266 | status results loc) |
---|
1267 | (unwind-protect |
---|
1268 | (save-window-excursion |
---|
1269 | (message "Starting \"%s\" process..." (file-name-nondirectory prog)) |
---|
1270 | (set-buffer ispell-grep-buffer) |
---|
1271 | (if look-p |
---|
1272 | nil |
---|
1273 | ;; convert * to .* |
---|
1274 | (insert "^" word "$") |
---|
1275 | (while (search-backward "*" nil t) (insert ".")) |
---|
1276 | (setq word (buffer-string)) |
---|
1277 | (erase-buffer)) |
---|
1278 | (setq status (call-process prog nil t nil args word lookup-dict)) |
---|
1279 | ;; grep returns status 1 and no output when word not found, which |
---|
1280 | ;; is a perfectly normal thing. |
---|
1281 | (if (stringp status) |
---|
1282 | (setq results (cons (format "error: %s exited with signal %s" |
---|
1283 | (file-name-nondirectory prog) status) |
---|
1284 | results)) |
---|
1285 | ;; else collect words into `results' in FIFO order |
---|
1286 | (goto-char (point-max)) |
---|
1287 | ;; assure we've ended with \n |
---|
1288 | (or (bobp) (= (preceding-char) ?\n) (insert ?\n)) |
---|
1289 | (while (not (bobp)) |
---|
1290 | (setq loc (point)) |
---|
1291 | (forward-line -1) |
---|
1292 | (setq results (cons (buffer-substring (point) (1- loc)) |
---|
1293 | results))))) |
---|
1294 | ;; protected |
---|
1295 | (kill-buffer ispell-grep-buffer) |
---|
1296 | (if (and results (string-match ".+: " (car results))) |
---|
1297 | (error "%s error: %s" ispell-grep-command (car results)))) |
---|
1298 | results)) |
---|
1299 | |
---|
1300 | |
---|
1301 | ;;; "ispell-filter" is a list of output lines from the generating function. |
---|
1302 | ;;; Each full line (ending with \n) is a separate item on the list. |
---|
1303 | ;;; "output" can contain multiple lines, part of a line, or both. |
---|
1304 | ;;; "start" and "end" are used to keep bounds on lines when "output" contains |
---|
1305 | ;;; multiple lines. |
---|
1306 | ;;; "ispell-filter-continue" is true when we have received only part of a |
---|
1307 | ;;; line as output from a generating function ("output" did not end with \n) |
---|
1308 | ;;; NOTE THAT THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESNT END WITH \n! |
---|
1309 | ;;; This is the case when a process dies or fails. The default behavior |
---|
1310 | ;;; in this case treats the next input received as fresh input. |
---|
1311 | |
---|
1312 | (defun ispell-filter (process output) |
---|
1313 | "Output filter function for ispell, grep, and look." |
---|
1314 | (let ((start 0) |
---|
1315 | (continue t) |
---|
1316 | end) |
---|
1317 | (while continue |
---|
1318 | (setq end (string-match "\n" output start)) ; get text up to the newline. |
---|
1319 | ;; If we get out of sync and ispell-filter-continue is asserted when we |
---|
1320 | ;; are not continuing, treat the next item as a separate list. When |
---|
1321 | ;; ispell-filter-continue is asserted, ispell-filter *should* always be a |
---|
1322 | ;; list! |
---|
1323 | |
---|
1324 | ;; Continue with same line (item)? |
---|
1325 | (if (and ispell-filter-continue ispell-filter (listp ispell-filter)) |
---|
1326 | ;; Yes. Add it to the prev item |
---|
1327 | (setcar ispell-filter |
---|
1328 | (concat (car ispell-filter) (substring output start end))) |
---|
1329 | ;; No. This is a new line and item. |
---|
1330 | (setq ispell-filter |
---|
1331 | (cons (substring output start end) ispell-filter))) |
---|
1332 | (if (null end) |
---|
1333 | ;; We've completed reading the output, but didn't finish the line. |
---|
1334 | (setq ispell-filter-continue t continue nil) |
---|
1335 | ;; skip over newline, this line complete. |
---|
1336 | (setq ispell-filter-continue nil end (1+ end)) |
---|
1337 | (if (= end (length output)) ; No more lines in output |
---|
1338 | (setq continue nil) ; so we can exit the filter. |
---|
1339 | (setq start end)))))) ; else move start to next line of input |
---|
1340 | |
---|
1341 | |
---|
1342 | ;;; This function destroys the mark location if it is in the word being |
---|
1343 | ;;; highlighted. |
---|
1344 | (defun ispell-highlight-spelling-error-generic (start end &optional highlight) |
---|
1345 | "Highlight the word from START to END with a kludge using `inverse-video'. |
---|
1346 | When the optional third arg HIGHLIGHT is set, the word is highlighted; |
---|
1347 | otherwise it is displayed normally." |
---|
1348 | (let ((modified (buffer-modified-p)) ; don't allow this fn to modify buffer |
---|
1349 | (buffer-read-only nil) ; Allow highlighting read-only buffers. |
---|
1350 | (text (buffer-substring start end)) ; Save highlight region |
---|
1351 | (inhibit-quit t) ; inhibit interrupt processing here. |
---|
1352 | (buffer-undo-list t)) ; don't clutter the undo list. |
---|
1353 | (delete-region start end) |
---|
1354 | (insert-char ? (- end start)) ; mimimize amount of redisplay |
---|
1355 | (sit-for 0) ; update display |
---|
1356 | (if highlight (setq inverse-video (not inverse-video))) ; toggle video |
---|
1357 | (delete-region start end) ; delete whitespace |
---|
1358 | (insert text) ; insert text in inverse video. |
---|
1359 | (sit-for 0) ; update display showing inverse video. |
---|
1360 | (if highlight (setq inverse-video (not inverse-video))) ; toggle video |
---|
1361 | (set-buffer-modified-p modified))) ; don't modify if flag not set. |
---|
1362 | |
---|
1363 | |
---|
1364 | (defun ispell-highlight-spelling-error-lucid (start end &optional highlight) |
---|
1365 | "Highlight the word from START to END using `isearch-highlight'. |
---|
1366 | When the optional third arg HIGHLIGHT is set, the word is highlighted, |
---|
1367 | otherwise it is displayed normally." |
---|
1368 | (if highlight |
---|
1369 | (isearch-highlight start end) |
---|
1370 | (isearch-dehighlight t)) |
---|
1371 | ;;(sit-for 0) |
---|
1372 | ) |
---|
1373 | |
---|
1374 | |
---|
1375 | (defun ispell-highlight-spelling-error-overlay (start end &optional highlight) |
---|
1376 | "Highlight the word from START to END using overlays. |
---|
1377 | When the optional third arg HIGHLIGHT is set, the word is highlighted |
---|
1378 | otherwise it is displayed normally. |
---|
1379 | |
---|
1380 | The variable `ispell-highlight-face' selects the face to use for highlighting." |
---|
1381 | (if highlight |
---|
1382 | (progn |
---|
1383 | (setq ispell-overlay (make-overlay start end)) |
---|
1384 | (overlay-put ispell-overlay 'face ispell-highlight-face)) |
---|
1385 | (delete-overlay ispell-overlay))) |
---|
1386 | |
---|
1387 | |
---|
1388 | (defun ispell-highlight-spelling-error (start end &optional highlight) |
---|
1389 | (cond |
---|
1390 | ((string-match "Lucid" emacs-version) |
---|
1391 | (ispell-highlight-spelling-error-lucid start end highlight)) |
---|
1392 | ((and (string-lessp "19" emacs-version) |
---|
1393 | (featurep 'faces) window-system) |
---|
1394 | (ispell-highlight-spelling-error-overlay start end highlight)) |
---|
1395 | (t (ispell-highlight-spelling-error-generic start end highlight)))) |
---|
1396 | |
---|
1397 | |
---|
1398 | (defun ispell-overlay-window (height) |
---|
1399 | "Create a window covering the top HEIGHT lines of the current window. |
---|
1400 | Ensure that the line above point is still visible but otherwise avoid |
---|
1401 | scrolling the current window. Leave the new window selected." |
---|
1402 | (save-excursion |
---|
1403 | (let ((oldot (save-excursion (forward-line -1) (point))) |
---|
1404 | (top (save-excursion (move-to-window-line height) (point)))) |
---|
1405 | ;; If line above old point (line starting at olddot) would be |
---|
1406 | ;; hidden by new window, scroll it to just below new win |
---|
1407 | ;; otherwise set top line of other win so it doesn't scroll. |
---|
1408 | (if (< oldot top) (setq top oldot)) |
---|
1409 | ;; NB: Lemacs 19.9 bug: If a window of size N (N includes the mode |
---|
1410 | ;; line) is demanded, the last line is not visible. |
---|
1411 | ;; At least this happens on AIX 3.2, lemacs w/ Motif, font 9x15. |
---|
1412 | ;; So we increment the height for this case. |
---|
1413 | (if (string-match "19\.9.*Lucid" (emacs-version)) |
---|
1414 | (setq height (1+ height))) |
---|
1415 | (split-window nil height) |
---|
1416 | (set-window-start (next-window) top)))) |
---|
1417 | |
---|
1418 | |
---|
1419 | ;;; Should we add a compound word match return value? |
---|
1420 | (defun ispell-parse-output (output) |
---|
1421 | "Parse the OUTPUT string from Ispell and return: |
---|
1422 | 1: t for an exact match. |
---|
1423 | 2: A string containing the root word for a match via suffix removal. |
---|
1424 | 3: A list of possible correct spellings of the format: |
---|
1425 | '(\"ORIGINAL-WORD\" OFFSET MISS-LIST GUESS-LIST) |
---|
1426 | ORIGINAL-WORD is a string of the possibly misspelled word. |
---|
1427 | OFFSET is an integer giving the line offset of the word. |
---|
1428 | MISS-LIST and GUESS-LIST are possibly null lists of guesses and misses." |
---|
1429 | (cond |
---|
1430 | ((string= output "") t) ; for startup with pipes... |
---|
1431 | ((string= output "*") t) ; exact match |
---|
1432 | ((string= output "-") t) ; compound word match |
---|
1433 | ((string= (substring output 0 1) "+") ; found cuz of root word |
---|
1434 | (substring output 2)) ; return root word |
---|
1435 | (t ; need to process &, ?, and #'s |
---|
1436 | (let ((type (substring output 0 1)) ; &, ?, or # |
---|
1437 | (original-word (substring output 2 (string-match " " output 2))) |
---|
1438 | (cur-count 0) ; contains number of misses + guesses |
---|
1439 | count miss-list guess-list offset) |
---|
1440 | (setq output (substring output (match-end 0))) ; skip over misspelling |
---|
1441 | (if (string= type "#") |
---|
1442 | (setq count 0) ; no misses for type # |
---|
1443 | (setq count (string-to-int output) ; get number of misses. |
---|
1444 | output (substring output (1+ (string-match " " output 1))))) |
---|
1445 | (setq offset (string-to-int output)) |
---|
1446 | (if (string= type "#") ; No miss or guess list. |
---|
1447 | (setq output nil) |
---|
1448 | (setq output (substring output (1+ (string-match " " output 1))))) |
---|
1449 | (while output |
---|
1450 | (let ((end (string-match ", \\|\\($\\)" output))) ; end of miss/guess. |
---|
1451 | (setq cur-count (1+ cur-count)) |
---|
1452 | (if (> cur-count count) |
---|
1453 | (setq guess-list (cons (substring output 0 end) guess-list)) |
---|
1454 | (setq miss-list (cons (substring output 0 end) miss-list))) |
---|
1455 | (if (match-end 1) ; True only when at end of line. |
---|
1456 | (setq output nil) ; no more misses or guesses |
---|
1457 | (setq output (substring output (+ end 2)))))) |
---|
1458 | (list original-word offset miss-list guess-list))))) |
---|
1459 | |
---|
1460 | |
---|
1461 | (defun check-ispell-version () |
---|
1462 | ;; This is a little wasteful as we actually launch ispell twice: once |
---|
1463 | ;; to make sure it's the right version, and once for real. But people |
---|
1464 | ;; get confused by version mismatches *all* the time (and I've got the |
---|
1465 | ;; email to prove it) so I think this is worthwhile. And the -v[ersion] |
---|
1466 | ;; option is the only way I can think of to do this that works with |
---|
1467 | ;; all versions, since versions earlier than 3.0.09 didn't identify |
---|
1468 | ;; themselves on startup. |
---|
1469 | (save-excursion |
---|
1470 | (let ((case-fold-search t) |
---|
1471 | ;; avoid bugs when syntax of `.' changes in various default modes |
---|
1472 | (default-major-mode 'fundamental-mode) |
---|
1473 | status) |
---|
1474 | (set-buffer (get-buffer-create " *ispell-tmp*")) |
---|
1475 | (erase-buffer) |
---|
1476 | (setq status (call-process ispell-program-name nil t nil "-v")) |
---|
1477 | (goto-char (point-min)) |
---|
1478 | (if (not (memq status '(0 nil))) |
---|
1479 | (error "%s exited with %s %s" ispell-program-name |
---|
1480 | (if (stringp status) "signal" "code") status)) |
---|
1481 | (if (not (re-search-forward |
---|
1482 | (concat "\\b\\(" |
---|
1483 | (regexp-quote (car ispell-required-version)) |
---|
1484 | "\\)\\([0-9]*\\)\\b") |
---|
1485 | nil t)) |
---|
1486 | (error |
---|
1487 | "%s version %s* is required: try renaming ispell4.el to ispell.el" |
---|
1488 | ispell-program-name (car ispell-required-version)) |
---|
1489 | ;; check that it is the correct version. |
---|
1490 | (if (< (car (read-from-string (buffer-substring |
---|
1491 | (match-beginning 2) (match-end 2)))) |
---|
1492 | (car (cdr ispell-required-version))) |
---|
1493 | (setq ispell-offset 0))) |
---|
1494 | (kill-buffer (current-buffer))))) |
---|
1495 | |
---|
1496 | |
---|
1497 | (defun ispell-init-process () |
---|
1498 | "Check status of Ispell process and start if necessary." |
---|
1499 | (if (and ispell-process |
---|
1500 | (eq (process-status ispell-process) 'run) |
---|
1501 | ;; If we're using a personal dictionary, assure |
---|
1502 | ;; we're in the same default directory! |
---|
1503 | (or (not ispell-personal-dictionary) |
---|
1504 | (equal ispell-process-directory default-directory))) |
---|
1505 | (setq ispell-filter nil ispell-filter-continue nil) |
---|
1506 | ;; may need to restart to select new personal dictionary. |
---|
1507 | (ispell-kill-ispell t) |
---|
1508 | (message "Starting new Ispell process...") |
---|
1509 | (sit-for 0) |
---|
1510 | (check-ispell-version) |
---|
1511 | (setq ispell-process |
---|
1512 | (let ((process-connection-type ispell-use-ptys-p)) |
---|
1513 | (apply 'start-process |
---|
1514 | "ispell" nil ispell-program-name |
---|
1515 | "-a" ; accept single input lines |
---|
1516 | "-m" ; make root/affix combos not in dict |
---|
1517 | (let (args) |
---|
1518 | ;; Local dictionary becomes the global dictionary in use. |
---|
1519 | (if ispell-local-dictionary |
---|
1520 | (setq ispell-dictionary ispell-local-dictionary)) |
---|
1521 | (setq args (ispell-get-ispell-args)) |
---|
1522 | (if ispell-dictionary ; use specified dictionary |
---|
1523 | (setq args |
---|
1524 | (append (list "-d" ispell-dictionary) args))) |
---|
1525 | (if ispell-personal-dictionary ; use specified pers dict |
---|
1526 | (setq args |
---|
1527 | (append args |
---|
1528 | (list "-p" |
---|
1529 | (expand-file-name |
---|
1530 | ispell-personal-dictionary))))) |
---|
1531 | (setq args (append args ispell-extra-args)) |
---|
1532 | args))) |
---|
1533 | ispell-filter nil |
---|
1534 | ispell-filter-continue nil |
---|
1535 | ispell-process-directory default-directory) |
---|
1536 | (set-process-filter ispell-process 'ispell-filter) |
---|
1537 | (accept-process-output ispell-process) ; Get version ID line |
---|
1538 | (cond ((null ispell-filter) |
---|
1539 | (error "%s did not output version line" ispell-program-name)) |
---|
1540 | ((and |
---|
1541 | (stringp (car ispell-filter)) |
---|
1542 | (if (string-match "warning: " (car ispell-filter)) |
---|
1543 | (progn |
---|
1544 | (accept-process-output ispell-process 5) ; 1st was warn msg. |
---|
1545 | (stringp (car ispell-filter))) |
---|
1546 | (null (cdr ispell-filter))) |
---|
1547 | (string-match "^@(#) " (car ispell-filter))) |
---|
1548 | ;; got the version line as expected (we already know it's the right |
---|
1549 | ;; version, so don't bother checking again.) |
---|
1550 | nil) |
---|
1551 | (t |
---|
1552 | ;; Otherwise, it must be an error message. Show the user. |
---|
1553 | ;; But first wait to see if some more output is going to arrive. |
---|
1554 | ;; Otherwise we get cool errors like "Can't open ". |
---|
1555 | (sleep-for 1) |
---|
1556 | (accept-process-output) |
---|
1557 | (error "%s" (mapconcat 'identity ispell-filter "\n")))) |
---|
1558 | (setq ispell-filter nil) ; Discard version ID line |
---|
1559 | (let ((extended-char-mode (ispell-get-extended-character-mode))) |
---|
1560 | (if extended-char-mode |
---|
1561 | (process-send-string ispell-process |
---|
1562 | (concat extended-char-mode "\n")))) |
---|
1563 | (process-kill-without-query ispell-process))) |
---|
1564 | |
---|
1565 | ;;;###autoload |
---|
1566 | (defun ispell-kill-ispell (&optional no-error) |
---|
1567 | "Kill current Ispell process (so that you may start a fresh one). |
---|
1568 | With NO-ERROR, just return non-nil if there was no Ispell running." |
---|
1569 | (interactive) |
---|
1570 | (if (not (and ispell-process |
---|
1571 | (eq (process-status ispell-process) 'run))) |
---|
1572 | (or no-error |
---|
1573 | (error "There is no ispell process running!")) |
---|
1574 | (kill-process ispell-process) |
---|
1575 | (setq ispell-process nil) |
---|
1576 | (message "Ispell process killed") |
---|
1577 | nil)) |
---|
1578 | |
---|
1579 | |
---|
1580 | ;;; ispell-change-dictionary is set in some people's hooks. Maybe this should |
---|
1581 | ;;; call ispell-init-process rather than wait for a spell checking command? |
---|
1582 | |
---|
1583 | ;;;###autoload |
---|
1584 | (defun ispell-change-dictionary (dict &optional arg) |
---|
1585 | "Change `ispell-dictionary' (q.v.) and kill old Ispell process. |
---|
1586 | A new one will be started as soon as necessary. |
---|
1587 | |
---|
1588 | By just answering RET you can find out what the current dictionary is. |
---|
1589 | |
---|
1590 | With prefix argument, set the default directory." |
---|
1591 | (interactive |
---|
1592 | (list (completing-read |
---|
1593 | "Use new dictionary (RET for current, SPC to complete): " |
---|
1594 | (cons (cons "default" nil) ispell-dictionary-alist) nil t) |
---|
1595 | current-prefix-arg)) |
---|
1596 | (if (equal dict "default") (setq dict nil)) |
---|
1597 | ;; This relies on completing-read's bug of returning "" for no match |
---|
1598 | (cond ((equal dict "") |
---|
1599 | (message "Using %s dictionary" |
---|
1600 | (or ispell-local-dictionary ispell-dictionary "default"))) |
---|
1601 | ((and (equal dict ispell-dictionary) |
---|
1602 | (or (null ispell-local-dictionary) |
---|
1603 | (equal dict ispell-local-dictionary))) |
---|
1604 | ;; Specified dictionary is the default already. No-op |
---|
1605 | (and (interactive-p) |
---|
1606 | (message "No change, using %s dictionary" (or dict "default")))) |
---|
1607 | (t ; reset dictionary! |
---|
1608 | (if (assoc dict ispell-dictionary-alist) |
---|
1609 | (progn |
---|
1610 | (if (or arg (null dict)) ; set default dictionary |
---|
1611 | (setq ispell-dictionary dict)) |
---|
1612 | (if (null arg) ; set local dictionary |
---|
1613 | (setq ispell-local-dictionary dict))) |
---|
1614 | (error "Illegal dictionary: %s" dict)) |
---|
1615 | (ispell-kill-ispell t) |
---|
1616 | (message "(Next %sIspell command will use %s dictionary)" |
---|
1617 | (cond ((equal ispell-local-dictionary ispell-dictionary) |
---|
1618 | "") |
---|
1619 | (arg "global ") |
---|
1620 | (t "local ")) |
---|
1621 | (or (if (or (equal ispell-local-dictionary ispell-dictionary) |
---|
1622 | (null arg)) |
---|
1623 | ispell-local-dictionary |
---|
1624 | ispell-dictionary) |
---|
1625 | "default"))))) |
---|
1626 | |
---|
1627 | |
---|
1628 | ;;; Spelling of comments are checked when ispell-check-comments is non-nil. |
---|
1629 | |
---|
1630 | ;;;###autoload |
---|
1631 | (defun ispell-region (reg-start reg-end) |
---|
1632 | "Interactively check a region for spelling errors." |
---|
1633 | (interactive "r") ; Don't flag errors on read-only bufs. |
---|
1634 | (ispell-accept-buffer-local-defs) ; set up dictionary, local words, etc. |
---|
1635 | (unwind-protect |
---|
1636 | (save-excursion |
---|
1637 | (message "Spell checking %s using %s dictionary..." |
---|
1638 | (if (and (= reg-start (point-min)) (= reg-end (point-max))) |
---|
1639 | (buffer-name) "region") |
---|
1640 | (or ispell-dictionary "default")) |
---|
1641 | ;; Returns cursor to original location. |
---|
1642 | (save-window-excursion |
---|
1643 | (goto-char reg-start) |
---|
1644 | (let ((transient-mark-mode nil) |
---|
1645 | ref-type) |
---|
1646 | (while (and (not ispell-quit) (< (point) reg-end)) |
---|
1647 | (let ((start (point)) |
---|
1648 | (offset-change 0) |
---|
1649 | (end (save-excursion (end-of-line) (min (point) reg-end))) |
---|
1650 | (ispell-casechars (ispell-get-casechars)) |
---|
1651 | string) |
---|
1652 | (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS |
---|
1653 | ((eolp) ; END OF LINE, just go to next line. |
---|
1654 | (forward-char 1)) |
---|
1655 | ((and (null ispell-check-comments) ; SKIPPING COMMENTS |
---|
1656 | comment-start ; skip comments that start on the line. |
---|
1657 | (search-forward comment-start end t)) ; or found here. |
---|
1658 | (if (= (- (point) start) (length comment-start)) |
---|
1659 | ;; comment starts the line. Skip entire line or region |
---|
1660 | (if (string= "" comment-end) ; skip to next line |
---|
1661 | (beginning-of-line 2) ; or jump to comment end. |
---|
1662 | (search-forward comment-end reg-end 'limit)) |
---|
1663 | ;; Comment later in line. Check spelling before comment. |
---|
1664 | (let ((limit (- (point) (length comment-start)))) |
---|
1665 | (goto-char (1- limit)) |
---|
1666 | (if (looking-at "\\\\") ; "quoted" comment, don't skip |
---|
1667 | ;; quoted comment. Skip over comment-start |
---|
1668 | (if (= start (1- limit)) |
---|
1669 | (setq limit (+ limit (length comment-start))) |
---|
1670 | (setq limit (1- limit)))) |
---|
1671 | (goto-char start) |
---|
1672 | ;; Only check when "casechars" or math before comment |
---|
1673 | (if (or (re-search-forward ispell-casechars limit t) |
---|
1674 | (re-search-forward "[][()$]" limit t)) |
---|
1675 | (setq string |
---|
1676 | (concat "^" (buffer-substring start limit) |
---|
1677 | "\n") |
---|
1678 | offset-change (- offset-change ispell-offset))) |
---|
1679 | (goto-char limit)))) |
---|
1680 | ((looking-at "[---#@*+!%~^]") ; SKIP SPECIAL ISPELL CHARACTERS |
---|
1681 | (forward-char 1)) |
---|
1682 | ((or (and ispell-skip-tib ; SKIP TIB REFERENCES OR SGML MARKUP |
---|
1683 | (re-search-forward ispell-tib-ref-beginning end t) |
---|
1684 | (setq ref-type 'tib)) |
---|
1685 | (and ispell-skip-sgml |
---|
1686 | (search-forward "[<&]" end t) |
---|
1687 | (setq ref-type 'sgml))) |
---|
1688 | (if (or (and (eq 'tib ref-type) ; tib tag is 2 chars. |
---|
1689 | (= (- (point) 2) start)) |
---|
1690 | (and (eq 'sgml ref-type) ; sgml skips 1 char. |
---|
1691 | (= (- (point) 1) start))) |
---|
1692 | ;; Skip to end of reference, not necessarily on this line |
---|
1693 | ;; Return an error if tib/sgml reference not found |
---|
1694 | (if (or |
---|
1695 | (and |
---|
1696 | (eq 'tib ref-type) |
---|
1697 | (not |
---|
1698 | (re-search-forward ispell-tib-ref-end reg-end t))) |
---|
1699 | (and (eq 'sgml ref-type) |
---|
1700 | (not (search-forward "[>;]" reg-end t)))) |
---|
1701 | (progn |
---|
1702 | (ispell-pdict-save ispell-silently-savep) |
---|
1703 | (ding) |
---|
1704 | (message |
---|
1705 | (concat |
---|
1706 | "Open tib or SGML command. Fix buffer or set " |
---|
1707 | (if (eq 'tib ref-type) |
---|
1708 | "ispell-skip-tib" |
---|
1709 | "ispell-skip-sgml") |
---|
1710 | " to nil")) |
---|
1711 | ;; keep cursor at error location |
---|
1712 | (setq ispell-quit (- (point) 2)))) |
---|
1713 | ;; Check spelling between reference and start of the line. |
---|
1714 | (let ((limit (- (point) (if (eq 'tib ref-type) 2 1)))) |
---|
1715 | (goto-char start) |
---|
1716 | (if (or (re-search-forward ispell-casechars limit t) |
---|
1717 | (re-search-forward "[][()$]" limit t)) |
---|
1718 | (setq string |
---|
1719 | (concat "^" (buffer-substring start limit) |
---|
1720 | "\n") |
---|
1721 | offset-change (- offset-change ispell-offset))) |
---|
1722 | (goto-char limit)))) |
---|
1723 | ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS |
---|
1724 | (re-search-forward "[][()$]" end t)) ; or MATH COMMANDS |
---|
1725 | (setq string (concat "^" (buffer-substring start end) "\n") |
---|
1726 | offset-change (- offset-change ispell-offset)) |
---|
1727 | (goto-char end)) |
---|
1728 | (t (beginning-of-line 2))) ; EMPTY LINE, skip it. |
---|
1729 | |
---|
1730 | (setq end (point)) ; "end" tracks end of region to check. |
---|
1731 | |
---|
1732 | (if string ; there is something to spell! |
---|
1733 | (let (poss) |
---|
1734 | ;; send string to spell process and get input. |
---|
1735 | (process-send-string ispell-process string) |
---|
1736 | (while (progn |
---|
1737 | (accept-process-output ispell-process) |
---|
1738 | ;; Last item of output contains a blank line. |
---|
1739 | (not (string= "" (car ispell-filter))))) |
---|
1740 | ;; parse all inputs from the stream one word at a time. |
---|
1741 | ;; Place in FIFO order and remove the blank item. |
---|
1742 | (setq ispell-filter (nreverse (cdr ispell-filter))) |
---|
1743 | (while (and (not ispell-quit) ispell-filter) |
---|
1744 | (setq poss (ispell-parse-output (car ispell-filter))) |
---|
1745 | (if (listp poss) ; spelling error occurred. |
---|
1746 | (let* ((word-start (+ start offset-change |
---|
1747 | (car (cdr poss)))) |
---|
1748 | (word-end (+ word-start |
---|
1749 | (length (car poss)))) |
---|
1750 | replace) |
---|
1751 | (goto-char word-start) |
---|
1752 | ;; Adjust the horizontal scroll & point |
---|
1753 | (ispell-horiz-scroll) |
---|
1754 | (goto-char word-end) |
---|
1755 | (ispell-horiz-scroll) |
---|
1756 | (goto-char word-start) |
---|
1757 | (ispell-horiz-scroll) |
---|
1758 | (if (/= word-end |
---|
1759 | (progn |
---|
1760 | (search-forward (car poss) word-end t) |
---|
1761 | (point))) |
---|
1762 | ;; This occurs due to filter pipe problems |
---|
1763 | (error |
---|
1764 | (concat "Ispell misalignment: word " |
---|
1765 | "`%s' point %d; please retry") |
---|
1766 | (car poss) word-start)) |
---|
1767 | (if ispell-keep-choices-win |
---|
1768 | (setq replace |
---|
1769 | (ispell-command-loop |
---|
1770 | (car (cdr (cdr poss))) |
---|
1771 | (car (cdr (cdr (cdr poss)))) |
---|
1772 | (car poss) word-start word-end)) |
---|
1773 | (save-window-excursion |
---|
1774 | (setq replace |
---|
1775 | (ispell-command-loop |
---|
1776 | (car (cdr (cdr poss))) |
---|
1777 | (car (cdr (cdr (cdr poss)))) |
---|
1778 | (car poss) word-start word-end)))) |
---|
1779 | (cond |
---|
1780 | ((and replace (listp replace)) |
---|
1781 | ;; REPLACEMENT WORD entered. Recheck line |
---|
1782 | ;; starting with the replacement word. |
---|
1783 | (setq ispell-filter nil |
---|
1784 | string (buffer-substring word-start |
---|
1785 | word-end)) |
---|
1786 | (let ((change (- (length (car replace)) |
---|
1787 | (length (car poss))))) |
---|
1788 | ;; adjust regions |
---|
1789 | (setq reg-end (+ reg-end change) |
---|
1790 | offset-change (+ offset-change |
---|
1791 | change))) |
---|
1792 | (if (not (equal (car replace) (car poss))) |
---|
1793 | (progn |
---|
1794 | (delete-region word-start word-end) |
---|
1795 | (insert (car replace)))) |
---|
1796 | ;; I only need to recheck typed-in replacements |
---|
1797 | (if (not (eq 'query-replace |
---|
1798 | (car (cdr replace)))) |
---|
1799 | (backward-char (length (car replace)))) |
---|
1800 | (setq end (point)) ; reposition for recheck |
---|
1801 | ;; when second arg exists, query-replace, saving regions |
---|
1802 | (if (car (cdr replace)) |
---|
1803 | (unwind-protect |
---|
1804 | (save-window-excursion |
---|
1805 | (set-marker |
---|
1806 | ispell-query-replace-marker reg-end) |
---|
1807 | ;; Assume case-replace & |
---|
1808 | ;; case-fold-search correct? |
---|
1809 | (query-replace string (car replace) |
---|
1810 | t)) |
---|
1811 | (setq reg-end |
---|
1812 | (marker-position |
---|
1813 | ispell-query-replace-marker)) |
---|
1814 | (set-marker ispell-query-replace-marker |
---|
1815 | nil)))) |
---|
1816 | ((or (null replace) |
---|
1817 | (equal 0 replace)) ; ACCEPT/INSERT |
---|
1818 | (if (equal 0 replace) ; BUFFER-LOCAL DICT ADD |
---|
1819 | (setq reg-end |
---|
1820 | (ispell-add-per-file-word-list |
---|
1821 | (car poss) reg-end))) |
---|
1822 | ;; This avoids pointing out the word that was |
---|
1823 | ;; just accepted (via 'i' or 'a') if it follows |
---|
1824 | ;; on the same line. |
---|
1825 | ;; Redo check following the accepted word. |
---|
1826 | (if (and ispell-pdict-modified-p |
---|
1827 | (listp ispell-pdict-modified-p)) |
---|
1828 | ;; Word accepted. Recheck line. |
---|
1829 | (setq ispell-pdict-modified-p ; update flag |
---|
1830 | (car ispell-pdict-modified-p) |
---|
1831 | ispell-filter nil ; discontinue check |
---|
1832 | end word-start))) ; reposition loc. |
---|
1833 | (replace ; STRING REPLACEMENT for this word. |
---|
1834 | (delete-region word-start word-end) |
---|
1835 | (insert replace) |
---|
1836 | (let ((change (- (length replace) |
---|
1837 | (length (car poss))))) |
---|
1838 | (setq reg-end (+ reg-end change) |
---|
1839 | offset-change (+ offset-change change) |
---|
1840 | end (+ end change))))) |
---|
1841 | (if (not ispell-quit) |
---|
1842 | (message |
---|
1843 | (concat "Continuing spelling check using " |
---|
1844 | (or ispell-dictionary "default") |
---|
1845 | " dictionary..."))) |
---|
1846 | (sit-for 0))) |
---|
1847 | ;; finished with line! |
---|
1848 | (setq ispell-filter (cdr ispell-filter))))) |
---|
1849 | (goto-char end))))) |
---|
1850 | (not ispell-quit)) |
---|
1851 | ;; protected |
---|
1852 | (if (get-buffer ispell-choices-buffer) |
---|
1853 | (kill-buffer ispell-choices-buffer)) |
---|
1854 | (if ispell-quit |
---|
1855 | (progn |
---|
1856 | ;; preserve or clear the region for ispell-continue. |
---|
1857 | (if (not (numberp ispell-quit)) |
---|
1858 | (set-marker ispell-region-end nil) |
---|
1859 | ;; Enable ispell-continue. |
---|
1860 | (set-marker ispell-region-end reg-end) |
---|
1861 | (goto-char ispell-quit)) |
---|
1862 | ;; Check for aborting |
---|
1863 | (if (and ispell-checking-message (numberp ispell-quit)) |
---|
1864 | (progn |
---|
1865 | (setq ispell-quit nil) |
---|
1866 | (error "Message send aborted."))) |
---|
1867 | (setq ispell-quit nil)) |
---|
1868 | (set-marker ispell-region-end nil) |
---|
1869 | ;; Only save if successful exit. |
---|
1870 | (ispell-pdict-save ispell-silently-savep) |
---|
1871 | (message "Spell-checking done")))) |
---|
1872 | |
---|
1873 | |
---|
1874 | |
---|
1875 | ;;;###autoload |
---|
1876 | (defun ispell-buffer () |
---|
1877 | "Check the current buffer for spelling errors interactively." |
---|
1878 | (interactive) |
---|
1879 | (ispell-region (point-min) (point-max))) |
---|
1880 | |
---|
1881 | |
---|
1882 | ;;;###autoload |
---|
1883 | (defun ispell-continue () |
---|
1884 | (interactive) |
---|
1885 | "Continue a spelling session after making some changes." |
---|
1886 | (if (not (marker-position ispell-region-end)) |
---|
1887 | (message "No session to continue. Use 'X' command when checking!") |
---|
1888 | (if (not (equal (marker-buffer ispell-region-end) (current-buffer))) |
---|
1889 | (message "Must continue ispell from buffer %s" |
---|
1890 | (buffer-name (marker-buffer ispell-region-end))) |
---|
1891 | (ispell-region (point) (marker-position ispell-region-end))))) |
---|
1892 | |
---|
1893 | |
---|
1894 | ;;; Horizontal scrolling |
---|
1895 | (defun ispell-horiz-scroll () |
---|
1896 | "Places point within the horizontal visibility of its window area." |
---|
1897 | (if truncate-lines ; display truncating lines? |
---|
1898 | ;; See if display needs to be scrolled. |
---|
1899 | (let ((column (- (current-column) (max (window-hscroll) 1)))) |
---|
1900 | (if (and (< column 0) (> (window-hscroll) 0)) |
---|
1901 | (scroll-right (max (- column) 10)) |
---|
1902 | (if (>= column (- (window-width) 2)) |
---|
1903 | (scroll-left (max (- column (window-width) -3) 10))))))) |
---|
1904 | |
---|
1905 | |
---|
1906 | ;;; Interactive word completion. |
---|
1907 | ;;; Forces "previous-word" processing. Do we want to make this selectable? |
---|
1908 | |
---|
1909 | ;;;###autoload |
---|
1910 | (defun ispell-complete-word (&optional interior-frag) |
---|
1911 | "Look up word before or under point in dictionary (see lookup-words command) |
---|
1912 | and try to complete it. If optional INTERIOR-FRAG is non-nil then the word |
---|
1913 | may be a character sequence inside of a word. |
---|
1914 | |
---|
1915 | Standard ispell choices are then available." |
---|
1916 | (interactive "P") |
---|
1917 | (let ((cursor-location (point)) |
---|
1918 | case-fold-search |
---|
1919 | (word (ispell-get-word nil "\\*")) ; force "previous-word" processing. |
---|
1920 | start end possibilities replacement) |
---|
1921 | (setq start (car (cdr word)) |
---|
1922 | end (car (cdr (cdr word))) |
---|
1923 | word (car word) |
---|
1924 | possibilities |
---|
1925 | (or (string= word "") ; Will give you every word |
---|
1926 | (lookup-words (concat (if interior-frag "*") word "*") |
---|
1927 | ispell-complete-word-dict))) |
---|
1928 | (cond ((eq possibilities t) |
---|
1929 | (message "No word to complete")) |
---|
1930 | ((null possibilities) |
---|
1931 | (message "No match for \"%s\"" word)) |
---|
1932 | (t ; There is a modification... |
---|
1933 | (cond ; Try and respect case of word. |
---|
1934 | ((string-match "^[^A-Z]+$" word) |
---|
1935 | (setq possibilities (mapcar 'downcase possibilities))) |
---|
1936 | ((string-match "^[^a-z]+$" word) |
---|
1937 | (setq possibilities (mapcar 'upcase possibilities))) |
---|
1938 | ((string-match "^[A-Z]" word) |
---|
1939 | (setq possibilities (mapcar 'capitalize possibilities)))) |
---|
1940 | (save-window-excursion |
---|
1941 | (setq replacement |
---|
1942 | (ispell-command-loop possibilities nil word start end))) |
---|
1943 | (cond |
---|
1944 | ((equal 0 replacement) ; BUFFER-LOCAL ADDITION |
---|
1945 | (ispell-add-per-file-word-list word)) |
---|
1946 | (replacement ; REPLACEMENT WORD |
---|
1947 | (delete-region start end) |
---|
1948 | (setq word (if (atom replacement) replacement (car replacement)) |
---|
1949 | cursor-location (+ (- (length word) (- end start)) |
---|
1950 | cursor-location)) |
---|
1951 | (insert word) |
---|
1952 | (if (not (atom replacement)) ; recheck spelling of replacement. |
---|
1953 | (progn |
---|
1954 | (goto-char cursor-location) |
---|
1955 | (ispell-word nil t))))) |
---|
1956 | (if (get-buffer ispell-choices-buffer) |
---|
1957 | (kill-buffer ispell-choices-buffer)))) |
---|
1958 | (ispell-pdict-save ispell-silently-savep) |
---|
1959 | (goto-char cursor-location))) |
---|
1960 | |
---|
1961 | |
---|
1962 | ;;;###autoload |
---|
1963 | (defun ispell-complete-word-interior-frag () |
---|
1964 | "Completes word matching character sequence inside a word." |
---|
1965 | (interactive) |
---|
1966 | (ispell-complete-word t)) |
---|
1967 | |
---|
1968 | |
---|
1969 | ;;; ********************************************************************** |
---|
1970 | ;;; Ispell Minor Mode |
---|
1971 | ;;; ********************************************************************** |
---|
1972 | |
---|
1973 | (defvar ispell-minor-mode nil |
---|
1974 | "Non-nil if Ispell minor mode is enabled.") |
---|
1975 | ;; Variable indicating that ispell minor mode is active. |
---|
1976 | (make-variable-buffer-local 'ispell-minor-mode) |
---|
1977 | |
---|
1978 | (or (assq 'ispell-minor-mode minor-mode-alist) |
---|
1979 | (setq minor-mode-alist |
---|
1980 | (cons '(ispell-minor-mode " Spell") minor-mode-alist))) |
---|
1981 | |
---|
1982 | (defvar ispell-minor-keymap |
---|
1983 | (let ((map (make-sparse-keymap))) |
---|
1984 | (define-key map " " 'ispell-minor-check) |
---|
1985 | (define-key map "\r" 'ispell-minor-check) |
---|
1986 | map) |
---|
1987 | "Keymap used for Ispell minor mode.") |
---|
1988 | |
---|
1989 | (or (not (boundp 'minor-mode-map-alist)) |
---|
1990 | (assoc 'ispell-minor-mode minor-mode-map-alist) |
---|
1991 | (setq minor-mode-map-alist |
---|
1992 | (cons (cons 'ispell-minor-mode ispell-minor-keymap) |
---|
1993 | minor-mode-map-alist))) |
---|
1994 | |
---|
1995 | ;;;###autoload |
---|
1996 | (defun ispell-minor-mode (&optional arg) |
---|
1997 | "Toggle Ispell minor mode. |
---|
1998 | With prefix arg, turn Ispell minor mode on iff arg is positive. |
---|
1999 | |
---|
2000 | In Ispell minor mode, pressing SPC or RET |
---|
2001 | warns you if the previous word is incorrectly spelled." |
---|
2002 | (interactive "P") |
---|
2003 | (setq ispell-minor-mode |
---|
2004 | (not (or (and (null arg) ispell-minor-mode) |
---|
2005 | (<= (prefix-numeric-value arg) 0)))) |
---|
2006 | (force-mode-line-update)) |
---|
2007 | |
---|
2008 | (defun ispell-minor-check () |
---|
2009 | ;; Check previous word then continue with the normal binding of this key. |
---|
2010 | (interactive "*") |
---|
2011 | (let ((ispell-minor-mode nil) |
---|
2012 | (ispell-check-only t)) |
---|
2013 | (save-restriction |
---|
2014 | (narrow-to-region (point-min) (point)) |
---|
2015 | (ispell-word nil t)) |
---|
2016 | (call-interactively (key-binding (this-command-keys))))) |
---|
2017 | |
---|
2018 | |
---|
2019 | ;;; ********************************************************************** |
---|
2020 | ;;; Ispell Message |
---|
2021 | ;;; ********************************************************************** |
---|
2022 | ;;; Original from D. Quinlan, E. Bradford, A. Albert, and M. Ernst |
---|
2023 | |
---|
2024 | |
---|
2025 | (defvar ispell-message-text-end |
---|
2026 | (mapconcat (function identity) |
---|
2027 | '( |
---|
2028 | ;; Matches postscript files. |
---|
2029 | "^%!PS-Adobe-[123].0" |
---|
2030 | ;; Matches uuencoded text |
---|
2031 | "^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" |
---|
2032 | ;; Matches shell files (esp. auto-decoding) |
---|
2033 | "^#! /bin/[ck]?sh" |
---|
2034 | ;; Matches context difference listing |
---|
2035 | "\\(diff -c .*\\)?\n\\*\\*\\* .*\n--- .*\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*" |
---|
2036 | ;; Matches "----------------- cut here" |
---|
2037 | "^[-=_]+\\s ?cut here") |
---|
2038 | "\\|") |
---|
2039 | "*End of text which will be checked in ispell-message. |
---|
2040 | If it is a string, limit at first occurrence of that regular expression. |
---|
2041 | Otherwise, it must be a function which is called to get the limit.") |
---|
2042 | |
---|
2043 | |
---|
2044 | (defvar ispell-message-start-skip |
---|
2045 | (mapconcat (function identity) |
---|
2046 | '( |
---|
2047 | ;; Matches forwarded messages |
---|
2048 | "^---* Forwarded Message" |
---|
2049 | ;; Matches PGP Public Key block |
---|
2050 | "^---*BEGIN PGP [A-Z ]*--*" |
---|
2051 | ) |
---|
2052 | "\\|") |
---|
2053 | "Spelling is skipped inside these start/end groups by ispell-message. |
---|
2054 | Assumed that blocks are not mutually inclusive.") |
---|
2055 | |
---|
2056 | |
---|
2057 | (defvar ispell-message-end-skip |
---|
2058 | (mapconcat (function identity) |
---|
2059 | '( |
---|
2060 | ;; Matches forwarded messages |
---|
2061 | "^--- End of Forwarded Message" |
---|
2062 | ;; Matches PGP Public Key block |
---|
2063 | "^---*END PGP [A-Z ]*--*" |
---|
2064 | ) |
---|
2065 | "\\|") |
---|
2066 | "Spelling is skipped inside these start/end groups by ispell-message. |
---|
2067 | Assumed that blocks are not mutually inclusive.") |
---|
2068 | |
---|
2069 | |
---|
2070 | ;;;###autoload |
---|
2071 | (defun ispell-message () |
---|
2072 | "Check the spelling of a mail message or news post. |
---|
2073 | Don't check spelling of message headers except the Subject field. |
---|
2074 | Don't check included messages. |
---|
2075 | |
---|
2076 | To abort spell checking of a message REGION and send the message anyway, |
---|
2077 | use the `x' or `q' command. (Any subsequent regions will be checked.) |
---|
2078 | The `X' command aborts the message send so that you can edit the buffer. |
---|
2079 | |
---|
2080 | To spell-check whenever a message is sent, include the appropriate lines |
---|
2081 | in your .emacs file: |
---|
2082 | (add-hook 'news-inews-hook 'ispell-message) |
---|
2083 | (add-hook 'mail-send-hook 'ispell-message) |
---|
2084 | (add-hook 'mh-before-send-letter-hook 'ispell-message) |
---|
2085 | |
---|
2086 | You can bind this to the key C-c i in GNUS or mail by adding to |
---|
2087 | `news-reply-mode-hook' or `mail-mode-hook' the following lambda expression: |
---|
2088 | (function (lambda () (local-set-key \"\\C-ci\" 'ispell-message)))" |
---|
2089 | (interactive) |
---|
2090 | (save-excursion |
---|
2091 | (goto-char (point-min)) |
---|
2092 | (let* ((internal-messagep (save-excursion |
---|
2093 | (re-search-forward |
---|
2094 | (concat "^" |
---|
2095 | (regexp-quote mail-header-separator) |
---|
2096 | "$") |
---|
2097 | nil t))) |
---|
2098 | (limit (copy-marker |
---|
2099 | (cond |
---|
2100 | ((not ispell-message-text-end) (point-max)) |
---|
2101 | ((char-or-string-p ispell-message-text-end) |
---|
2102 | (if (re-search-forward ispell-message-text-end nil t) |
---|
2103 | (match-beginning 0) |
---|
2104 | (point-max))) |
---|
2105 | (t (min (point-max) (funcall ispell-message-text-end)))))) |
---|
2106 | (cite-regexp ;Prefix of inserted text |
---|
2107 | (cond |
---|
2108 | ((featurep 'supercite) ; sc 3.0 |
---|
2109 | (concat "\\(" (sc-cite-regexp) "\\)" "\\|" |
---|
2110 | (ispell-non-empty-string sc-reference-tag-string))) |
---|
2111 | ((featurep 'sc) ; sc 2.3 |
---|
2112 | (concat "\\(" sc-cite-regexp "\\)" "\\|" |
---|
2113 | (ispell-non-empty-string sc-reference-tag-string))) |
---|
2114 | ((equal major-mode 'news-reply-mode) ;GNUS |
---|
2115 | (concat "In article <" "\\|" |
---|
2116 | (if mail-yank-prefix |
---|
2117 | (ispell-non-empty-string mail-yank-prefix) |
---|
2118 | "^ \\|^\t"))) |
---|
2119 | ((equal major-mode 'mh-letter-mode) ; mh mail message |
---|
2120 | (ispell-non-empty-string mh-ins-buf-prefix)) |
---|
2121 | ((not internal-messagep) ; Assume n sent us this message. |
---|
2122 | (concat "In [a-zA-Z.]+ you write:" "\\|" |
---|
2123 | "In <[^,;&+=]+> [^,;&+=]+ writes:" "\\|" |
---|
2124 | " *> *")) |
---|
2125 | ((boundp 'vm-included-text-prefix) ; VM mail message |
---|
2126 | (concat "[^,;&+=]+ writes:" "\\|" |
---|
2127 | (ispell-non-empty-string vm-included-text-prefix))) |
---|
2128 | (mail-yank-prefix ; vanilla mail message. |
---|
2129 | (ispell-non-empty-string mail-yank-prefix)) |
---|
2130 | (t "^ \\|^\t"))) |
---|
2131 | (cite-regexp-start (concat "^[ \t]*$\\|" cite-regexp)) |
---|
2132 | (cite-regexp-end (concat "^\\(" cite-regexp "\\)")) |
---|
2133 | (old-case-fold-search case-fold-search) |
---|
2134 | (case-fold-search t) |
---|
2135 | (ispell-checking-message t)) |
---|
2136 | (goto-char (point-min)) |
---|
2137 | ;; Skip header fields except Subject: without Re:'s |
---|
2138 | ;;(search-forward mail-header-separator nil t) |
---|
2139 | (while (if internal-messagep |
---|
2140 | (< (point) internal-messagep) |
---|
2141 | (and (looking-at "[a-zA-Z---]+:\\|\t\\| ") |
---|
2142 | (not (eobp)))) |
---|
2143 | (if (looking-at "Subject: *") ; Spell check new subject fields |
---|
2144 | (progn |
---|
2145 | (goto-char (match-end 0)) |
---|
2146 | (if (and (not (looking-at ".*Re\\>")) |
---|
2147 | (not (looking-at "\\["))) |
---|
2148 | (let ((case-fold-search old-case-fold-search)) |
---|
2149 | (ispell-region (point) |
---|
2150 | (progn |
---|
2151 | (end-of-line) |
---|
2152 | (while (looking-at "\n[ \t]") |
---|
2153 | (end-of-line 2)) |
---|
2154 | (point))))))) |
---|
2155 | (forward-line 1)) |
---|
2156 | (setq case-fold-search nil) |
---|
2157 | ;; Skip mail header, particularly for non-english languages. |
---|
2158 | (if (looking-at (concat (regexp-quote mail-header-separator) "$")) |
---|
2159 | (forward-line 1)) |
---|
2160 | (while (< (point) limit) |
---|
2161 | ;; Skip across text cited from other messages. |
---|
2162 | (while (and (looking-at cite-regexp-start) |
---|
2163 | (< (point) limit) |
---|
2164 | (zerop (forward-line 1)))) |
---|
2165 | |
---|
2166 | (if (< (point) limit) |
---|
2167 | (let* ((start (point)) |
---|
2168 | ;; Check the next batch of lines that *aren't* cited. |
---|
2169 | (end-c (and (re-search-forward cite-regexp-end limit 'end) |
---|
2170 | (match-beginning 0))) |
---|
2171 | ;; Skip a block of included text. |
---|
2172 | (end-fwd (and (goto-char start) |
---|
2173 | (re-search-forward ispell-message-start-skip |
---|
2174 | limit 'end) |
---|
2175 | (progn (beginning-of-line) |
---|
2176 | (point)))) |
---|
2177 | (end (or (and end-c end-fwd (min end-c end-fwd)) |
---|
2178 | end-c end-fwd |
---|
2179 | ;; defalut to limit of text. |
---|
2180 | (marker-position limit)))) |
---|
2181 | (goto-char start) |
---|
2182 | (ispell-region start end) |
---|
2183 | (if (and end-fwd (= end end-fwd)) |
---|
2184 | (progn |
---|
2185 | (goto-char end) |
---|
2186 | (re-search-forward ispell-message-end-skip limit 'end)) |
---|
2187 | (goto-char end))))) |
---|
2188 | (set-marker limit nil)))) |
---|
2189 | |
---|
2190 | |
---|
2191 | (defun ispell-non-empty-string (string) |
---|
2192 | (if (or (not string) (string-equal string "")) |
---|
2193 | "\\'\\`" ; An unmatchable string if string is null. |
---|
2194 | (regexp-quote string))) |
---|
2195 | |
---|
2196 | |
---|
2197 | ;;; ********************************************************************** |
---|
2198 | ;;; Buffer Local Functions |
---|
2199 | ;;; ********************************************************************** |
---|
2200 | |
---|
2201 | |
---|
2202 | (defun ispell-accept-buffer-local-defs () |
---|
2203 | "Load all buffer-local information, restarting ispell when necessary." |
---|
2204 | (ispell-buffer-local-dict) ; May kill ispell-process. |
---|
2205 | (ispell-buffer-local-words) ; Will initialize ispell-process. |
---|
2206 | (ispell-buffer-local-parsing)) |
---|
2207 | |
---|
2208 | |
---|
2209 | (defun ispell-buffer-local-parsing () |
---|
2210 | "Place Ispell into parsing mode for this buffer. |
---|
2211 | Overrides the default parsing mode. |
---|
2212 | Includes latex/nroff modes and extended character mode." |
---|
2213 | ;; (ispell-init-process) must already be called. |
---|
2214 | (process-send-string ispell-process "!\n") ; Put process in terse mode. |
---|
2215 | ;; We assume all major modes with "tex-mode" in them should use latex parsing |
---|
2216 | (if (or (and (eq ispell-parser 'use-mode-name) |
---|
2217 | (string-match "[Tt][Ee][Xx]-mode" (symbol-name major-mode))) |
---|
2218 | (eq ispell-parser 'tex)) |
---|
2219 | (process-send-string ispell-process "+\n") ; set ispell mode to tex |
---|
2220 | (process-send-string ispell-process "-\n")) ; set mode to normal (nroff) |
---|
2221 | ;; Hard-wire test for SGML & HTML mode. |
---|
2222 | (setq ispell-skip-sgml (memq major-mode '(sgml-mode html-mode))) |
---|
2223 | ;; Set default extended character mode for given buffer, if any. |
---|
2224 | (let ((extended-char-mode (ispell-get-extended-character-mode))) |
---|
2225 | (if extended-char-mode |
---|
2226 | (process-send-string ispell-process (concat extended-char-mode "\n")))) |
---|
2227 | ;; Set buffer-local parsing mode and extended character mode, if specified. |
---|
2228 | (save-excursion |
---|
2229 | (goto-char (point-min)) |
---|
2230 | ;; Uses last valid definition |
---|
2231 | (while (search-forward ispell-parsing-keyword nil t) |
---|
2232 | (let ((end (save-excursion (end-of-line) (point))) |
---|
2233 | (case-fold-search t) |
---|
2234 | string) |
---|
2235 | (while (re-search-forward " *\\([^ \"]+\\)" end t) |
---|
2236 | ;; space separated definitions. |
---|
2237 | (setq string (buffer-substring (match-beginning 1) (match-end 1))) |
---|
2238 | (cond ((string-match "latex-mode" string) |
---|
2239 | (process-send-string ispell-process "+\n~tex\n")) |
---|
2240 | ((string-match "nroff-mode" string) |
---|
2241 | (process-send-string ispell-process "-\n~nroff")) |
---|
2242 | ((string-match "~" string) ; Set extended character mode. |
---|
2243 | (process-send-string ispell-process (concat string "\n"))) |
---|
2244 | (t (message "Illegal Ispell Parsing argument!") |
---|
2245 | (sit-for 2)))))))) |
---|
2246 | |
---|
2247 | |
---|
2248 | ;;; Can kill the current ispell process |
---|
2249 | |
---|
2250 | (defun ispell-buffer-local-dict () |
---|
2251 | "Initializes local dictionary. |
---|
2252 | When a dictionary is defined in the buffer (see variable |
---|
2253 | `ispell-dictionary-keyword'), it will override the local setting |
---|
2254 | from \\[ispell-change-dictionary]. |
---|
2255 | Both should not be used to define a buffer-local dictionary." |
---|
2256 | (save-excursion |
---|
2257 | (goto-char (point-min)) |
---|
2258 | (let (end) |
---|
2259 | ;; Override the local variable definition. |
---|
2260 | ;; Uses last valid definition. |
---|
2261 | (while (search-forward ispell-dictionary-keyword nil t) |
---|
2262 | (setq end (save-excursion (end-of-line) (point))) |
---|
2263 | (if (re-search-forward " *\\([^ \"]+\\)" end t) |
---|
2264 | (setq ispell-local-dictionary |
---|
2265 | (buffer-substring (match-beginning 1) (match-end 1))))) |
---|
2266 | (goto-char (point-min)) |
---|
2267 | (while (search-forward ispell-pdict-keyword nil t) |
---|
2268 | (setq end (save-excursion (end-of-line) (point))) |
---|
2269 | (if (re-search-forward " *\\([^ \"]+\\)" end t) |
---|
2270 | (setq ispell-local-pdict |
---|
2271 | (buffer-substring (match-beginning 1) (match-end 1))))))) |
---|
2272 | ;; Reload if new personal dictionary defined. |
---|
2273 | (if (and ispell-local-pdict |
---|
2274 | (not (equal ispell-local-pdict ispell-personal-dictionary))) |
---|
2275 | (progn |
---|
2276 | (ispell-kill-ispell t) |
---|
2277 | (setq ispell-personal-dictionary ispell-local-pdict))) |
---|
2278 | ;; Reload if new dictionary defined. |
---|
2279 | (if (and ispell-local-dictionary |
---|
2280 | (not (equal ispell-local-dictionary ispell-dictionary))) |
---|
2281 | (ispell-change-dictionary ispell-local-dictionary))) |
---|
2282 | |
---|
2283 | |
---|
2284 | (defun ispell-buffer-local-words () |
---|
2285 | "Loads the buffer-local dictionary in the current buffer." |
---|
2286 | (if (and ispell-buffer-local-name |
---|
2287 | (not (equal ispell-buffer-local-name (buffer-name)))) |
---|
2288 | (progn |
---|
2289 | (ispell-kill-ispell t) |
---|
2290 | (setq ispell-buffer-local-name nil))) |
---|
2291 | (ispell-init-process) |
---|
2292 | (save-excursion |
---|
2293 | (goto-char (point-min)) |
---|
2294 | (while (search-forward ispell-words-keyword nil t) |
---|
2295 | (or ispell-buffer-local-name |
---|
2296 | (setq ispell-buffer-local-name (buffer-name))) |
---|
2297 | (let ((end (save-excursion (end-of-line) (point))) |
---|
2298 | string) |
---|
2299 | ;; buffer-local words separated by a space, and can contain |
---|
2300 | ;; any character other than a space. |
---|
2301 | (while (re-search-forward " *\\([^ ]+\\)" end t) |
---|
2302 | (setq string (buffer-substring (match-beginning 1) (match-end 1))) |
---|
2303 | (process-send-string ispell-process (concat "@" string "\n"))))))) |
---|
2304 | |
---|
2305 | |
---|
2306 | ;;; returns optionally adjusted region-end-point. |
---|
2307 | |
---|
2308 | (defun ispell-add-per-file-word-list (word &optional reg-end) |
---|
2309 | "Adds new word to the per-file word list." |
---|
2310 | (or ispell-buffer-local-name |
---|
2311 | (setq ispell-buffer-local-name (buffer-name))) |
---|
2312 | (if (null reg-end) |
---|
2313 | (setq reg-end 0)) |
---|
2314 | (save-excursion |
---|
2315 | (goto-char (point-min)) |
---|
2316 | (let (case-fold-search line-okay search done string) |
---|
2317 | (while (not done) |
---|
2318 | (setq search (search-forward ispell-words-keyword nil 'move) |
---|
2319 | line-okay (< (+ (length word) 1 ; 1 for space after word.. |
---|
2320 | (progn (end-of-line) (current-column))) |
---|
2321 | 80)) |
---|
2322 | (if (or (and search line-okay) |
---|
2323 | (null search)) |
---|
2324 | (progn |
---|
2325 | (setq done t) |
---|
2326 | (if (null search) |
---|
2327 | (progn |
---|
2328 | (open-line 1) |
---|
2329 | (setq string (concat comment-start " " |
---|
2330 | ispell-words-keyword)) |
---|
2331 | ;; in case the keyword is in the middle of the file.... |
---|
2332 | (if (> reg-end (point)) |
---|
2333 | (setq reg-end (+ reg-end (length string)))) |
---|
2334 | (insert string) |
---|
2335 | (if (and comment-end (not (equal "" comment-end))) |
---|
2336 | (save-excursion |
---|
2337 | (open-line 1) |
---|
2338 | (forward-line 1) |
---|
2339 | (insert comment-end))))) |
---|
2340 | (if (> reg-end (point)) |
---|
2341 | (setq reg-end (+ 1 reg-end (length word)))) |
---|
2342 | (insert (concat " " word))))))) |
---|
2343 | reg-end) |
---|
2344 | |
---|
2345 | |
---|
2346 | (defconst ispell-version "2.37 -- Tue Jun 13 12:05:28 EDT 1995") |
---|
2347 | |
---|
2348 | (provide 'ispell) |
---|
2349 | |
---|
2350 | |
---|
2351 | ;;; LOCAL VARIABLES AND BUFFER-LOCAL VALUE EXAMPLES. |
---|
2352 | |
---|
2353 | ;;; Local Variable options: |
---|
2354 | ;;; mode: name(-mode) |
---|
2355 | ;;; eval: expression |
---|
2356 | ;;; local-variable: value |
---|
2357 | |
---|
2358 | ;;; The following sets the buffer local dictionary to english! |
---|
2359 | |
---|
2360 | ;;; Local Variables: |
---|
2361 | ;;; mode: emacs-lisp |
---|
2362 | ;;; comment-column: 40 |
---|
2363 | ;;; ispell-local-dictionary: "english" |
---|
2364 | ;;; End: |
---|
2365 | |
---|
2366 | |
---|
2367 | ;;; MORE EXAMPLES OF ISPELL BUFFER-LOCAL VALUES |
---|
2368 | |
---|
2369 | ;;; The following places this file in nroff parsing and extended char modes. |
---|
2370 | ;;; Local IspellParsing: nroff-mode ~nroff |
---|
2371 | ;;; Change IspellDict to IspellDict: to enable the following line. |
---|
2372 | ;;; Local IspellDict english |
---|
2373 | ;;; Change IspellPersDict to IspellPersDict: to enable the following line. |
---|
2374 | ;;; Local IspellPersDict ~/.ispell_lisp |
---|
2375 | ;;; The following were automatically generated by ispell using the 'A' command: |
---|
2376 | ; LocalWords: ispell ispell-highlight-p ispell-check-comments query-replace |
---|
2377 | ; LocalWords: ispell-query-replace-choices ispell-skip-tib non-nil tib |
---|
2378 | ; LocalWords: regexps ispell-tib-ref-beginning ispell-tib-ref-end |
---|
2379 | |
---|
2380 | ;; ispell.el ends here |
---|
2381 | |
---|