comparison lisp/textmodes/ispell.el @ 51151:fe11e703042b

Summary: MIME support added for e-mail processing that skips encoded regions. Allow user to skip saving Fcc messages with large attachments. Fixed region skipping bug with multi-line comments - e.g. tex $ regions spanning multiple lines. Added support for postscript and uuencoded regions. Redundant dictionary file names purged. Dictionary definition field name changed from "Character Set" to "Coding System". Fixed bug in reloading dictionaries. Modified headers to reflect new version. XEmacs menu now adds customize item. (ispell-check-version): No longer an aliased function. Returns library path if not called interactively. Variable `temporary-file-directory' protected if not loaded. (check-ispell-version): Now the alias for `ispell-check-version'. (ispell-message-fcc-skip): New variable that determines if and when to query about saving Fcc copy of message if an attachment is large. (ispell-skip-html): Declared buffer-local. (ispell-local-dictionary-alist): Docstring expanded. Tag name changed from "Character Set" to "Coding System". (ispell-dictionary-alist-1): Removed redundant command-line option to load brasileiro, british, and castellano dictionary files. (ispell-dictionary-alist-2): Removed redundant command-line option to load czech dictionary file. (ispell-dictionary-alist-3): Moved francais-tex here. (ispell-dictionary-alist-4): Removed german and german8 dictionaries. The deutsch ones are the correct definitions. `nederlands' and `nederlands8' dictionaries moved here. (ispell-dictionary-alist-5): `polish' and `portugues' dictionaries moved here. Removed redundant command-line option to `norsk' and `portugues'. (ispell-dictionary-alist-6): Removed redundant command-line option to load `russian' and `slovak' dictionary files. (ispell-dictionary-alist): Tag name changed from "Character Set" to "Coding System". (ispell-version): Updated to 3.6. (ispell-library-directory): Calls non-deprecated function. (ispell-valid-dictionary-list): New function returning all valid dictionaries on machine. (ispell-checking-message): Documentation string improved. (ispell-skip-region-alist): Added uuencoded and postscript region skipping. Improved http/e-mail/file regexp to not match `/.\w'. (ispell-html-skip-alists): New variable for html region support. (ispell-send-string): Removed redundant xemacs check. (ispell-word): Fix spelling error in documentation string, added extent information to support highlighting in ispell-minor-mode. (ispell-command-loop): Disable horizontal scrollbar in XEmacs choices buffer. (ispell-show-choices): Directly select `choices-window'. (ispell-help): Use default buffer size for electric help. (ispell-adjusted-window-height): Correct for xemacs detection. (ispell-start-process): Don't double specify dictionary file name. (ispell-init-process): Set `ispell-library-path' each call. (ispell-change-dictionary): Now only completes valid dictionaries. (ispell-region): Add support for MIME region skipping and Fcc message query for large attachments. (ispell-begin-skip-region-regexp): Add documentation string. Added message support and cleaned up code for generic and html regions. (ispell-begin-skip-region): Function is now requires alist argument. (ispell-begin-tex-skip-regexp): Added comments and support improved html and message regions. (ispell-skip-region-list): New function for MIME and region skipping. (ispell-tex-arg-end): Add documentation string. (ispell-ignore-fcc): New function to query saving Fcc message. (ispell-skip-region): Calculate alist for key match dynamically, html skipping pushed to alists. (ispell-get-line): Add support for multi-line comment regions. (ispell): Check that variables to continue spelling are bound. (ispell-message-text-end): Postscript and uuencoded regions now supported as MIME regions, rather than as end-of-message region. (ispell-mime-multipartp): New function supporting MIME. (ispell-mime-skip-part): New function supporting MIME. (ispell-message): Add MIME support. (ispell-buffer-local-parsing): Variable `ispell-skip-html' now local. (ispell-buffer-local-dict): Fixed bug for detecting and reloading new dictionary.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 22 May 2003 21:34:00 +0000
parents f4923c2899b6
children 1ffb07fde6de
comparison
equal deleted inserted replaced
51150:61009a4befe6 51151:fe11e703042b
2 2
3 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 3 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 4
5 ;; Author: Ken Stevens <k.stevens@ieee.org> 5 ;; Author: Ken Stevens <k.stevens@ieee.org>
6 ;; Maintainer: Ken Stevens <k.stevens@ieee.org> 6 ;; Maintainer: Ken Stevens <k.stevens@ieee.org>
7 ;; Stevens Mod Date: Fri Aug 4 09:41:50 PDT 2000 7 ;; Stevens Mod Date: Mon Jan 7 12:32:44 PST 2003
8 ;; Stevens Revision: 3.4 8 ;; Stevens Revision: 3.6
9 ;; Status : Release with 3.1.12+ and 3.2.0+ ispell. 9 ;; Status : Release with 3.1.12+ and 3.2.0+ ispell.
10 ;; Bug Reports : ispell-el-bugs@itcorp.com 10 ;; Bug Reports : ispell-el-bugs@itcorp.com
11 ;; Web Site : http://kdstevens.com/~stevens/ispell-page.html 11 ;; Web Site : http://kdstevens.com/~stevens/ispell-page.html
12 ;; Keywords: unix wp 12 ;; Keywords: unix wp
13 13
126 ;; can cause misalignment errors. 126 ;; can cause misalignment errors.
127 127
128 ;; HISTORY 128 ;; HISTORY
129 129
130 ;; Modifications made in latest versions: 130 ;; Modifications made in latest versions:
131
132 ;; Revision 3.6 2003/01/07 12:32:44 kss
133 ;; Removed extra -d LIB in dictionary defs. (Pavel Janik)
134 ;; Filtered process calls with duplicate dictionary entries.
135 ;; Fixed bug where message-text-end is inside a mime skipped region.
136 ;; Minor fixes to get ispell menus right in XEmacs
137 ;; Fixed skip regexp so it doesn't match stuff like `/.\w'.
138 ;; Detecting dictionary change not working. Fixed. kss
139 ;; function `ispell-change-dictionary' now only completes valid dicts.
140
141 ;; Revision 3.5 2001/7/11 18:43:57 kss
142 ;; Added fix for aspell to work in XEmacs (ispell-check-version).
143 ;; Added Portuguese dictionary definition.
144 ;; New feature: MIME mail message support, Fcc support.
145 ;; Bug fix: retain comment syntax on lines with region skipping. (TeX $ bug...)
146 ;; Improved allocation for graphic mode lines. (Miles Bader)
147 ;; Support -v flag for old versions of aspell. (Eli Zaretskii)
148 ;; Clear minibuffer on ^G from ispell-help (Tak Ota)
131 149
132 ;; Revision 3.4 2000/8/4 09:41:50 kss 150 ;; Revision 3.4 2000/8/4 09:41:50 kss
133 ;; Support new color display functions. 151 ;; Support new color display functions.
134 ;; Fixed misalignment offset bug when replacing a string after a shift made. 152 ;; Fixed misalignment offset bug when replacing a string after a shift made.
135 ;; Set to standard Author/Maintainer heading, 153 ;; Set to standard Author/Maintainer heading,
201 219
202 (if (not (fboundp 'buffer-substring-no-properties)) 220 (if (not (fboundp 'buffer-substring-no-properties))
203 (defun buffer-substring-no-properties (start end) 221 (defun buffer-substring-no-properties (start end)
204 (buffer-substring start end))) 222 (buffer-substring start end)))
205 223
206 (defalias 'ispell-check-version 'check-ispell-version) 224 (defalias 'check-ispell-version 'ispell-check-version)
207 225
208 ;;; ********************************************************************** 226 ;;; **********************************************************************
209 ;;; The following variables should be set according to personal preference 227 ;;; The following variables should be set according to personal preference
210 ;;; and location of binaries: 228 ;;; and location of binaries:
211 ;;; ********************************************************************** 229 ;;; **********************************************************************
306 (\"^To:[^\\n,]+\\\\.de[ \\t\\n,>]\" . \"deutsch8\"))" 324 (\"^To:[^\\n,]+\\\\.de[ \\t\\n,>]\" . \"deutsch8\"))"
307 :type '(repeat (cons regexp string)) 325 :type '(repeat (cons regexp string))
308 :group 'ispell) 326 :group 'ispell)
309 327
310 328
329 (defcustom ispell-message-fcc-skip 50000
330 "*Query before saving Fcc message copy if attachment larger than this value.
331 Always stores Fcc copy of message when nil."
332 :type '(choice integer (const :tag "off" nil))
333 :group 'ispell)
334
335
311 (defcustom ispell-grep-command "egrep" 336 (defcustom ispell-grep-command "egrep"
312 "Name of the grep command for search processes." 337 "Name of the grep command for search processes."
313 :type 'string 338 :type 'string
314 :group 'ispell) 339 :group 'ispell)
315 340
443 buffer's major mode." 468 buffer's major mode."
444 :type '(choice (const :tag "always" t) (const :tag "never" nil) 469 :type '(choice (const :tag "always" t) (const :tag "never" nil)
445 (const :tag "use-mode-name" use-mode-name)) 470 (const :tag "use-mode-name" use-mode-name))
446 :group 'ispell) 471 :group 'ispell)
447 472
473 (make-variable-buffer-local 'ispell-skip-html)
474
448 475
449 ;;; Define definitions here only for personal dictionaries. 476 ;;; Define definitions here only for personal dictionaries.
450 ;;;###autoload 477 ;;;###autoload
451 (defcustom ispell-local-dictionary-alist nil 478 (defcustom ispell-local-dictionary-alist nil
452 "*Contains local or customized dictionary definitions. 479 "*Contains local or customized dictionary definitions.
453 See `ispell-dictionary-alist'." 480
481 These will override the values in `ispell-dictionary-alist'.
482
483 Customization changes made to `ispell-dictionary-alist' will not operate
484 over emacs sessions. To make permanent changes to your dictionary
485 definitions, you will need to make your changes in this variable, save,
486 and then re-start emacs."
454 :type '(repeat (list (choice :tag "Dictionary" 487 :type '(repeat (list (choice :tag "Dictionary"
455 (string :tag "Dictionary name") 488 (string :tag "Dictionary name")
456 (const :tag "default" nil)) 489 (const :tag "default" nil))
457 (regexp :tag "Case characters") 490 (regexp :tag "Case characters")
458 (regexp :tag "Non case characters") 491 (regexp :tag "Non case characters")
463 (choice :tag "Extended character mode" 496 (choice :tag "Extended character mode"
464 (const "~tex") (const "~plaintex") 497 (const "~tex") (const "~plaintex")
465 (const "~nroff") (const "~list") 498 (const "~nroff") (const "~list")
466 (const "~latin1") (const "~latin3") 499 (const "~latin1") (const "~latin3")
467 (const :tag "default" nil)) 500 (const :tag "default" nil))
468 (choice :tag "Character set" 501 (choice :tag "Coding system"
469 (const iso-8859-1) 502 (const iso-8859-1)
470 (const iso-8859-2) 503 (const iso-8859-2)
471 (const koi8-r)))) 504 (const koi8-r))))
472 :group 'ispell) 505 :group 'ispell)
473 506
483 ("american" ; Yankee English 516 ("american" ; Yankee English
484 "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1) 517 "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
485 ("brasileiro" ; Brazilian mode 518 ("brasileiro" ; Brazilian mode
486 "[A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" 519 "[A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]"
487 "[^A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" 520 "[^A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]"
488 "[']" nil ("-d" "brasileiro") nil iso-8859-1) 521 "[']" nil nil nil iso-8859-1)
489 ("british" ; British version 522 ("british" ; British version
490 "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B" "-d" "british") nil iso-8859-1) 523 "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
491 ("castellano" ; Spanish mode 524 ("castellano" ; Spanish mode
492 "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" 525 "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
493 "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" 526 "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
494 "[-]" nil ("-B" "-d" "castellano") "~tex" iso-8859-1) 527 "[-]" nil ("-B") "~tex" iso-8859-1)
495 ("castellano8" ; 8 bit Spanish mode 528 ("castellano8" ; 8 bit Spanish mode
496 "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" 529 "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
497 "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" 530 "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
498 "[-]" nil ("-B" "-d" "castellano") "~latin1" iso-8859-1))) 531 "[-]" nil ("-B" "-d" "castellano") "~latin1" iso-8859-1)))
499 532
503 (setq 536 (setq
504 ispell-dictionary-alist-2 537 ispell-dictionary-alist-2
505 '(("czech" 538 '(("czech"
506 "[A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" 539 "[A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]"
507 "[^A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" 540 "[^A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]"
508 "" nil ("-B" "-d" "czech") nil iso-8859-2) 541 "" nil ("-B") nil iso-8859-2)
509 ("dansk" ; Dansk.aff 542 ("dansk" ; Dansk.aff
510 "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]" 543 "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]"
511 "[']" nil ("-C") nil iso-8859-1) 544 "[']" nil ("-C") nil iso-8859-1)
512 ("deutsch" ; Deutsch.aff 545 ("deutsch" ; Deutsch.aff
513 "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) 546 "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1)
533 ("francais7" 566 ("francais7"
534 "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil iso-8859-1) 567 "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil iso-8859-1)
535 ("francais" ; Francais.aff 568 ("francais" ; Francais.aff
536 "[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]" 569 "[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]"
537 "[^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]" 570 "[^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]"
538 "[-']" t nil "~list" iso-8859-1))) 571 "[-']" t nil "~list" iso-8859-1)
572 ("francais-tex" ; Francais.aff
573 "[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\\]"
574 "[^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\\]"
575 "[-'^`\"]" t nil "~tex" iso-8859-1)))
539 576
540 577
541 ;;; Fourth part of dictionary, shortened for loaddefs.el 578 ;;; Fourth part of dictionary, shortened for loaddefs.el
542 ;;;###autoload 579 ;;;###autoload
543 (setq 580 (setq
544 ispell-dictionary-alist-4 581 ispell-dictionary-alist-4
545 '(("francais-tex" ; Francais.aff 582 '(("german" ; german.aff
546 "[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\\]"
547 "[^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\\]"
548 "[-'^`\"]" t nil "~tex" iso-8859-1)
549 ("german" ; german.aff
550 "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) 583 "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1)
551 ("german8" 584 ("german8" ; german.aff
552 "[a-zA-Z\304\326\334\344\366\337\374]" 585 "[a-zA-Z\304\326\334\344\366\337\374]"
553 "[^a-zA-Z\304\326\334\344\366\337\374]" 586 "[^a-zA-Z\304\326\334\344\366\337\374]"
554 "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1) 587 "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1)
555 ("italiano" ; Italian.aff 588 ("italiano" ; Italian.aff
556 "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" 589 "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]"
557 "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" 590 "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]"
558 "[-]" nil ("-B" "-d" "italian") "~tex" iso-8859-1))) 591 "[-]" nil ("-B" "-d" "italian") "~tex" iso-8859-1)
559 592 ("nederlands" ; Nederlands.aff
560
561 ;;; Fifth part of dictionary, shortened for loaddefs.el
562 ;;;###autoload
563 (setq
564 ispell-dictionary-alist-5
565 '(("nederlands" ; Nederlands.aff
566 "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" 593 "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
567 "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" 594 "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
568 "[']" t ("-C") nil iso-8859-1) 595 "[']" t ("-C") nil iso-8859-1)
569 ("nederlands8" ; Dutch8.aff 596 ("nederlands8" ; Dutch8.aff
570 "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" 597 "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
571 "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" 598 "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
572 "[']" t ("-C") nil iso-8859-1) 599 "[']" t ("-C") nil iso-8859-1)))
573 ("norsk" ; 8 bit Norwegian mode 600
601
602 ;;; Fifth part of dictionary, shortened for loaddefs.el
603 ;;;###autoload
604 (setq
605 ispell-dictionary-alist-5
606 '(("norsk" ; 8 bit Norwegian mode
574 "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" 607 "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]"
575 "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" 608 "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]"
576 "[\"]" nil ("-d" "norsk") "~list" iso-8859-1) 609 "[\"]" nil nil "~list" iso-8859-1)
577 ("norsk7-tex" ; 7 bit Norwegian TeX mode 610 ("norsk7-tex" ; 7 bit Norwegian TeX mode
578 "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" 611 "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]"
579 "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1))) 612 "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1)
613 ("polish" ; Polish mode
614 "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
615 "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
616 "" nil nil nil iso-8859-2)
617 ("portugues" ; Portuguese mode
618 "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
619 "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
620 "[']" t ("-C") "~latin1" iso-8859-1)))
580 621
581 622
582 ;;; Sixth part of dictionary, shortened for loaddefs.el 623 ;;; Sixth part of dictionary, shortened for loaddefs.el
583 ;;;###autoload 624 ;;;###autoload
584 (setq 625 (setq
585 ispell-dictionary-alist-6 626 ispell-dictionary-alist-6
586 ;; include Russian iso character set too? 627 ;; include Russian iso coding system too?
587 ;; "[']" t ("-d" "russian") "~latin1" iso-8859-1 628 ;; "[']" t ("-d" "russian") "~latin1" iso-8859-1
588 '(("polish" ; polish mode 629 '(("russian" ; Russian.aff (KOI8-R charset)
589 "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
590 "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
591 "" nil ( "-d" "polish") nil iso-8859-2)
592 ("russian" ; Russian.aff (KOI8-R charset)
593 "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" 630 "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]"
594 "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" 631 "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]"
595 "" nil ("-d" "russian") nil koi8-r) 632 "" nil nil nil koi8-r)
633 ("slovak" ; Slovakian
634 "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
635 "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
636 "" nil ("-B") nil iso-8859-2)
596 ("svenska" ; Swedish mode 637 ("svenska" ; Swedish mode
597 "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" 638 "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
598 "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" 639 "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
599 "[']" nil ("-C") "~list" iso-8859-1) 640 "[']" nil ("-C") "~list" iso-8859-1)))
600 ("portugues" 641
601 "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
602 "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
603 "[']" t ("-C" "-d" "portugues") "~latin1" iso-8859-1)
604 ("slovak"
605 "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
606 "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
607 "" nil ("-B" "-d" "slovak") nil iso-8859-2)))
608 642
609 ;;;###autoload 643 ;;;###autoload
610 (defcustom ispell-dictionary-alist 644 (defcustom ispell-dictionary-alist
611 (append ispell-local-dictionary-alist ; dictionary customizations 645 (append ispell-local-dictionary-alist ; dictionary customizations
612 ispell-dictionary-alist-1 ispell-dictionary-alist-2 646 ispell-dictionary-alist-1 ispell-dictionary-alist-2
670 (choice :tag "Extended character mode" 704 (choice :tag "Extended character mode"
671 (const "~tex") (const "~plaintex") 705 (const "~tex") (const "~plaintex")
672 (const "~nroff") (const "~list") 706 (const "~nroff") (const "~list")
673 (const "~latin1") (const "~latin3") 707 (const "~latin1") (const "~latin3")
674 (const :tag "default" nil)) 708 (const :tag "default" nil))
675 (choice :tag "Character set" 709 (choice :tag "Coding System"
676 (const iso-8859-1) 710 (const iso-8859-1)
677 (const iso-8859-2) 711 (const iso-8859-2)
678 (const koi8-r)))) 712 (const koi8-r))))
679 :group 'ispell) 713 :group 'ispell)
680 714
699 (defconst ispell-required-version '(3 1 12) 733 (defconst ispell-required-version '(3 1 12)
700 "Ispell versions with which this version of ispell.el is known to work.") 734 "Ispell versions with which this version of ispell.el is known to work.")
701 (defvar ispell-offset -1 735 (defvar ispell-offset -1
702 "Offset that maps protocol differences between ispell 3.1 versions.") 736 "Offset that maps protocol differences between ispell 3.1 versions.")
703 737
704 (defconst ispell-version "ispell.el 3.4 -- Fri Aug 4 09:41:50 PDT 2000") 738 (defconst ispell-version "ispell.el 3.6 - 7-Jan-2003")
705 739
706 740
707 (defun check-ispell-version (&optional interactivep) 741 (defun ispell-check-version (&optional interactivep)
708 "Ensure that `ispell-program-name' is valid and the correct version. 742 "Ensure that `ispell-program-name' is valid and the correct version.
709 Returns version number if called interactively. 743 Returns version number if called interactively.
710 Otherwise returns the library directory name, if that is defined." 744 Otherwise returns the library directory name, if that is defined."
711 ;; This is a little wasteful as we actually launch ispell twice: once 745 ;; This is a little wasteful as we actually launch ispell twice: once
712 ;; to make sure it's the right version, and once for real. But people 746 ;; to make sure it's the right version, and once for real. But people
717 ;; themselves on startup. 751 ;; themselves on startup.
718 (interactive "p") 752 (interactive "p")
719 (let ((case-fold-search-val case-fold-search) 753 (let ((case-fold-search-val case-fold-search)
720 ;; avoid bugs when syntax of `.' changes in various default modes 754 ;; avoid bugs when syntax of `.' changes in various default modes
721 (default-major-mode 'fundamental-mode) 755 (default-major-mode 'fundamental-mode)
722 (default-directory temporary-file-directory) 756 (default-directory (or (and (boundp 'temporary-file-directory)
757 temporary-file-directory)
758 default-directory))
723 result status) 759 result status)
724 (save-excursion 760 (save-excursion
725 (let ((buf (get-buffer " *ispell-tmp*"))) 761 (let ((buf (get-buffer " *ispell-tmp*")))
726 (if buf (kill-buffer buf))) 762 (if buf (kill-buffer buf)))
727 (set-buffer (get-buffer-create " *ispell-tmp*")) 763 (set-buffer (get-buffer-create " *ispell-tmp*"))
735 (file-name-nondirectory ispell-program-name))) 771 (file-name-nondirectory ispell-program-name)))
736 ;; Assume anything that isn't `aspell' is Ispell. 772 ;; Assume anything that isn't `aspell' is Ispell.
737 (if (string-match "\\`aspell" speller) "-v" "-vv")))) 773 (if (string-match "\\`aspell" speller) "-v" "-vv"))))
738 (goto-char (point-min)) 774 (goto-char (point-min))
739 (if interactivep 775 (if interactivep
776 ;; report version information of ispell and ispell.el
740 (progn 777 (progn
741 (end-of-line) 778 (end-of-line)
742 (setq result (concat (buffer-substring-no-properties (point-min) 779 (setq result (concat (buffer-substring-no-properties (point-min)
743 (point)) 780 (point))
744 ", " 781 ", "
805 (and (not ispell-menu-map) 842 (and (not ispell-menu-map)
806 (not (featurep 'xemacs)) 843 (not (featurep 'xemacs))
807 'reload)) 844 'reload))
808 845
809 (defvar ispell-library-directory (condition-case () 846 (defvar ispell-library-directory (condition-case ()
810 (check-ispell-version) 847 (ispell-check-version)
811 (error nil)) 848 (error nil))
812 "Directory where ispell dictionaries reside.") 849 "Directory where ispell dictionaries reside.")
813 850
814 (defvar ispell-process nil 851 (defvar ispell-process nil
815 "The process object for Ispell.") 852 "The process object for Ispell.")
821 ;;(fboundp 'set-process-filter) 858 ;;(fboundp 'set-process-filter)
822 ;;(fboundp 'process-kill-without-query) 859 ;;(fboundp 'process-kill-without-query)
823 ) 860 )
824 "Non-nil means that the OS supports asynchronous processes.") 861 "Non-nil means that the OS supports asynchronous processes.")
825 862
863 (defun ispell-valid-dictionary-list ()
864 "Returns a list of valid dictionaries.
865 The variable `ispell-library-directory' defines the library location."
866 (let ((dicts ispell-dictionary-alist)
867 (dict-list (cons "default" nil))
868 name load-dict)
869 (dolist (dict dicts)
870 (setq name (car dict)
871 load-dict (car (cdr (member "-d" (nth 5 dict)))))
872 ;; Include if the dictionary is in the library, or dir not defined.
873 (if (and
874 name
875 ;; include all dictionaries if lib directory not known.
876 (or (not ispell-library-directory)
877 (file-exists-p (concat ispell-library-directory
878 "/" name ".hash"))
879 (file-exists-p (concat ispell-library-directory "/" name ".has"))
880 (and load-dict
881 (or (file-exists-p (concat ispell-library-directory
882 "/" load-dict ".hash"))
883 (file-exists-p (concat ispell-library-directory
884 "/" load-dict ".has"))))))
885 (setq dict-list (cons name dict-list))))
886 dict-list))
887
888
826 ;;;###autoload 889 ;;;###autoload
827 (if ispell-menu-map-needed 890 (if ispell-menu-map-needed
828 (let ((dicts (reverse (cons (cons "default" nil) ispell-dictionary-alist))) 891 (let ((dicts (if (fboundp 'ispell-valid-dictionary-list)
829 (dir (if (boundp 'ispell-library-directory) ispell-library-directory)) 892 (ispell-valid-dictionary-list)
830 (dict-map (make-sparse-keymap "Dictionaries")) 893 (mapcar (lambda (x) (or (car x) "default"))
831 name load-dict) 894 ispell-dictionary-alist)))
895 (dict-map (make-sparse-keymap "Dictionaries")))
832 (setq ispell-menu-map (make-sparse-keymap "Spell")) 896 (setq ispell-menu-map (make-sparse-keymap "Spell"))
833 ;; add the dictionaries to the bottom of the list. 897 ;; add the dictionaries to the bottom of the list.
834 (define-key ispell-menu-map [default] 898 (if (not dicts)
835 '("Select Default Dict" 899 (define-key ispell-menu-map [default]
836 "Dictionary for which Ispell was configured" 900 '("Select Default Dict"
837 . (lambda () (interactive) 901 "Dictionary for which Ispell was configured"
838 (ispell-change-dictionary "default")))) 902 . (lambda () (interactive)
903 (ispell-change-dictionary "default")))))
839 (fset 'ispell-dict-map dict-map) 904 (fset 'ispell-dict-map dict-map)
840 (define-key ispell-menu-map [dictionaries] 905 (define-key ispell-menu-map [dictionaries]
841 `(menu-item "Select Dict" ispell-dict-map)) 906 `(menu-item "Select Dict" ispell-dict-map))
842 (dolist (dict dicts) 907 (dolist (name dicts)
843 (setq name (car dict) 908 (define-key dict-map (vector (intern name))
844 load-dict (car (cdr (member "-d" (nth 5 dict))))) 909 (cons (concat "Select " (capitalize name) " Dict")
845 (cond ((not (stringp name))) 910 `(lambda () (interactive)
846 ((or (not dir) ; load all if library dir not defined 911 (ispell-change-dictionary ,name)))))))
847 (file-exists-p (concat dir "/" name ".hash"))
848 (file-exists-p (concat dir "/" name ".has"))
849 (and load-dict
850 (or (file-exists-p (concat dir "/" load-dict ".hash"))
851 (file-exists-p (concat dir "/" load-dict ".has")))))
852 (define-key dict-map (vector (intern name))
853 (cons (concat "Select " (capitalize name) " Dict")
854 `(lambda () (interactive)
855 (ispell-change-dictionary ,name)))))))))
856
857 912
858 ;;; define commands in menu in opposite order you want them to appear. 913 ;;; define commands in menu in opposite order you want them to appear.
859 ;;;###autoload 914 ;;;###autoload
860 (if ispell-menu-map-needed 915 (if ispell-menu-map-needed
861 (progn 916 (progn
926 (fset 'ispell-menu-map (symbol-value 'ispell-menu-map)))) 981 (fset 'ispell-menu-map (symbol-value 'ispell-menu-map))))
927 982
928 ;;; XEmacs versions 19 & 20 983 ;;; XEmacs versions 19 & 20
929 (if (and (featurep 'xemacs) 984 (if (and (featurep 'xemacs)
930 (featurep 'menubar) 985 (featurep 'menubar)
931 (null ispell-menu-xemacs) 986 ;;(null ispell-menu-xemacs)
932 (not (and (boundp 'infodock-version) infodock-version))) 987 (not (and (boundp 'infodock-version) infodock-version)))
933 (let ((dicts (cons (cons "default" nil) ispell-dictionary-alist)) 988 (let ((dicts (if (fboundp 'ispell-valid-dictionary-list)
989 (reverse (ispell-valid-dictionary-list))))
934 (current-menubar (or current-menubar default-menubar)) 990 (current-menubar (or current-menubar default-menubar))
935 (menu 991 (menu
936 '(["Help" (describe-function 'ispell-help) t] 992 '(["Help" (describe-function 'ispell-help) t]
937 ;;["Help" (popup-menu ispell-help-list) t] 993 ;;["Help" (popup-menu ispell-help-list) t]
938 ["Check Message" ispell-message t] 994 ["Check Message" ispell-message t]
942 ["Check Region" ispell-region (or (not zmacs-regions) (mark))] 998 ["Check Region" ispell-region (or (not zmacs-regions) (mark))]
943 ["Continue Check" ispell-continue t] 999 ["Continue Check" ispell-continue t]
944 ["Complete Word Frag"ispell-complete-word-interior-frag t] 1000 ["Complete Word Frag"ispell-complete-word-interior-frag t]
945 ["Complete Word" ispell-complete-word t] 1001 ["Complete Word" ispell-complete-word t]
946 ["Kill Process" ispell-kill-ispell t] 1002 ["Kill Process" ispell-kill-ispell t]
1003 ["Customize..." (customize-group 'ispell) t]
1004 ;; flyspell-mode may not be bound...
1005 ;;["flyspell" flyspell-mode
1006 ;; :style toggle :selected flyspell-mode ]
947 "-" 1007 "-"
948 ["Save Personal Dict"(ispell-pdict-save t t) t] 1008 ["Save Personal Dict"(ispell-pdict-save t t) t]
949 ["Change Dictionary" ispell-change-dictionary t] 1009 ["Change Dictionary" ispell-change-dictionary t])))
950 ["Select Default" (ispell-change-dictionary "default") t])) 1010 (if (null dicts)
951 name load-dict) 1011 (setq dicts (cons "default" nil)))
952 (while dicts 1012 (dolist (name dicts)
953 (setq name (car (car dicts)) 1013 (setq menu (append menu
954 load-dict (car (cdr (member "-d" (nth 5 (car dicts))))) 1014 (list
955 dicts (cdr dicts)) 1015 (vector
956 ;; Include if the dictionary is in the library, or dir not defined. 1016 (concat "Select " (capitalize name))
957 (if (and (stringp name) 1017 (list 'ispell-change-dictionary name)
958 (or (not ispell-library-directory) 1018 t)))))
959 (file-exists-p (concat ispell-library-directory "/"
960 name ".hash"))
961 (file-exists-p (concat ispell-library-directory "/"
962 name ".has"))
963 (and load-dict
964 (or (file-exists-p (concat ispell-library-directory "/"
965 load-dict ".hash"))
966 (file-exists-p (concat ispell-library-directory "/"
967 load-dict ".has"))))))
968 (setq menu (append menu
969 (list
970 (vector (concat "Select " (capitalize name))
971 (list 'ispell-change-dictionary name)
972 t))))))
973 (setq ispell-menu-xemacs menu) 1019 (setq ispell-menu-xemacs menu)
974 (if current-menubar 1020 (if current-menubar
975 (progn 1021 (progn
976 (delete-menu-item '("Edit" "Spell")) ; in case already defined 1022 (if (car (find-menu-item current-menubar '("Cmds")))
977 (add-menu '("Edit") "Spell" ispell-menu-xemacs))))) 1023 (progn
1024 ;; XEmacs 21.2
1025 (delete-menu-item '("Cmds" "Spell-Check"))
1026 (add-menu '("Cmds") "Spell-Check" ispell-menu-xemacs))
1027 ;; previous
1028 (delete-menu-item '("Edit" "Spell")) ; in case already defined
1029 (add-menu '("Edit") "Spell" ispell-menu-xemacs))))))
978 1030
979 ;;; Allow incrementing characters as integers in XEmacs 20 1031 ;;; Allow incrementing characters as integers in XEmacs 20
980 (if (and (featurep 'xemacs) 1032 (if (and (featurep 'xemacs)
981 (fboundp 'int-char)) 1033 (fboundp 'int-char))
982 (fset 'ispell-int-char 'int-char) 1034 (fset 'ispell-int-char 'int-char)
1058 1110
1059 (defvar ispell-recursive-edit-marker (make-marker) 1111 (defvar ispell-recursive-edit-marker (make-marker)
1060 "Marker for return point from recursive edit.") 1112 "Marker for return point from recursive edit.")
1061 1113
1062 (defvar ispell-checking-message nil 1114 (defvar ispell-checking-message nil
1063 "Non-nil when we're checking a mail message.") 1115 "Non-nil when we're checking a mail message.
1116 Set to the MIME boundary locations when checking messages.")
1064 1117
1065 (defconst ispell-choices-buffer "*Choices*") 1118 (defconst ispell-choices-buffer "*Choices*")
1066 1119
1067 (defvar ispell-overlay nil "Overlay variable for Ispell highlighting.") 1120 (defvar ispell-overlay nil "Overlay variable for Ispell highlighting.")
1068 1121
1098 '((ispell-words-keyword forward-line) 1151 '((ispell-words-keyword forward-line)
1099 (ispell-dictionary-keyword forward-line) 1152 (ispell-dictionary-keyword forward-line)
1100 (ispell-pdict-keyword forward-line) 1153 (ispell-pdict-keyword forward-line)
1101 (ispell-parsing-keyword forward-line) 1154 (ispell-parsing-keyword forward-line)
1102 ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*") 1155 ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*")
1103 ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage" . "^---* End of [Ff]orwarded [Mm]essage") 1156 ;; assume multiline uuencoded file? "\nM.*$"?
1157 ("^begin [0-9][0-9][0-9] [^ \t]+$" . "\nend\n")
1158 ("^%!PS-Adobe-[123].0" . "\n%%EOF\n")
1159 ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage"
1160 . "^---* End of [Ff]orwarded [Mm]essage")
1104 ;; Matches e-mail addresses, file names, http addresses, etc. The `-+' 1161 ;; Matches e-mail addresses, file names, http addresses, etc. The `-+'
1105 ;; pattern necessary for performance reasons when `-' part of word syntax. 1162 ;; pattern necessary for performance reasons when `-' part of word syntax.
1106 ("\\(-+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+\\)") 1163 ("\\(--+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
1164 ;; above checks /.\w sequences
1165 ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
1107 ;; This is a pretty complex regexp. It can be simplified to the following: 1166 ;; This is a pretty complex regexp. It can be simplified to the following:
1108 ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+" 1167 ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+"
1109 ;; but some valid text will be skipped, e.g. "his/her". This could be 1168 ;; but some valid text will be skipped, e.g. "his/her". This could be
1110 ;; fixed up (at the expense of a moderately more complex regexp) 1169 ;; fixed up (at the expense of a moderately more complex regexp)
1111 ;; by not allowing "/" to be the character which triggers the 1170 ;; by not allowing "/" to be the character which triggers the
1147 First list is used raw. 1206 First list is used raw.
1148 Second list has key placed inside \\begin{}. 1207 Second list has key placed inside \\begin{}.
1149 1208
1150 Delete or add any regions you want to be automatically selected 1209 Delete or add any regions you want to be automatically selected
1151 for skipping in latex mode.") 1210 for skipping in latex mode.")
1211
1212
1213 ;;;###autoload
1214 (defvar ispell-html-skip-alists
1215 '(("<[cC][oO][dD][eE]\\>[^>]*>" "</[cC][oO][dD][eE]*>")
1216 ("<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "</[sS][cC][rR][iI][pP][tT]>")
1217 ("<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "</[aA][pP][pP][lL][eE][tT]>")
1218 ("<[vV][eE][rR][bB]\\>[^>]*>" "<[vV][eE][rR][bB]\\>[^>]*>")
1219 ;;("<[tT][tT]\\>[^>]*>" "<[tT][tT]\\>[^>]*>")
1220 ("<[tT][tT]/" "/")
1221 ("<[^ \t\n>]" ">")
1222 ("&[^ \t\n;]" "[; \t\n]"))
1223 "*Lists of start and end keys to skip in HTML buffers.
1224 Same format as `ispell-skip-region-alist'
1225 Note - substrings of other matches must come last
1226 (e.g. \"<[tT][tT]/\" and \"<[^ \t\n>]\").")
1152 1227
1153 1228
1154 (defvar ispell-local-pdict ispell-personal-dictionary 1229 (defvar ispell-local-pdict ispell-personal-dictionary
1155 "A buffer local variable containing the current personal dictionary. 1230 "A buffer local variable containing the current personal dictionary.
1156 If non-nil, the value must be a string, which is a file name. 1231 If non-nil, the value must be a string, which is a file name.
1239 (setq prev-pos (point)) 1314 (setq prev-pos (point))
1240 (setq default-directory defdir) 1315 (setq default-directory defdir)
1241 (insert string) 1316 (insert string)
1242 (if (not (memq cmd cmds-to-defer)) 1317 (if (not (memq cmd cmds-to-defer))
1243 (let (coding-system-for-read coding-system-for-write status) 1318 (let (coding-system-for-read coding-system-for-write status)
1244 (if (or (featurep 'xemacs) 1319 (if (and (boundp 'enable-multibyte-characters)
1245 (and (boundp 'enable-multibyte-characters) 1320 enable-multibyte-characters)
1246 enable-multibyte-characters))
1247 (setq coding-system-for-read (ispell-get-coding-system) 1321 (setq coding-system-for-read (ispell-get-coding-system)
1248 coding-system-for-write (ispell-get-coding-system))) 1322 coding-system-for-write (ispell-get-coding-system)))
1249 (set-buffer output-buf) 1323 (set-buffer output-buf)
1250 (erase-buffer) 1324 (erase-buffer)
1251 (set-buffer session-buf) 1325 (set-buffer session-buf)
1311 1385
1312 This will check or reload the dictionary. Use \\[ispell-change-dictionary] 1386 This will check or reload the dictionary. Use \\[ispell-change-dictionary]
1313 or \\[ispell-region] to update the Ispell process. 1387 or \\[ispell-region] to update the Ispell process.
1314 1388
1315 return values: 1389 return values:
1316 nil word is correct or spelling is accpeted. 1390 nil word is correct or spelling is accepted.
1317 0 word is inserted into buffer-local definitions. 1391 0 word is inserted into buffer-local definitions.
1318 \"word\" word corrected from word list. 1392 \"word\" word corrected from word list.
1319 \(\"word\" arg\) word is hand entered. 1393 \(\"word\" arg\) word is hand entered.
1320 quit spell session exited." 1394 quit spell session exited."
1321 1395
1353 (error "Ispell and its process have different character maps") 1427 (error "Ispell and its process have different character maps")
1354 (setq poss (ispell-parse-output (car ispell-filter))))) 1428 (setq poss (ispell-parse-output (car ispell-filter)))))
1355 (cond ((eq poss t) 1429 (cond ((eq poss t)
1356 (or quietly 1430 (or quietly
1357 (message "%s is correct" 1431 (message "%s is correct"
1358 (funcall ispell-format-word word)))) 1432 (funcall ispell-format-word word)))
1433 (and (fboundp 'extent-at)
1434 (extent-at start)
1435 (delete-extent (extent-at start))))
1359 ((stringp poss) 1436 ((stringp poss)
1360 (or quietly 1437 (or quietly
1361 (message "%s is correct because of root %s" 1438 (message "%s is correct because of root %s"
1362 (funcall ispell-format-word word) 1439 (funcall ispell-format-word word)
1363 (funcall ispell-format-word poss)))) 1440 (funcall ispell-format-word poss)))
1441 (and (fboundp 'extent-at)
1442 (extent-at start)
1443 (delete-extent (extent-at start))))
1364 ((null poss) (message "Error in ispell process")) 1444 ((null poss) (message "Error in ispell process"))
1365 (ispell-check-only ; called from ispell minor mode. 1445 (ispell-check-only ; called from ispell minor mode.
1366 (beep) 1446 (if (fboundp 'make-extent)
1367 (message "%s is incorrect" (funcall ispell-format-word word))) 1447 (let ((ext (make-extent start end)))
1448 (set-extent-property ext 'face ispell-highlight-face)
1449 (set-extent-property ext 'priority 2000))
1450 (beep)
1451 (message "%s is incorrect"(funcall ispell-format-word word))))
1368 (t ; prompt for correct word. 1452 (t ; prompt for correct word.
1369 (save-window-excursion 1453 (save-window-excursion
1370 (setq replace (ispell-command-loop 1454 (setq replace (ispell-command-loop
1371 (car (cdr (cdr poss))) 1455 (car (cdr (cdr poss)))
1372 (car (cdr (cdr (cdr poss)))) 1456 (car (cdr (cdr (cdr poss))))
1514 1598
1515 ;; setup the *Choices* buffer with valid data. 1599 ;; setup the *Choices* buffer with valid data.
1516 (save-excursion 1600 (save-excursion
1517 (set-buffer (get-buffer-create ispell-choices-buffer)) 1601 (set-buffer (get-buffer-create ispell-choices-buffer))
1518 (setq mode-line-format (concat "-- %b -- word: " word)) 1602 (setq mode-line-format (concat "-- %b -- word: " word))
1519 ;; XEmacs: prevent thick modeline vs increasing height in overlay-window 1603 ;; XEmacs: no need for horizontal scrollbar in choices window
1520 ;;(and (fboundp 'set-specifier) 1604 (and (fboundp 'set-specifier)
1521 ;; (set-specifier has-modeline-p (cons (current-buffer) nil))) 1605 (boundp 'horizontal-scrollbar-visible-p)
1606 (set-specifier horizontal-scrollbar-visible-p nil
1607 (cons (current-buffer) nil)))
1522 (erase-buffer) 1608 (erase-buffer)
1523 (if guess 1609 (if guess
1524 (progn 1610 (progn
1525 (insert "Affix rules generate and capitalize " 1611 (insert "Affix rules generate and capitalize "
1526 "this word as shown below:\n\t") 1612 "this word as shown below:\n\t")
1787 (move-to-window-line 0) 1873 (move-to-window-line 0)
1788 (vertical-motion window-line) 1874 (vertical-motion window-line)
1789 (set-window-start (selected-window) 1875 (set-window-start (selected-window)
1790 (if (> (point) visible) visible (point))) 1876 (if (> (point) visible) visible (point)))
1791 (goto-char end) 1877 (goto-char end)
1792 (select-window (previous-window)) ; *Choices* window 1878 (select-window choices-window)
1793 (enlarge-window window-line))) 1879 (enlarge-window window-line)))
1794 ;; Overlay *Choices* window when it isn't showing 1880 ;; Overlay *Choices* window when it isn't showing
1795 (ispell-overlay-window (max line ispell-choices-win-default-height))) 1881 (ispell-overlay-window (max line ispell-choices-win-default-height)))
1796 (switch-to-buffer ispell-choices-buffer) 1882 (switch-to-buffer ispell-choices-buffer)
1797 (goto-char (point-min))))) 1883 (goto-char (point-min)))))
1828 (with-electric-help 1914 (with-electric-help
1829 (function (lambda () 1915 (function (lambda ()
1830 ;;This shouldn't be necessary: with-electric-help needs 1916 ;;This shouldn't be necessary: with-electric-help needs
1831 ;; an optional argument telling it about the smallest 1917 ;; an optional argument telling it about the smallest
1832 ;; acceptable window-height of the help buffer. 1918 ;; acceptable window-height of the help buffer.
1833 (if (< (window-height) 15) 1919 ;;(if (< (window-height) 15)
1834 (enlarge-window 1920 ;; (enlarge-window
1835 (- 15 (ispell-adjusted-window-height)))) 1921 ;; (- 15 (ispell-adjusted-window-height))))
1836 (princ "Selections are: 1922 (princ "Selections are:
1837 1923
1838 DIGIT: Replace the word with a digit offered in the *Choices* buffer. 1924 DIGIT: Replace the word with a digit offered in the *Choices* buffer.
1839 SPC: Accept word this time. 1925 SPC: Accept word this time.
1840 `i': Accept word and insert into private dictionary. 1926 `i': Accept word and insert into private dictionary.
2060 `window-height', but if the window has a mode-line is taller than a normal 2146 `window-height', but if the window has a mode-line is taller than a normal
2061 text line, the returned value may be smaller than that from 2147 text line, the returned value may be smaller than that from
2062 `window-height'." 2148 `window-height'."
2063 (cond ((fboundp 'window-text-height) 2149 (cond ((fboundp 'window-text-height)
2064 (1+ (window-text-height window))) 2150 (1+ (window-text-height window)))
2065 ((if (fboundp 'display-graphic-p) 2151 ((or (and (fboundp 'display-graphic-p) (display-graphic-p))
2066 (display-graphic-p) 2152 (and (featurep 'xemacs) window-system))
2067 (featurep 'xemacs))
2068 (1- (window-height window))) 2153 (1- (window-height window)))
2069 (t 2154 (t
2070 (window-height window)))) 2155 (window-height window))))
2071 2156
2072 (defun ispell-overlay-window (height) 2157 (defun ispell-overlay-window (height)
2169 (let (args) 2254 (let (args)
2170 ;; Local dictionary becomes the global dictionary in use. 2255 ;; Local dictionary becomes the global dictionary in use.
2171 (if ispell-local-dictionary 2256 (if ispell-local-dictionary
2172 (setq ispell-dictionary ispell-local-dictionary)) 2257 (setq ispell-dictionary ispell-local-dictionary))
2173 (setq args (ispell-get-ispell-args)) 2258 (setq args (ispell-get-ispell-args))
2174 (if ispell-dictionary ; use specified dictionary 2259 (if (and ispell-dictionary ; use specified dictionary
2260 (not (member "-d" args))) ; only define if not overridden
2175 (setq args 2261 (setq args
2176 (append (list "-d" ispell-dictionary) args))) 2262 (append (list "-d" ispell-dictionary) args)))
2177 (if ispell-personal-dictionary ; use specified pers dict 2263 (if ispell-personal-dictionary ; use specified pers dict
2178 (setq args 2264 (setq args
2179 (append args 2265 (append args
2207 (setq ispell-filter nil ispell-filter-continue nil) 2293 (setq ispell-filter nil ispell-filter-continue nil)
2208 ;; may need to restart to select new personal dictionary. 2294 ;; may need to restart to select new personal dictionary.
2209 (ispell-kill-ispell t) 2295 (ispell-kill-ispell t)
2210 (message "Starting new Ispell process...") 2296 (message "Starting new Ispell process...")
2211 (sit-for 0) 2297 (sit-for 0)
2212 (check-ispell-version) 2298 (setq ispell-library-directory (ispell-check-version)
2213 (setq ispell-process-directory default-directory 2299 ispell-process-directory default-directory
2214 ispell-process (ispell-start-process) 2300 ispell-process (ispell-start-process)
2215 ispell-filter nil 2301 ispell-filter nil
2216 ispell-filter-continue nil) 2302 ispell-filter-continue nil)
2217 (if ispell-async-processp 2303 (if ispell-async-processp
2218 (set-process-filter ispell-process 'ispell-filter)) 2304 (set-process-filter ispell-process 'ispell-filter))
2296 2382
2297 With prefix argument, set the default dictionary." 2383 With prefix argument, set the default dictionary."
2298 (interactive 2384 (interactive
2299 (list (completing-read 2385 (list (completing-read
2300 "Use new dictionary (RET for current, SPC to complete): " 2386 "Use new dictionary (RET for current, SPC to complete): "
2301 (cons (cons "default" nil) ispell-dictionary-alist) nil t) 2387 (and (fboundp 'ispell-valid-dictionary-list)
2388 (mapcar (lambda (x)(cons x nil)) (ispell-valid-dictionary-list)))
2389 nil t)
2302 current-prefix-arg)) 2390 current-prefix-arg))
2303 (if (equal dict "default") (setq dict nil)) 2391 (if (equal dict "default") (setq dict nil))
2304 ;; This relies on completing-read's bug of returning "" for no match 2392 ;; This relies on completing-read's bug of returning "" for no match
2305 (cond ((equal dict "") 2393 (cond ((equal dict "")
2306 (message "Using %s dictionary" 2394 (message "Using %s dictionary"
2340 Return nil if spell session is quit, 2428 Return nil if spell session is quit,
2341 otherwise returns shift offset amount for last line processed." 2429 otherwise returns shift offset amount for last line processed."
2342 (interactive "r") ; Don't flag errors on read-only bufs. 2430 (interactive "r") ; Don't flag errors on read-only bufs.
2343 (if (not recheckp) 2431 (if (not recheckp)
2344 (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc. 2432 (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc.
2433 (let ((skip-region-start (make-marker))
2434 (rstart (make-marker)))
2345 (unwind-protect 2435 (unwind-protect
2346 (save-excursion 2436 (save-excursion
2347 (message "Spell checking %s using %s dictionary..." 2437 (message "Spell checking %s using %s dictionary..."
2348 (if (and (= reg-start (point-min)) (= reg-end (point-max))) 2438 (if (and (= reg-start (point-min)) (= reg-end (point-max)))
2349 (buffer-name) "region") 2439 (buffer-name) "region")
2351 ;; Returns cursor to original location. 2441 ;; Returns cursor to original location.
2352 (save-window-excursion 2442 (save-window-excursion
2353 (goto-char reg-start) 2443 (goto-char reg-start)
2354 (let ((transient-mark-mode) 2444 (let ((transient-mark-mode)
2355 (case-fold-search case-fold-search) 2445 (case-fold-search case-fold-search)
2356 (skip-region-start (make-marker)) 2446 (query-fcc t)
2357 (skip-regexp (ispell-begin-skip-region-regexp)) 2447 in-comment key)
2358 (skip-alist ispell-skip-region-alist)
2359 key)
2360 (if (eq ispell-parser 'tex)
2361 (setq case-fold-search nil
2362 skip-alist
2363 (append (car ispell-tex-skip-alists)
2364 (car (cdr ispell-tex-skip-alists))
2365 skip-alist)))
2366 (let (message-log-max) 2448 (let (message-log-max)
2367 (message "searching for regions to skip")) 2449 (message "searching for regions to skip"))
2368 (if (re-search-forward skip-regexp reg-end t) 2450 (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t)
2369 (progn 2451 (progn
2370 (setq key (buffer-substring-no-properties 2452 (setq key (buffer-substring-no-properties
2371 (match-beginning 0) (match-end 0))) 2453 (match-beginning 0) (match-end 0)))
2372 (set-marker skip-region-start (- (point) (length key))) 2454 (set-marker skip-region-start (- (point) (length key)))
2373 (goto-char reg-start))) 2455 (goto-char reg-start)))
2374 (let (message-log-max) 2456 (let (message-log-max)
2375 (message "Continuing spelling check using %s dictionary..." 2457 (message "Continuing spelling check using %s dictionary..."
2376 (or ispell-dictionary "default"))) 2458 (or ispell-dictionary "default")))
2459 (set-marker rstart reg-start)
2377 (set-marker ispell-region-end reg-end) 2460 (set-marker ispell-region-end reg-end)
2378 (while (and (not ispell-quit) 2461 (while (and (not ispell-quit)
2379 (< (point) ispell-region-end)) 2462 (< (point) ispell-region-end))
2380 ;; spell-check region with skipping 2463 ;; spell-check region with skipping
2381 (if (and (marker-position skip-region-start) 2464 (if (and (marker-position skip-region-start)
2382 (<= skip-region-start (point))) 2465 (<= skip-region-start (point)))
2383 (progn 2466 (progn
2384 (ispell-skip-region key skip-alist) ; moves pt past region. 2467 ;; If region inside line comment, must keep comment start.
2385 (setq reg-start (point)) 2468 (setq in-comment (point)
2386 (if (and (< reg-start ispell-region-end) 2469 in-comment
2387 (re-search-forward skip-regexp 2470 (and comment-start
2388 ispell-region-end t)) 2471 (or (null comment-end) (string= "" comment-end))
2472 (save-excursion
2473 (beginning-of-line)
2474 (re-search-forward comment-start in-comment t))
2475 comment-start))
2476 ;; Can change skip-regexps (in ispell-message)
2477 (ispell-skip-region key) ; moves pt past region.
2478 (set-marker rstart (point))
2479 ;; check for saving large attachments...
2480 (setq query-fcc (and query-fcc
2481 (ispell-ignore-fcc skip-region-start
2482 rstart)))
2483 (if (and (< rstart ispell-region-end)
2484 (re-search-forward
2485 (ispell-begin-skip-region-regexp)
2486 ispell-region-end t))
2389 (progn 2487 (progn
2390 (setq key (buffer-substring-no-properties 2488 (setq key (buffer-substring-no-properties
2391 (car (match-data)) 2489 (car (match-data))
2392 (car (cdr (match-data))))) 2490 (car (cdr (match-data)))))
2393 (set-marker skip-region-start 2491 (set-marker skip-region-start
2394 (- (point) (length key))) 2492 (- (point) (length key)))
2395 (goto-char reg-start)) 2493 (goto-char rstart))
2396 (set-marker skip-region-start nil)))) 2494 (set-marker skip-region-start nil))))
2397 (setq reg-end (if (marker-position skip-region-start) 2495 (setq reg-end (max (point)
2398 (min skip-region-start ispell-region-end) 2496 (if (marker-position skip-region-start)
2399 (marker-position ispell-region-end))) 2497 (min skip-region-start ispell-region-end)
2498 (marker-position ispell-region-end))))
2400 (let* ((start (point)) 2499 (let* ((start (point))
2401 (end (save-excursion (end-of-line) (min (point) reg-end))) 2500 (end (save-excursion (end-of-line) (min (point) reg-end)))
2402 (string (ispell-get-line start end))) 2501 (string (ispell-get-line start end in-comment)))
2502 (if in-comment ; account for comment chars added
2503 (setq start (- start (length in-comment))
2504 in-comment nil))
2403 (setq end (point)) ; "end" tracks region retrieved. 2505 (setq end (point)) ; "end" tracks region retrieved.
2404 (if string ; there is something to spell check! 2506 (if string ; there is something to spell check!
2405 ;; (special start end) 2507 ;; (special start end)
2406 (setq shift (ispell-process-line string 2508 (setq shift (ispell-process-line string
2407 (and recheckp shift)))) 2509 (and recheckp shift))))
2411 (or shift 0))) 2513 (or shift 0)))
2412 ;; protected 2514 ;; protected
2413 (if (and (not (and recheckp ispell-keep-choices-win)) 2515 (if (and (not (and recheckp ispell-keep-choices-win))
2414 (get-buffer ispell-choices-buffer)) 2516 (get-buffer ispell-choices-buffer))
2415 (kill-buffer ispell-choices-buffer)) 2517 (kill-buffer ispell-choices-buffer))
2518 (set-marker skip-region-start nil)
2519 (set-marker rstart nil)
2416 (if ispell-quit 2520 (if ispell-quit
2417 (progn 2521 (progn
2418 ;; preserve or clear the region for ispell-continue. 2522 ;; preserve or clear the region for ispell-continue.
2419 (if (not (numberp ispell-quit)) 2523 (if (not (numberp ispell-quit))
2420 (set-marker ispell-region-end nil) 2524 (set-marker ispell-region-end nil)
2427 (error "Message send aborted"))) 2531 (error "Message send aborted")))
2428 (if (not recheckp) (setq ispell-quit nil))) 2532 (if (not recheckp) (setq ispell-quit nil)))
2429 (if (not recheckp) (set-marker ispell-region-end nil)) 2533 (if (not recheckp) (set-marker ispell-region-end nil))
2430 ;; Only save if successful exit. 2534 ;; Only save if successful exit.
2431 (ispell-pdict-save ispell-silently-savep) 2535 (ispell-pdict-save ispell-silently-savep)
2432 (message "Spell-checking done")))) 2536 (message "Spell-checking done")))))
2433 2537
2434 2538
2435 ;;; Creates the regexp for skipping a region.
2436 ;;; Makes the skip-regexp local for tex buffers adding in the
2437 ;;; tex expressions to skip as well.
2438 ;;; Call AFTER ispell-buffer-local-parsing.
2439 (defun ispell-begin-skip-region-regexp () 2539 (defun ispell-begin-skip-region-regexp ()
2440 (let ((skip-regexp (ispell-begin-skip-region))) 2540 "Returns a regexp of the search keys for region skipping.
2541 Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys.
2542 Must call after ispell-buffer-local-parsing due to dependence on mode."
2543 ;; start with regions generic to all buffers
2544 (let ((skip-regexp (ispell-begin-skip-region ispell-skip-region-alist)))
2545 ;; Comments
2441 (if (and (null ispell-check-comments) comment-start) 2546 (if (and (null ispell-check-comments) comment-start)
2442 (setq skip-regexp (concat (regexp-quote comment-start) "\\|" 2547 (setq skip-regexp (concat (regexp-quote comment-start) "\\|"
2443 skip-regexp))) 2548 skip-regexp)))
2444 (if (and (eq 'exclusive ispell-check-comments) comment-start) 2549 (if (and (eq 'exclusive ispell-check-comments) comment-start)
2550 ;; search from end of current comment to start of next comment.
2445 (setq skip-regexp (concat (if (string= "" comment-end) "^" 2551 (setq skip-regexp (concat (if (string= "" comment-end) "^"
2446 (regexp-quote comment-end)) 2552 (regexp-quote comment-end))
2447 "\\|" skip-regexp))) 2553 "\\|" skip-regexp)))
2554 ;; tib
2448 (if ispell-skip-tib 2555 (if ispell-skip-tib
2449 (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp))) 2556 (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp)))
2557 ;; html stuff
2450 (if ispell-skip-html 2558 (if ispell-skip-html
2451 (setq skip-regexp (concat "<[cC][oO][dD][eE]\\>[^>]*>" "\\|" 2559 (setq skip-regexp (concat
2452 "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "\\|" 2560 (ispell-begin-skip-region ispell-html-skip-alists)
2453 "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "\\|" 2561 "\\|"
2454 "<[vV][eE][rR][bB]\\>[^>]*>" "\\|" 2562 skip-regexp)))
2455 ;; "<[tT][tT]\\>[^>]*>" "\\|" 2563 ;; tex
2456 "<[tT][tT]/" "\\|"
2457 "<" "\\|"
2458 "&" "\\|"
2459 skip-regexp)))
2460 (if (eq ispell-parser 'tex) 2564 (if (eq ispell-parser 'tex)
2461 (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|" 2565 (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|"
2462 skip-regexp))) 2566 skip-regexp)))
2567 ;; messages
2568 (if (and ispell-checking-message
2569 (not (eq t ispell-checking-message)))
2570 (setq skip-regexp (concat
2571 (mapconcat (lambda (lst) (car lst))
2572 ispell-checking-message
2573 "\\|")
2574 "\\|"
2575 skip-regexp)))
2576
2577 ;; return new regexp
2463 skip-regexp)) 2578 skip-regexp))
2579
2580
2581 (defun ispell-begin-skip-region (skip-alist)
2582 "Regular expression for start of regions to skip generated from SKIP-ALIST.
2583 Each selection should be a key of SKIP-ALIST;
2584 otherwise, the current line is skipped."
2585 (mapconcat (lambda (lst) (if (stringp (car lst)) (car lst) (eval (car lst))))
2586 skip-alist
2587 "\\|"))
2464 2588
2465 2589
2466 (defun ispell-begin-tex-skip-regexp () 2590 (defun ispell-begin-tex-skip-regexp ()
2467 "Regular expression of tex commands to skip. 2591 "Regular expression of tex commands to skip.
2468 Generated from `ispell-tex-skip-alists'." 2592 Generated from `ispell-tex-skip-alists'."
2469 (concat 2593 (concat
2594 ;; raw tex keys
2470 (mapconcat (function (lambda (lst) (car lst))) 2595 (mapconcat (function (lambda (lst) (car lst)))
2471 (car ispell-tex-skip-alists) 2596 (car ispell-tex-skip-alists)
2472 "\\|") 2597 "\\|")
2473 "\\|" 2598 "\\|"
2599 ;; keys wrapped in begin{}
2474 (mapconcat (function (lambda (lst) 2600 (mapconcat (function (lambda (lst)
2475 (concat "\\\\begin[ \t\n]*{[ \t\n]*" 2601 (concat "\\\\begin[ \t\n]*{[ \t\n]*"
2476 (car lst) 2602 (car lst)
2477 "[ \t\n]*}"))) 2603 "[ \t\n]*}")))
2478 (car (cdr ispell-tex-skip-alists)) 2604 (car (cdr ispell-tex-skip-alists))
2479 "\\|"))) 2605 "\\|")))
2480 2606
2481 2607
2482 (defun ispell-begin-skip-region () 2608 (defun ispell-skip-region-list ()
2483 "Regular expression of regions to skip for all buffers. 2609 "Returns a list describing key and body regions to skip for this buffer.
2484 Each selection should be a key of `ispell-skip-region-alist'; 2610 Includes regions defined by `ispell-skip-region-alist', tex mode,
2485 otherwise, the current line is skipped." 2611 `ispell-html-skip-alists', and `ispell-checking-message'.
2486 (mapconcat (function (lambda (lst) (if (stringp (car lst)) (car lst) 2612 Manual checking must include comments and tib references.
2487 (eval (car lst))))) 2613 The list is of the form described by variable `ispell-skip-region-alist'.
2488 ispell-skip-region-alist 2614 Must call after `ispell-buffer-local-parsing' due to dependence on mode."
2489 "\\|")) 2615 (let ((skip-alist ispell-skip-region-alist))
2616 ;; only additional explicit region definition is tex.
2617 (if (eq ispell-parser 'tex)
2618 (setq case-fold-search nil
2619 skip-alist (append (car ispell-tex-skip-alists)
2620 (car (cdr ispell-tex-skip-alists))
2621 skip-alist)))
2622 (if ispell-skip-html
2623 (setq skip-alist (append ispell-html-skip-alists skip-alist)))
2624 (if (and ispell-checking-message
2625 (not (eq t ispell-checking-message)))
2626 (setq skip-alist (append ispell-checking-message skip-alist)))
2627 skip-alist))
2490 2628
2491 2629
2492 (defun ispell-tex-arg-end (&optional arg) 2630 (defun ispell-tex-arg-end (&optional arg)
2631 "Skip across ARG number of braces."
2493 (condition-case nil 2632 (condition-case nil
2494 (progn 2633 (progn
2495 (while (looking-at "[ \t\n]*\\[") (forward-sexp)) 2634 (while (looking-at "[ \t\n]*\\[") (forward-sexp))
2496 (forward-sexp (or arg 1))) 2635 (forward-sexp (or arg 1)))
2497 (error 2636 (error
2498 (message "error skipping s-expressions at point %d." (point)) 2637 (message "error skipping s-expressions at point %d." (point))
2499 (beep) 2638 (beep)
2500 (sit-for 2)))) 2639 (sit-for 2))))
2501 2640
2502 2641
2503 ;;; Skips to region-end from point, or a single line. 2642 (defun ispell-ignore-fcc (start end)
2504 ;;; Places point at end of region skipped. 2643 "Deletes the Fcc: message header when large attachments are included.
2505 (defun ispell-skip-region (key alist) 2644 Return value `nil' if file with large attachments are saved.
2645 This can be used to avoid multiple questions for multiple large attachments.
2646 Returns point to starting location afterwards."
2647 (let ((result t))
2648 (if (and ispell-checking-message ispell-message-fcc-skip)
2649 (if (< ispell-message-fcc-skip (- end start))
2650 (let (case-fold-search head-end)
2651 (goto-char (point-min))
2652 (setq head-end
2653 (or (re-search-forward
2654 (concat "^" (regexp-quote mail-header-separator) "$")
2655 nil t)
2656 (re-search-forward "^$" nil t)
2657 (point-min)))
2658 (goto-char (point-min))
2659 (if (re-search-forward "^Fcc:" head-end t)
2660 (if (y-or-n-p
2661 "Save copy of this message with large attachments? ")
2662 (setq result nil)
2663 (beginning-of-line)
2664 (kill-line 1)))
2665 (goto-char end))))
2666 result))
2667
2668
2669 (defun ispell-skip-region (key)
2670 "Skips across KEY and then to end of region.
2671 Key lookup determines region to skip.
2672 Point is placed at end of skipped region."
2506 ;; move over key to begin checking. 2673 ;; move over key to begin checking.
2507 (forward-char (length key)) 2674 (forward-char (length key))
2508 (let ((start (point)) 2675 (let ((start (point))
2676 ;; Regenerate each call... This function can change region definition.
2677 (alist (ispell-skip-region-list))
2509 alist-key null-skip) 2678 alist-key null-skip)
2510 (cond 2679 (cond
2511 ;; what about quoted comment, or comment inside strings? 2680 ;; what about quoted comment, or comment inside strings?
2512 ((and (null ispell-check-comments) comment-start 2681 ((and (null ispell-check-comments) comment-start
2513 (string= key comment-start)) 2682 (string= key comment-start))
2517 ((and (eq 'exclusive ispell-check-comments) comment-start 2686 ((and (eq 'exclusive ispell-check-comments) comment-start
2518 (string= key comment-end)) 2687 (string= key comment-end))
2519 (search-forward comment-start ispell-region-end :end)) 2688 (search-forward comment-start ispell-region-end :end))
2520 ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key)) 2689 ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key))
2521 (re-search-forward ispell-tib-ref-end ispell-region-end t)) 2690 (re-search-forward ispell-tib-ref-end ispell-region-end t))
2522 ((and ispell-skip-html (string-match "</" key))
2523 (search-forward ">" ispell-region-end t))
2524 ((and ispell-skip-html (string-match "<[cC][oO][dD][eE]\\>[^>]*>" key))
2525 (search-forward-regexp "</[cC][oO][dD][eE]>" ispell-region-end t))
2526 ((and ispell-skip-html
2527 (string-match "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" key))
2528 (search-forward-regexp "</[sS][cC][rR][iI][pP][tT]>" ispell-region-end t))
2529 ((and ispell-skip-html
2530 (string-match "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" key))
2531 (search-forward-regexp "</[aA][pP][pP][lL][eE][tT]>" ispell-region-end t))
2532 ((and ispell-skip-html (string-match "<[vV][eE][rR][bB]\\>[^>]*>" key))
2533 (search-forward-regexp "</[vV][eE][rR][bB]>" ispell-region-end t))
2534 ;;((and ispell-skip-html (string-match "<[tT][tT]\\>[^>]*>" key))
2535 ;; (search-forward-regexp "</[tT][tT]>" ispell-region-end t))
2536 ((and ispell-skip-html (string-match "<[tT][tT]/" key))
2537 (search-forward "/" ispell-region-end t))
2538 ((and ispell-skip-html (string-match "<" key))
2539 (search-forward ">" ispell-region-end t))
2540 ((and ispell-skip-html (string-match "&" key))
2541 (search-forward-regexp "[; \t\n]" ispell-region-end t))
2542 ;; markings from alist 2691 ;; markings from alist
2543 (t 2692 (t
2544 (while alist 2693 (while alist
2545 (setq alist-key (eval (car (car alist)))) 2694 (setq alist-key (eval (car (car alist))))
2546 (if (string-match alist-key key) 2695 (if (string-match alist-key key)
2549 (cond 2698 (cond
2550 ((null alist) (setq null-skip t)) ; done! Just skip key. 2699 ((null alist) (setq null-skip t)) ; done! Just skip key.
2551 ((not (consp alist)) 2700 ((not (consp alist))
2552 ;; Search past end of spell region to find this region end. 2701 ;; Search past end of spell region to find this region end.
2553 (re-search-forward (eval alist) (point-max) t)) 2702 (re-search-forward (eval alist) (point-max) t))
2554 ((consp alist) 2703 ((and (= 1 (length alist))
2555 (if (stringp alist) 2704 (stringp (car alist)))
2556 (re-search-forward alist (point-max) t) 2705 (re-search-forward (car alist) (point-max) t))
2557 (setq null-skip t) ; error handling in functions! 2706 (t
2558 (if (consp (cdr alist)) 2707 (setq null-skip t) ; error handling in functions!
2559 (apply (car alist) (cdr alist)) 2708 (if (consp (cdr alist))
2560 (funcall (car alist)))))) 2709 (apply (car alist) (cdr alist))
2710 (funcall (car alist)))))
2561 (setq alist nil)) 2711 (setq alist nil))
2562 (setq alist (cdr alist)))))) 2712 (setq alist (cdr alist))))))
2563 (if (and (= start (point)) (null null-skip)) 2713 (if (and (= start (point)) (null null-skip))
2564 (progn 2714 (progn
2565 (message "Matching region end for `%s' point %d not found" 2715 (message "Matching region end for `%s' point %d not found"
2568 (sit-for 2))))) 2718 (sit-for 2)))))
2569 2719
2570 2720
2571 ;;; Grab the next line of data. 2721 ;;; Grab the next line of data.
2572 ;;; Returns a string with the line data 2722 ;;; Returns a string with the line data
2573 (defun ispell-get-line (start end) 2723 (defun ispell-get-line (start end in-comment)
2574 (let ((ispell-casechars (ispell-get-casechars)) 2724 (let ((ispell-casechars (ispell-get-casechars))
2575 string) 2725 string)
2576 (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS 2726 (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS
2577 ((eolp) ; END OF LINE, just go to next line. 2727 ((eolp) ; END OF LINE, just go to next line.
2578 (forward-line)) 2728 (forward-line))
2579 ;;((looking-at "[-#@*+!%~^]") ; SKIP SPECIAL ISPELL CHARACTERS 2729 ;;((looking-at "[-#@*+!%~^]") ; SKIP SPECIAL ISPELL CHARACTERS
2580 ;; (forward-char 1)) ; not needed as quoted below. 2730 ;; (forward-char 1)) ; not needed as quoted below.
2581 ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS 2731 ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS
2582 (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS 2732 (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS
2583 (setq string (concat "^" (buffer-substring-no-properties start end) 2733 (setq string (concat "^" in-comment
2734 (buffer-substring-no-properties start end)
2584 "\n")) 2735 "\n"))
2585 (goto-char end)) 2736 (goto-char end))
2586 (t (goto-char end))) ; EMPTY LINE, skip it. 2737 (t (goto-char end))) ; EMPTY LINE, skip it.
2587 string)) 2738 string))
2588 2739
2635 2786
2636 ;; Alignment cannot be tracked and this error will occur when 2787 ;; Alignment cannot be tracked and this error will occur when
2637 ;; `query-replace' makes multiple corrections on the starting line. 2788 ;; `query-replace' makes multiple corrections on the starting line.
2638 (if (/= (+ word-len (point)) 2789 (if (/= (+ word-len (point))
2639 (progn 2790 (progn
2640 ;; NB: Search can fail with Mule character sets that don't 2791 ;; NB: Search can fail with Mule coding systems that don't
2641 ;; display properly. Ignore the error in this case? 2792 ;; display properly. Ignore the error in this case?
2642 (search-forward (car poss) (+ word-len (point)) t) 2793 (search-forward (car poss) (+ word-len (point)) t)
2643 (point))) 2794 (point)))
2644 ;; This occurs due to filter pipe problems 2795 ;; This occurs due to filter pipe problems
2645 (error (concat "Ispell misalignment: word " 2796 (error (concat "Ispell misalignment: word "
2879 Ispell dictionaries are not distributed with Emacs. If you are 3030 Ispell dictionaries are not distributed with Emacs. If you are
2880 looking for a dictionary, please see the distribution of the GNU ispell 3031 looking for a dictionary, please see the distribution of the GNU ispell
2881 program, or do an Internet search; there are various dictionaries 3032 program, or do an Internet search; there are various dictionaries
2882 available on the net." 3033 available on the net."
2883 (interactive) 3034 (interactive)
2884 (if (and transient-mark-mode mark-active) 3035 (if (and (boundp 'transient-mark-mode) transient-mark-mode
3036 (boundp 'mark-active) mark-active)
2885 (ispell-region (region-beginning) (region-end)) 3037 (ispell-region (region-beginning) (region-end))
2886 (ispell-buffer))) 3038 (ispell-buffer)))
2887 3039
2888 3040
2889 ;;; ********************************************************************** 3041 ;;; **********************************************************************
2944 3096
2945 3097
2946 ;;; ********************************************************************** 3098 ;;; **********************************************************************
2947 ;;; Ispell Message 3099 ;;; Ispell Message
2948 ;;; ********************************************************************** 3100 ;;; **********************************************************************
2949 ;;; Original from D. Quinlan, E. Bradford, A. Albert, and M. Ernst
2950
2951 3101
2952 (defvar ispell-message-text-end 3102 (defvar ispell-message-text-end
2953 (mapconcat (function identity) 3103 (mapconcat (function identity)
2954 '( 3104 '(
2955 ;; Don't spell check signatures 3105 ;; Don't spell check signatures
2956 "^-- $" 3106 "^-- $"
2957 ;; Matches postscript files. 3107 ;; Matches postscript files.
2958 "^%!PS-Adobe-[123].0" 3108 ;;"^%!PS-Adobe-[123].0"
2959 ;; Matches uuencoded text 3109 ;; Matches uuencoded text
2960 "^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" 3110 ;;"^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM"
2961 ;; Matches shell files (especially auto-decoding) 3111 ;; Matches shell files (especially auto-decoding)
2962 "^#! /bin/[ck]?sh" 3112 "^#! /bin/[ck]?sh"
2963 ;; Matches context difference listing 3113 ;; Matches context difference listing
2964 "\\(\\(^cd .*\n\\)?diff -c .*\\)?\n\\*\\*\\* .*\n--- .*\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*" 3114 "\\(\\(^cd .*\n\\)?diff -c .*\\)?\n\\*\\*\\* .*\n--- .*\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*"
2965 ;; Matches unidiff difference listing 3115 ;; Matches unidiff difference listing
2972 "*End of text which will be checked in `ispell-message'. 3122 "*End of text which will be checked in `ispell-message'.
2973 If it is a string, limit at first occurrence of that regular expression. 3123 If it is a string, limit at first occurrence of that regular expression.
2974 Otherwise, it must be a function which is called to get the limit.") 3124 Otherwise, it must be a function which is called to get the limit.")
2975 3125
2976 3126
3127 (defun ispell-mime-multipartp (&optional limit)
3128 "Return multipart message start boundary or nil if none."
3129 ;; caller must ensure `case-fold-search' is set to `t'
3130 (and
3131 (re-search-forward
3132 "Content-Type: *multipart/\\([^ \t\n]*;[ \t]*[\n]?[ \t]*\\)+boundary="
3133 limit t)
3134 (let (boundary)
3135 (if (looking-at "\"")
3136 (let (start)
3137 (forward-char)
3138 (setq start (point))
3139 (while (not (looking-at "\""))
3140 (forward-char 1))
3141 (setq boundary (buffer-substring-no-properties start (point))))
3142 (let ((start (point)))
3143 (while (looking-at "[-0-9a-zA-Z'()+_,./:=?]")
3144 (forward-char))
3145 (setq boundary (buffer-substring-no-properties start (point)))))
3146 (if (< (length boundary) 1)
3147 (setq boundary nil)
3148 (concat "--" boundary)))))
3149
3150
3151 (defun ispell-mime-skip-part (boundary)
3152 "Moves point across header, or entire MIME part if message is encoded.
3153 All specified types except `7bit' `8bit' and `quoted-printable' are considered
3154 encoded and therefore skipped. See rfc 1521, 2183, ...
3155 If no boundary is given, then entire message is skipped.
3156
3157 This starts one line ABOVE the MIME content messages, on the boundary marker,
3158 for operation with the generic region-skipping code.
3159 This places new MIME boundaries into variable `ispell-checking-message'."
3160 (forward-line) ; skip over boundary to headers
3161 (let ((save-case-fold-search case-fold-search)
3162 (continuep t)
3163 textp)
3164 (setq case-fold-search t
3165 ispell-skip-html nil)
3166 (while continuep
3167 (setq continuep nil)
3168 (if (looking-at "Content-Type: *text/")
3169 (progn
3170 (goto-char (match-end 0))
3171 (if (looking-at "html")
3172 (setq ispell-skip-html t))
3173 (setq textp t
3174 continuep t)
3175 (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t)
3176 (forward-line)))
3177 (if (looking-at "Content-Transfer-Encoding: *\\([^ \t\n]*\\)")
3178 (let ((match (buffer-substring (match-beginning 1) (match-end 1))))
3179 (setq textp (member (upcase match)
3180 ;; only spell check the following encodings:
3181 '("7BIT" "8BIT" "QUOTED-PRINTABLE" "BINARY"))
3182 continuep t)
3183 (goto-char (match-end 0))
3184 (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t)
3185 (forward-line)))
3186 ;; hierarchical boundary definition
3187 (if (looking-at "Content-Type: *multipart/")
3188 (let ((new-boundary (ispell-mime-multipartp)))
3189 (if (string-match new-boundary boundary)
3190 (setq continuep t)
3191 ;; first pass redefine skip function to include new boundary
3192 ;;(re-search-backward boundary nil t)
3193 (forward-line)
3194 (setq ispell-checking-message
3195 (cons
3196 (list new-boundary 'ispell-mime-skip-part new-boundary)
3197 (if (eq t ispell-checking-message) nil
3198 ispell-checking-message))
3199 textp t
3200 continuep t)))
3201 ;; Skip all MIME headers that don't affect spelling
3202 (if (looking-at "Content-[^ \t]*: *\\(.*;[ \t]*[\n]\\)*.*$")
3203 (progn
3204 (setq continuep t)
3205 (goto-char (match-end 0))
3206 (forward-line)))))
3207
3208 (setq case-fold-search save-case-fold-search)
3209 (if textp
3210 (point)
3211 ;; encoded message. Skip to boundary, or entire message.
3212 (if (not boundary)
3213 (goto-char (point-max))
3214 (re-search-forward boundary nil t)
3215 (beginning-of-line)
3216 (point)))))
3217
2977 3218
2978 ;;;###autoload 3219 ;;;###autoload
2979 (defun ispell-message () 3220 (defun ispell-message ()
2980 "Check the spelling of a mail message or news post. 3221 "Check the spelling of a mail message or news post.
2981 Don't check spelling of message headers except the Subject field. 3222 Don't check spelling of message headers except the Subject field.
2996 `news-reply-mode-hook' or `mail-mode-hook' the following lambda expression: 3237 `news-reply-mode-hook' or `mail-mode-hook' the following lambda expression:
2997 (function (lambda () (local-set-key \"\\C-ci\" 'ispell-message)))" 3238 (function (lambda () (local-set-key \"\\C-ci\" 'ispell-message)))"
2998 (interactive) 3239 (interactive)
2999 (save-excursion 3240 (save-excursion
3000 (goto-char (point-min)) 3241 (goto-char (point-min))
3001 (let* ( 3242 (let* (boundary mimep
3243 (ispell-skip-region-alist-save ispell-skip-region-alist)
3002 ;; Nil when message came from outside (eg calling emacs as editor) 3244 ;; Nil when message came from outside (eg calling emacs as editor)
3003 ;; Non-nil marker of end of headers. 3245 ;; Non-nil marker of end of headers.
3004 (internal-messagep 3246 (internal-messagep
3005 (re-search-forward 3247 (re-search-forward
3006 (concat "^" (regexp-quote mail-header-separator) "$") nil t)) 3248 (concat "^" (regexp-quote mail-header-separator) "$") nil t))
3021 (if (and (boundp 'mail-yank-prefix) mail-yank-prefix) 3263 (if (and (boundp 'mail-yank-prefix) mail-yank-prefix)
3022 (ispell-non-empty-string mail-yank-prefix) 3264 (ispell-non-empty-string mail-yank-prefix)
3023 " \\|\t")) 3265 " \\|\t"))
3024 (cite-regexp ;Prefix of quoted text 3266 (cite-regexp ;Prefix of quoted text
3025 (cond 3267 (cond
3026 ((functionp 'sc-cite-regexp) ; sc 3.0 3268 ((functionp 'sc-cite-regexp) ; sc 3.0
3027 (concat "\\(" (sc-cite-regexp) "\\)" "\\|" 3269 (concat "\\(" (sc-cite-regexp) "\\)" "\\|"
3028 (ispell-non-empty-string sc-reference-tag-string))) 3270 (ispell-non-empty-string sc-reference-tag-string)))
3029 ((boundp 'sc-cite-regexp) ; sc 2.3 3271 ((boundp 'sc-cite-regexp) ; sc 2.3
3030 (concat "\\(" sc-cite-regexp "\\)" "\\|" 3272 (concat "\\(" sc-cite-regexp "\\)" "\\|"
3031 (ispell-non-empty-string sc-reference-tag-string))) 3273 (ispell-non-empty-string sc-reference-tag-string)))
3032 ((or (equal major-mode 'news-reply-mode) ;GNUS 4 & below 3274 ((or (equal major-mode 'news-reply-mode) ;GNUS 4 & below
3033 (equal major-mode 'message-mode)) ;GNUS 5 3275 (equal major-mode 'message-mode)) ;GNUS 5
3034 (concat "In article <" "\\|" 3276 (concat "In article <" "\\|"
3066 3308
3067 (unwind-protect 3309 (unwind-protect
3068 (progn 3310 (progn
3069 ;; Spell check any original Subject: 3311 ;; Spell check any original Subject:
3070 (goto-char (point-min)) 3312 (goto-char (point-min))
3071 (setq case-fold-search t) 3313 (setq case-fold-search t
3314 mimep (re-search-forward "MIME-Version:" end-of-headers t))
3315 (goto-char (point-min))
3072 (if (re-search-forward "^Subject: *" end-of-headers t) 3316 (if (re-search-forward "^Subject: *" end-of-headers t)
3073 (progn 3317 (progn
3074 (goto-char (match-end 0)) 3318 (goto-char (match-end 0))
3075 (if (and (not (looking-at ".*Re\\>")) 3319 (if (and (not (looking-at ".*Re\\>"))
3076 (not (looking-at "\\["))) 3320 (not (looking-at "\\[")))
3080 (progn ;Tab-initiated continuation lns. 3324 (progn ;Tab-initiated continuation lns.
3081 (end-of-line) 3325 (end-of-line)
3082 (while (looking-at "\n[ \t]") 3326 (while (looking-at "\n[ \t]")
3083 (end-of-line 2)) 3327 (end-of-line 2))
3084 (point))))))) 3328 (point)))))))
3329 (if mimep
3330 (progn
3331 (goto-char (point-min))
3332 (setq boundary (ispell-mime-multipartp end-of-headers))))
3333 ;; Adjust message limit to MIME message if necessary.
3334 (and boundary
3335 (re-search-forward (concat boundary "--") nil t)
3336 (re-search-backward boundary nil t)
3337 (< (point) (marker-position limit))
3338 (set-marker limit (point)))
3339 (goto-char (point-min))
3340 ;; Select type or skip checking if this is a non-multipart message
3341 ;; Point moved to end of buffer if region is encoded.
3342 (if (and mimep (not boundary))
3343 (let (skip-regexp) ; protect from `ispell-mime-skip-part'
3344 (goto-char (point-min))
3345 (re-search-forward "Content-[^ \t]*:" end-of-headers t)
3346 (forward-line -1) ; following fn starts one line above
3347 (ispell-mime-skip-part nil)
3348 ;; if message-text-end region, limit may be less than point.
3349 (if (> (point) limit)
3350 (set-marker limit (point)))))
3351 (goto-char (max end-of-headers (point)))
3352 (forward-line 1)
3085 (setq case-fold-search old-case-fold-search) 3353 (setq case-fold-search old-case-fold-search)
3086 (goto-char end-of-headers) 3354 ;; Define MIME regions to skip.
3087 (forward-line 1) 3355 (if boundary
3356 (setq ispell-checking-message
3357 (list (list boundary 'ispell-mime-skip-part boundary))))
3088 (ispell-region (point) limit)) 3358 (ispell-region (point) limit))
3089 (set-marker end-of-headers nil) 3359 (set-marker end-of-headers nil)
3090 (set-marker limit nil))))) 3360 (set-marker limit nil)
3361 (setq ispell-skip-region-alist ispell-skip-region-alist-save
3362 ispell-skip-html nil
3363 case-fold-search old-case-fold-search)))))
3091 3364
3092 3365
3093 (defun ispell-non-empty-string (string) 3366 (defun ispell-non-empty-string (string)
3094 (if (or (not string) (string-equal string "")) 3367 (if (or (not string) (string-equal string ""))
3095 "\\'\\`" ; An unmatchable string if string is null. 3368 "\\'\\`" ; An unmatchable string if string is null.
3126 (if (not (eq ispell-parser 'tex)) 3399 (if (not (eq ispell-parser 'tex))
3127 (set (make-local-variable 'ispell-parser) 'tex))) 3400 (set (make-local-variable 'ispell-parser) 'tex)))
3128 (ispell-send-string "-\n")) ; set mode to normal (nroff) 3401 (ispell-send-string "-\n")) ; set mode to normal (nroff)
3129 ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value. 3402 ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value.
3130 (if (and ispell-skip-html (not (eq ispell-skip-html t))) 3403 (if (and ispell-skip-html (not (eq ispell-skip-html t)))
3131 (set (make-local-variable 'ispell-skip-html) 3404 (setq ispell-skip-html
3132 (not (null (string-match "sgml\\|html\\|xml" 3405 (not (null (string-match "sgml\\|html\\|xml"
3133 (downcase (symbol-name major-mode))))))) 3406 (downcase (symbol-name major-mode)))))))
3134 ;; Set default extended character mode for given buffer, if any. 3407 ;; Set default extended character mode for given buffer, if any.
3135 (let ((extended-char-mode (ispell-get-extended-character-mode))) 3408 (let ((extended-char-mode (ispell-get-extended-character-mode)))
3136 (if extended-char-mode 3409 (if extended-char-mode
3137 (ispell-send-string (concat extended-char-mode "\n")))) 3410 (ispell-send-string (concat extended-char-mode "\n"))))
3138 ;; Set buffer-local parsing mode and extended character mode, if specified. 3411 ;; Set buffer-local parsing mode and extended character mode, if specified.
3194 (not (equal ispell-local-pdict ispell-personal-dictionary))) 3467 (not (equal ispell-local-pdict ispell-personal-dictionary)))
3195 (progn 3468 (progn
3196 (ispell-kill-ispell t) 3469 (ispell-kill-ispell t)
3197 (setq ispell-personal-dictionary ispell-local-pdict))) 3470 (setq ispell-personal-dictionary ispell-local-pdict)))
3198 ;; Reload if new dictionary defined. 3471 ;; Reload if new dictionary defined.
3199 (if (and ispell-local-dictionary 3472 (if (not (equal ispell-local-dictionary ispell-dictionary))
3200 (not (equal ispell-local-dictionary ispell-dictionary)))
3201 (ispell-change-dictionary ispell-local-dictionary))) 3473 (ispell-change-dictionary ispell-local-dictionary)))
3202 3474
3203 3475
3204 (defun ispell-buffer-local-words () 3476 (defun ispell-buffer-local-words ()
3205 "Loads the buffer-local dictionary in the current buffer." 3477 "Loads the buffer-local dictionary in the current buffer."