Anonymous avatar Anonymous committed 7f01df7

Synch to ispell-3.0-beta

Comments (0)

Files changed (2)

 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 # Boston, MA 02111-1307, USA.
 
-VERSION = 1.04
-AUTHOR_VERSION = 2.37
+VERSION = 1.05
+AUTHOR_VERSION = 3.0beta
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = ispell
 PKG_TYPE = regular
-;;; ispell.el --- spell checking using Ispell
+;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: emacs-lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; GNU EMACS interface for International Ispell Version 3.1 by Geoff Kuenning.
+;;;
+;;;
+;;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+;;;
+;;;
+;;; Authors         : Ken Stevens <k.stevens@ieee.org>
+;;; Last Modified On: Wed Nov 12 03:08:53 1997
+;;; Update Revision : 3.0 beta
+;;; Syntax          : emacs-lisp
+;;; Status          : Release with 3.1.12+ ispell.
+;;; Version         : International Ispell Version 3.1 by Geoff Kuenning.
+;;; Bug Reports     : ispell-el-bugs@itcorp.com
+;;; Web Site        : http://kdstevens.com/~stevens/ispell-page.html
+;;;
+;;; Note: version numbers and time stamp are not updated
+;;;   when this file is edited for release with GNU emacs.
+;;;
+;;; This file is part of GNU Emacs.
+;;;
+;;; GNU Emacs is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2, or (at your option)
+;;; any later version.
+;;;
+;;; GNU Emacs is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Emacs; see the file COPYING.  If not, write to
+;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;;
+;;; Commentary:
+;;;
+;;; INSTRUCTIONS
+;;;
+;;;  This code contains a section of user-settable variables that you should
+;;; inspect prior to installation.  Look past the end of the history list.
+;;; Set them up for your locale and the preferences of the majority of the
+;;; users.  Otherwise the users may need to set a number of variables
+;;; themselves.
+;;;  You particularly may want to change the default dictionary for your
+;;; country and language.
+;;;
+;;;
+;;; To fully install this, add this file to your Emacs Lisp directory and
+;;; compile it with M-X byte-compile-file.  Then add the following to the
+;;; appropriate init file:
+;;;
+;;;  (autoload 'ispell-word "ispell"
+;;;    "Check the spelling of word in buffer." t)
+;;;  (global-set-key "\e$" 'ispell-word)
+;;;  (autoload 'ispell-region "ispell"
+;;;    "Check the spelling of region." t)
+;;;  (autoload 'ispell-buffer "ispell"
+;;;    "Check the spelling of buffer." t)
+;;;  (autoload 'ispell-complete-word "ispell"
+;;;    "Look up current word in dictionary and try to complete it." t)
+;;;  (autoload 'ispell-change-dictionary "ispell"
+;;;    "Change ispell dictionary." t)
+;;;  (autoload 'ispell-message "ispell"
+;;;    "Check spelling of mail message or news post.")
+;;;  (autoload 'ispell-minor-mode "ispell"
+;;;    "Toggle mode to automatically spell check words as they are typed in.")
+;;;
+;;;  Depending on the mail system you use, you may want to include these:
+;;;
+;;;  (add-hook 'news-inews-hook 'ispell-message)
+;;;  (add-hook 'mail-send-hook  'ispell-message)
+;;;  (add-hook 'mh-before-send-letter-hook 'ispell-message)
+;;;
+;;;
+;;; Ispell has a TeX parser and a nroff parser (the default).
+;;; The parsing is controlled by the variable ispell-parser.  Currently
+;;; it is just a "toggle" between TeX and nroff, but if more parsers are
+;;; added it will be updated.  See the variable description for more info.
+;;;
+;;;
+;;; TABLE OF CONTENTS
+;;;
+;;;   ispell-word
+;;;   ispell-region
+;;;   ispell-buffer
+;;;   ispell-message
+;;;   ispell-continue
+;;;   ispell-complete-word
+;;;   ispell-complete-word-interior-frag
+;;;   ispell-change-dictionary
+;;;   ispell-kill-ispell
+;;;   ispell-pdict-save
+;;;   ispell-skip-region-alist
+;;;
+;;; Commands in ispell-region:
+;;; Character replacement: Replace word with choice.  May query-replace.
+;;; ' ': Accept word this time.
+;;; 'i': Accept word and insert into private dictionary.
+;;; 'a': Accept word for this session.
+;;; 'A': Accept word and place in buffer-local dictionary.
+;;; 'r': Replace word with typed-in value.  Rechecked.
+;;; 'R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+;;; '?': Show these commands
+;;; 'x': Exit spelling buffer.  Move cursor to original point.
+;;; 'X': Exit spelling buffer.  Leaves cursor at the current point, and permits
+;;;      the check to be completed later.
+;;; 'q': Quit spelling session (Kills ispell process).
+;;; 'l': Look up typed-in replacement in alternate dictionary.  Wildcards okay.
+;;; 'u': Like 'i', but the word is lower-cased first.
+;;; 'm': Place entered value in personal dictionary, then recheck current word.
+;;; 'C-l': redraws screen
+;;; 'C-r': recursive edit
+;;; 'C-z': suspend emacs or iconify frame
+;;;
+;;; Buffer-Local features:
+;;; There are a number of buffer-local features that can be used to customize
+;;;  ispell for the current buffer.  This includes language dictionaries,
+;;;  personal dictionaries, parsing, and local word spellings.  Each of these
+;;;  local customizations are done either through local variables, or by
+;;;  including the keyword and argument(s) at the end of the buffer (usually
+;;;  prefixed by the comment characters).  See the end of this file for
+;;;  examples.  The local keywords and variables are:
+;;;
+;;;  ispell-dictionary-keyword   language-dictionary
+;;;      uses local variable ispell-local-dictionary
+;;;  ispell-pdict-keyword        personal-dictionary
+;;;      uses local variable ispell-local-pdict
+;;;  ispell-parsing-keyword      mode-arg extended-char-arg
+;;;  ispell-words-keyword        any number of local word spellings
+;;;
+;;; Region skipping:
+;;;  Place new regular expression definitions of regions you prefer not to
+;;;  spell check in `ispell-skip-region-alist'.  Mode-dependent features can
+;;;  be added to latex by modifying `ispell-tex-skip-alists'.
+;;;  `ispell-message' contains some custom skipping code for e-mail messages.
+;;;
+;;; BUGS:
+;;;  Highlighting in version 19 still doesn't work on tty's.
+;;;  On some versions of emacs, growing the minibuffer fails.
+;;;  Autoloading ispell can result in problems if you need to use a local or
+;;;    modified dictionary.  Place the following in your .emacs file to
+;;;    override the autoload definitions:
+;;;    (setq ispell-dictionary-alist (cons '(dictionary ...)
+;;;					   ispell-dictionary-alist))
+;;;    (setq ispell-menu-map nil)
+;;;    (load-library "ispell")
+;;;  
+;;;
+;;; HISTORY
+;;;
+;;; Revision 3.0  1997/11/12 03:08:53	stevens
+;;; Recursive editing now supported.  Castellano dictionary entry added.
+;;; Cleanup documentation, ispell-word, ispell-minor-mode,
+;;; and buffer-local definition searches. Added electric-help.
+;;; Tty highlighting can use block cursor to highlight. ispell-show-choices
+;;; uses framepop.  ispell-skip-sgml locally set by buffer-mode.
+;;; replaced \b with \< and \> for bug on some machines.
+;;; restored emacs-18 support, buffer-local-words more robust.
+;;; check-ispell-version prints loaded versions, xemacs modeline hiding
+;;; American dictionary added, added error interaction in process.
+;;; fixed skipping error in ispell-message, improved sgml skipping (Dave Love)
+;;; Message dictionary selection (Christoph Wedler)
+;;; fixed alignment error in ispell-process-line (error as 1st word, menu)
+;;; support unsplitable frames, skip everything but comments
+;;; ispell message body now checked as one region (Ethan Bradford)
+;;; added customize support
+;;;
+;;; Revision 2.37  1995/6/13 12:05:28	stevens
+;;; Removed autoload from ispell-dictionary-alist. *choices* mode-line shows
+;;; misspelled word.  Block skip for pgp & forwarded messages added.
+;;; RMS: the autoload changes had problems and I removed them.
+;;;
+;;; Revision 2.36  1995/2/6 17:39:38	stevens
+;;; Properly adjust screen with different ispell-choices-win-default-height
+;;; settings.  Skips SGML entity references.
+;;;
+;;; Revision 2.35  1995/1/13 14:16:46	stevens
+;;; Skips SGML tags, ispell-change-dictionary fix for add-hook, assure personal
+;;; dictionary is saved when called from the menu
+;;;
+;;; Revision 2.34  1994/12/08 13:17:41  stevens
+;;; Interaction corrected to function with all 3.1 ispell versions.
+;;;
+;;; Revision 2.33  1994/11/24 02:31:20  stevens
+;;; Repaired bug introduced in 2.32 that corrupts buffers when correcting.
+;;; Improved buffer scrolling. Non-destructive buffer selections allowed.
+;;;
+;;; Revision 2.32  1994/10/31 21:10:08  geoff
+;;; Many revisions accepted from RMS/FSF.  I think (though I don't know) that
+;;; this represents an 'official' version.
+;;;
+;;; Revision 2.31  1994/5/31 10:18:17  stevens
+;;; Repaired comments.  buffer-local commands executed in `ispell-word' now.
+;;; German dictionary described for extended character mode.  Dict messages.
+;;;
+;;; Revision 2.30  1994/5/20 22:18:36  stevens
+;;; Continue ispell from ispell-word, C-z functionality fixed.
+;;;
+;;; Revision 2.29  1994/5/12 09:44:33  stevens
+;;; Restored ispell-use-ptys-p, ispell-message aborts sends with interrupt.
+;;; defined function ispell
+;;;
+;;; Revision 2.28  1994/4/28 16:24:40  stevens
+;;; Window checking when ispell-message put on gnus-inews-article-hook jwz.
+;;; prefixed ispell- to highlight functions and horiz-scroll function.
+;;; Try and respect case of word in ispell-complete-word.
+;;; Ignore non-char events.  Ispell-use-ptys-p commented out. Lucid menu.
+;;; Better interrupt handling.  ispell-message improvements from Ethan.
+;;;
+;;; Revision 2.27
+;;; version 18 explicit C-g handling disabled as it didn't work. Added
+;;; ispell-extra-args for ispell customization (jwz)
+;;;
+;;; Revision 2.26  1994/2/15 16:11:14  stevens
+;;; name changes for copyright assignment.  Added word-frags in complete-word.
+;;; Horizontal scroll (John Conover). Query-replace matches words now.  bugs.
+;;;
+;;; Revision 2.25
+;;; minor mods, upgraded ispell-message
+;;;
+;;; Revision 2.24
+;;; query-replace more robust, messages, defaults, ispell-change-dict.
+;;;
+;;; Revision 2.23  1993/11/22 23:47:03  stevens
+;;; ispell-message, Fixed highlighting, added menu-bar, fixed ispell-help, ...
+;;;
+;;; Revision 2.22
+;;; Added 'u' command.  Fixed default in ispell-local-dictionary.
+;;; fixed affix rules display.  Tib skipping more robust.  Contributions by
+;;; Per Abraham (parser selection), Denis Howe, and Eberhard Mattes.
+;;;
+;;; Revision 2.21  1993/06/30 14:09:04  stevens
+;;; minor bugs. (nroff word skipping fixed)
+;;;
+;;; Revision 2.20  1993/06/30 14:09:04  stevens
+;;;
+;;; Debugging and contributions by: Boris Aronov, Rik Faith, Chris Moore,
+;;;  Kevin Rodgers, Malcolm Davis.
+;;; Particular thanks to Michael Lipp, Jamie Zawinski, Phil Queinnec
+;;;  and John Heidemann for suggestions and code.
+;;; Major update including many tweaks.
+;;; Many changes were integrations of suggestions.
+;;; lookup-words rehacked to use call-process (Jamie).
+;;; ispell-complete-word rehacked to be compatible with the rest of the
+;;; system for word searching and to include multiple wildcards,
+;;; and its own dictionary.
+;;; query-replace capability added.  New options 'X', 'R', and 'A'.
+;;; buffer-local modes for dictionary, word-spelling, and formatter-parsing.
+;;; Many random bugs, like commented comments being skipped, fix to
+;;; keep-choices-win, fix for math mode, added pipe mode choice,
+;;; fixed 'q' command, ispell-word checks previous word and leave cursor
+;;; in same location.  Fixed tib code which could drop spelling regions.
+;;; Cleaned up setq calls for efficiency. Gave more context on window overlays.
+;;; Assure context on ispell-command-loop.  Window lossage in look cmd fixed.
+;;; Due to pervasive opinion, common-lisp package syntax removed. Display
+;;; problem when not highlighting. skip special keywords when checking comments
+;;;
+;;; Revision 2.19  1992/01/10  10:54:08  geoff
+;;; Make another attempt at fixing the "Bogus, dude" problem.  This one is
+;;; less elegant, but has the advantage of working.
+;;;
+;;; Revision 2.18  1992/01/07  10:04:52  geoff
+;;; Fix the "Bogus, Dude" problem in ispell-word.
+;;;
+;;; Revision 2.17  1991/09/12  00:01:42  geoff
+;;; Add some changes to make ispell-complete-word work better, though
+;;; still not perfectly.
+;;;
+;;; Revision 2.16  91/09/04  18:00:52  geoff
+;;; More updates from Sebastian, to make the multiple-dictionary support
+;;; more flexible.
+;;;
+;;; Revision 2.15  91/09/04  17:30:02  geoff
+;;; tib support (Sebastian Kremer)
+;;;
+;;; Revision 2.14  91/09/04  16:19:37  geoff
+;;; Don't do set-window-start if the move-to-window-line moved us
+;;; downward, rather than upward.  This prevents getting the buffer all
+;;; confused.  Also, don't use the "not-modified" function to clear the
+;;; modification flag;  instead use set-buffer-modified-p.  This prevents
+;;; extra messages from flashing.
+;;;
+;;; Revision 2.13  91/09/04  14:35:41  geoff
+;;; Fix a spelling error in a comment.  Add code to handshake with the
+;;; ispell process before sending anything to it.
+;;;
+;;; Revision 2.12  91/09/03  20:14:21  geoff
+;;; Add multiple-language support (Sebastian Kremer)
+;;;
+;;;
+;;; Original ispell.el by Walt Buehring
+;;;
+;;; Tue Jan 13 20:18:02 CST 1987 (Perry Smith)
+;;; ispell-region 
+;;;
+;;; Sun May 10 11:45:04 NZST 1987
+;;; extensively modified by Mark Davies and Andrew Vignaux
+;;;
+;;; Tue Jan  3 16:59:07 PST 1989  Ken Stevens
+;;; This file has received a major overhaul to be compatible with ispell
+;;; version 2.1.  Most of the functions have been totally rewritten, and
+;;; many user-accessible variables have been added.  The syntax table has
+;;; been removed since it didn't work properly anyway, and a filter is
+;;; used rather than a buffer.  Regular expressions are used based on
+;;; ispell's internal definition of characters (see ispell(4)).
+;;; Some new updates:
+;;; - Updated to version 3.0 to include terse processing.
+;;; - Added a variable for the look command.
+;;; - Fixed a bug in ispell-word when cursor is far away from the word
+;;;   that is to be checked.
+;;; - Ispell places the incorrect word or guess in the minibuffer now.
+;;; - fixed a bug with 'l' option when multiple windows are on the screen.
+;;; - lookup-words just didn't work with the process filter.  Fixed.
+;;; - Rewrote the process filter to make it cleaner and more robust
+;;;   in the event of a continued line not being completed.
+;;; - Made ispell-init-process more robust in handling errors.
+;;; - Fixed bug in continuation location after a region has been modified by
+;;;   correcting a misspelling.
+;;;
+;;; Wed Aug  7 14:02:17 MET DST 1991 Sebastian Kremer
+;;; - Ported ispell-complete-word from Ispell 2 to Ispell 3.
+;;; - Added ispell-kill-ispell command.
+;;; - Added ispell-dictionary and ispell-dictionary-alist variables to
+;;;   support other than default language.  See their docstrings and
+;;;   command ispell-change-dictionary.
+;;; - Added ispell-skip-tib variable to support the tib bibliography
+;;;   program.
+;;;
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-;; Copyright (C) 1994, 1995 Free Software Foundation, Inc.
 
-;; Authors         : Ken Stevens <k.stevens@ieee.org>
-;; Last Modified On: Tue Jun 13 12:05:28 EDT 1995
-;; Update Revision : 2.37
-;; Syntax          : emacs-lisp
-;; Status	    : Release with 3.1.12+ ispell.
-;; Version	    : International Ispell Version 3.1 by Geoff Kuenning.
-;; Bug Reports	    : ispell-el-bugs@itcorp.com
+;;; Custom.el macros require recompiling this when they are not present.
+;;; Add in backward compatible custom support.
+(eval-when-compile
+  (if (not (fboundp 'defcustom))
+      (defmacro defcustom (symbol value doc &rest args)
+	"Empty replacement for defcustom when not supplied."
+	`(defvar ,symbol ,value ,doc))))
 
-;; Note: version numbers and time stamp are not updated
-;;   when this file is edited for release with GNU emacs.
+(eval-when-compile
+  (if (fboundp 'defgroup)
+      (defgroup ispell nil
+	"User variables for emacs ispell interface."
+	:group 'applications)))
 
-;; This file is part of XEmacs.
 
-;; XEmacs is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;;; **********************************************************************
+;;; The following variables should be set according to personal preference
+;;; and location of binaries:
+;;; **********************************************************************
 
-;; XEmacs is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
 
-;; You should have received a copy of the GNU General Public License
-;; along with XEmacs; see the file COPYING.  If not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-;; 02111-1307, USA.
-
-;;; Commentary:
-
-;; INSTRUCTIONS
-;;
-;;  This code contains a section of user-settable variables that you should
-;; inspect prior to installation.  Look past the end of the history list.
-;; Set them up for your locale and the preferences of the majority of the
-;; users.  Otherwise the users may need to set a number of variables
-;; themselves.
-;;  You particularly may want to change the default dictionary for your
-;; country and language.
-;;
-;;
-;; To fully install this, add this file to your Emacs Lisp directory and
-;; compile it with M-X byte-compile-file.  Then add the following to the
-;; appropriate init file:
-;;
-;;  (autoload 'ispell-word "ispell"
-;;    "Check the spelling of word in buffer." t)
-;;  (global-set-key "\e$" 'ispell-word)
-;;  (autoload 'ispell-region "ispell"
-;;    "Check the spelling of region." t)
-;;  (autoload 'ispell-buffer "ispell"
-;;    "Check the spelling of buffer." t)
-;;  (autoload 'ispell-complete-word "ispell"
-;;    "Look up current word in dictionary and try to complete it." t)
-;;  (autoload 'ispell-change-dictionary "ispell"
-;;    "Change ispell dictionary." t)
-;;  (autoload 'ispell-message "ispell"
-;;    "Check spelling of mail message or news post.")
-;;
-;;  Depending on the mail system you use, you may want to include these:
-;;
-;;  (add-hook 'news-inews-hook 'ispell-message)
-;;  (add-hook 'mail-send-hook  'ispell-message)
-;;  (add-hook 'mh-before-send-letter-hook 'ispell-message)
-;;
-;;
-;; Ispell has a TeX parser and a nroff parser (the default).
-;; The parsing is controlled by the variable ispell-parser.  Currently
-;; it is just a "toggle" between TeX and nroff, but if more parsers are
-;; added it will be updated.  See the variable description for more info.
-;;
-;;
-;; TABLE OF CONTENTS
-;;
-;;   ispell-word
-;;   ispell-region
-;;   ispell-buffer
-;;   ispell-message
-;;   ispell-continue
-;;   ispell-complete-word
-;;   ispell-complete-word-interior-frag
-;;   ispell-change-dictionary
-;;   ispell-kill-ispell
-;;   ispell-pdict-save
-;;
-;;
-;; Commands in ispell-region:
-;; Character replacement: Replace word with choice.  May query-replace.
-;; ' ': Accept word this time.
-;; 'i': Accept word and insert into private dictionary.
-;; 'a': Accept word for this session.
-;; 'A': Accept word and place in buffer-local dictionary.
-;; 'r': Replace word with typed-in value.  Rechecked.
-;; 'R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
-;; '?': Show these commands
-;; 'x': Exit spelling buffer.  Move cursor to original point.
-;; 'X': Exit spelling buffer.  Leave cursor at the current point.
-;; 'q': Quit spelling session (Kills ispell process).
-;; 'l': Look up typed-in replacement in alternate dictionary.  Wildcards okay.
-;; 'u': Like 'i', but the word is lower-cased first.
-;; 'm': Like 'i', but allows one to include dictionary completion info.
-;; 'C-l': redraws screen
-;; 'C-r': recursive edit
-;; 'C-z': suspend emacs or iconify frame
-;;
-;; Buffer-Local features:
-;; There are a number of buffer-local features that can be used to customize
-;;  ispell for the current buffer.  This includes language dictionaries,
-;;  personal dictionaries, parsing, and local word spellings.  Each of these
-;;  local customizations are done either through local variables, or by
-;;  including the keyword and argument(s) at the end of the buffer (usually
-;;  prefixed by the comment characters).  See the end of this file for
-;;  examples.  The local keywords and variables are:
-;;
-;;  ispell-dictionary-keyword   language-dictionary
-;;      uses local variable ispell-local-dictionary
-;;  ispell-pdict-keyword        personal-dictionary
-;;      uses local variable ispell-local-pdict
-;;  ispell-parsing-keyword      mode-arg extended-char-arg
-;;  ispell-words-keyword        any number of local word spellings
-;;
-;;
-;; BUGS:
-;;  Highlighting in version 19 still doesn't work on tty's.
-;;  On some versions of emacs, growing the minibuffer fails.
-;;
-;; HISTORY
-;;
-;; Revision 2.38  1996/5/30    ethanb@phys.washington.edu
-;; Update ispell-message for gnus 5 (news-inews-hook => message-send-hook;
-;; different header for quoted message).
-;;
-;; Revision 2.37  1995/6/13 12:05:28	stevens
-;; Removed autoload from ispell-dictionary-alist. *choices* mode-line shows
-;; misspelled word.  Block skip for pgp & forwarded messages added.
-;; RMS: the autoload changes had problems and I removed them.
-;;
-;; Revision 2.36  1995/2/6 17:39:38	stevens
-;; Properly adjust screen with different ispell-choices-win-default-height
-;; settings.  Skips SGML entity references.
-;;
-;; Revision 2.35  1995/1/13 14:16:46	stevens
-;; Skips SGML tags, ispell-change-dictionary fix for add-hook, assure personal
-;; dictionary is saved when called from the menu
-;;
-;; Revision 2.34  1994/12/08 13:17:41  stevens
-;; Interaction corrected to function with all 3.1 ispell versions.
-;;
-;; Revision 2.33  1994/11/24 02:31:20  stevens
-;; Repaired bug introduced in 2.32 that corrupts buffers when correcting.
-;; Improved buffer scrolling. Nondestructive buffer selections allowed.
-;;
-;; Revision 2.32  1994/10/31 21:10:08  geoff
-;; Many revisions accepted from RMS/FSF.  I think (though I don't know) that
-;; this represents an 'official' version.
-;;
-;; Revision 2.31  1994/5/31 10:18:17  stevens
-;; Repaired comments.  buffer-local commands executed in `ispell-word' now.
-;; German dictionary described for extended character mode.  Dict messages.
-;;
-;; Revision 2.30  1994/5/20 22:18:36  stevens
-;; Continue ispell from ispell-word, C-z functionality fixed.
-;;
-;; Revision 2.29  1994/5/12 09:44:33  stevens
-;; Restored ispell-use-ptys-p, ispell-message aborts sends with interrupt.
-;; defined fn ispell
-;;
-;; Revision 2.28  1994/4/28 16:24:40  stevens
-;; Window checking when ispell-message put on gnus-inews-article-hook jwz.
-;; prefixed ispell- to highlight functions and horiz-scroll fn.
-;; Try and respect case of word in ispell-complete-word.
-;; Ignore non-char events.  Ispell-use-ptys-p commented out. Lucid menu.
-;; Better interrupt handling.  ispell-message improvements from Ethan.
-;;
-;; Revision 2.27
-;; version 18 explicit C-g handling disabled as it didn't work. Added
-;; ispell-extra-args for ispell customization (jwz)
-;;
-;; Revision 2.26  1994/2/15 16:11:14  stevens
-;; name changes for copyright assignment.  Added word-frags in complete-word.
-;; Horizontal scroll (John Conover). Query-replace matches words now.  bugs.
-;;
-;; Revision 2.25
-;; minor mods, upgraded ispell-message
-;;
-;; Revision 2.24
-;; query-replace more robust, messages, defaults, ispell-change-dict.
-;;
-;; Revision 2.23  1993/11/22 23:47:03  stevens
-;; ispell-message, Fixed highlighting, added menu-bar, fixed ispell-help, ...
-;;
-;; Revision 2.22
-;; Added 'u' command.  Fixed default in ispell-local-dictionary.
-;; fixed affix rules display.  Tib skipping more robust.  Contributions by
-;; Per Abraham (parser selection), Denis Howe, and Eberhard Mattes.
-;;
-;; Revision 2.21  1993/06/30 14:09:04  stevens
-;; minor bugs. (nroff word skipping fixed)
-;;
-;; Revision 2.20  1993/06/30 14:09:04  stevens
-;;
-;; Debugging and contributions by: Boris Aronov, Rik Faith, Chris Moore,
-;;  Kevin Rodgers, Malcolm Davis.
-;; Particular thanks to Michael Lipp, Jamie Zawinski, Phil Queinnec
-;;  and John Heidemann for suggestions and code.
-;; Major update including many tweaks.
-;; Many changes were integrations of suggestions.
-;; lookup-words rehacked to use call-process (Jamie).
-;; ispell-complete-word rehacked to be compatible with the rest of the
-;; system for word searching and to include multiple wildcards,
-;; and it's own dictionary.
-;; query-replace capability added.  New options 'X', 'R', and 'A'.
-;; buffer-local modes for dictionary, word-spelling, and formatter-parsing.
-;; Many random bugs, like commented comments being skipped, fix to
-;; keep-choices-win, fix for math mode, added pipe mode choice,
-;; fixed 'q' command, ispell-word checks previous word and leave cursor
-;; in same location.  Fixed tib code which could drop spelling regions.
-;; Cleaned up setq calls for efficiency. Gave more context on window overlays.
-;; Assure context on ispell-command-loop.  Window lossage in look cmd fixed.
-;; Due to pervasive opinion, common-lisp package syntax removed. Display
-;; problem when not highlighting.
-;;
-;; Revision 2.19  1992/01/10  10:54:08  geoff
-;; Make another attempt at fixing the "Bogus, dude" problem.  This one is
-;; less elegant, but has the advantage of working.
-;;
-;; Revision 2.18  1992/01/07  10:04:52  geoff
-;; Fix the "Bogus, Dude" problem in ispell-word.
-;;
-;; Revision 2.17  1991/09/12  00:01:42  geoff
-;; Add some changes to make ispell-complete-word work better, though
-;; still not perfectly.
-;;
-;; Revision 2.16  91/09/04  18:00:52  geoff
-;; More updates from Sebastian, to make the multiple-dictionary support
-;; more flexible.
-;;
-;; Revision 2.15  91/09/04  17:30:02  geoff
-;; Sebastian Kremer's tib support
-;;
-;; Revision 2.14  91/09/04  16:19:37  geoff
-;; Don't do set-window-start if the move-to-window-line moved us
-;; downward, rather than upward.  This prevents getting the buffer all
-;; confused.  Also, don't use the "not-modified" function to clear the
-;; modification flag;  instead use set-buffer-modified-p.  This prevents
-;; extra messages from flashing.
-;;
-;; Revision 2.13  91/09/04  14:35:41  geoff
-;; Fix a spelling error in a comment.  Add code to handshake with the
-;; ispell process before sending anything to it.
-;;
-;; Revision 2.12  91/09/03  20:14:21  geoff
-;; Add Sebastian Kremer's multiple-language support.
-;;
-;;
-;; Walt Buehring
-;; Texas Instruments - Computer Science Center
-;; ARPA:  Buehring%TI-CSL@CSNet-Relay
-;; UUCP:  {smu, texsun, im4u, rice} ! ti-csl ! buehring
-;;
-;; ispell-region and associated routines added by
-;; Perry Smith
-;; pedz@bobkat
-;; Tue Jan 13 20:18:02 CST 1987
-;;
-;; extensively modified by Mark Davies and Andrew Vignaux
-;; {mark,andrew}@vuwcomp
-;; Sun May 10 11:45:04 NZST 1987
-;;
-;; Ken Stevens  ARPA: k.stevens@ieee.org
-;; Tue Jan  3 16:59:07 PST 1989
-;; This file has overgone a major overhaul to be compatible with ispell
-;; version 2.1.  Most of the functions have been totally rewritten, and
-;; many user-accessible variables have been added.  The syntax table has
-;; been removed since it didn't work properly anyway, and a filter is
-;; used rather than a buffer.  Regular expressions are used based on
-;; ispell's internal definition of characters (see ispell(4)).
-;; Some new updates:
-;; - Updated to version 3.0 to include terse processing.
-;; - Added a variable for the look command.
-;; - Fixed a bug in ispell-word when cursor is far away from the word
-;;   that is to be checked.
-;; - Ispell places the incorrect word or guess in the minibuffer now.
-;; - fixed a bug with 'l' option when multiple windows are on the screen.
-;; - lookup-words just didn't work with the process filter.  Fixed.
-;; - Rewrote the process filter to make it cleaner and more robust
-;;   in the event of a continued line not being completed.
-;; - Made ispell-init-process more robust in handling errors.
-;; - Fixed bug in continuation location after a region has been modified by
-;;   correcting a misspelling.
-;; Mon 17 Sept 1990
-;;
-;; Sebastian Kremer <sk@thp.uni-koeln.de>
-;; Wed Aug  7 14:02:17 MET DST 1991
-;; - Ported ispell-complete-word from Ispell 2 to Ispell 3.
-;; - Added ispell-kill-ispell command.
-;; - Added ispell-dictionary and ispell-dictionary-alist variables to
-;;   support other than default language.  See their docstrings and
-;;   command ispell-change-dictionary.
-;; - (ispelled it :-)
-;; - Added ispell-skip-tib variable to support the tib bibliography
-;;   program.
-
-
-;; **********************************************************************
-;; The following variables should be set according to personal preference
-;; and location of binaries:
-;; **********************************************************************
-
-;;  ******* THIS FILE IS WRITTEN FOR ISPELL VERSION 3.1
-
+;;;  ******* THIS FILE IS WRITTEN FOR ISPELL VERSION 3.1
 ;;; Code:
 
-(defgroup ispell nil
-  "Spell checking using ispell"
-  :group 'processes)
-
-
-(defcustom ispell-highlight-p t
-  "*Highlight spelling errors when non-nil."
-  :type 'boolean
+(defcustom ispell-highlight-p 'block
+  "*Highlight spelling errors when non-nil.
+When set to 'block, assumes a block cursor with TTY displays."
+  :type '(choice (const block) (const t) (const nil))
   :group 'ispell)
 
 (defcustom ispell-highlight-face 'highlight
   :group 'ispell)
 
 (defcustom ispell-check-comments t
-  "*If nil, don't check spelling of comments."
-  :type 'boolean
+  "*Spelling of comments checked when non-nil.
+When set to 'exclusive ONLY comments are checked.  (For code comments).
+Warning!  Not checking comments when a comment-start is embedded in strings
+may produce undesired results."
+  :type '(choice (const exclusive) (const t) (const nil))
   :group 'ispell)
 
 (defcustom ispell-query-replace-choices nil
   :type 'file
   :group 'ispell)
 
-(defvar ispell-grep-command "egrep"
-  "Name of the grep command for search processes.")
+(defcustom ispell-message-dictionary-alist nil
+  "*List used by `ispell-message' to select a new dictionary.
+It consists of pairs (REGEXP . DICTIONARY).  If REGEXP is found
+in the message headers, `ispell-local-dictionary' will be set to
+DICTIONARY if `ispell-local-dictionary' is not buffer-local.
+E.g. you may use the following value:
+  '((\"^Newsgroups:[ \\t]*de\\\\.\" . \"deutsch8\")
+    (\"^To:[^\\n,]+\\\\.de[ \\t\\n,>]\" . \"deutsch8\"))"
+  :type '(repeat (cons regexp string))
+  :group 'ispell)
 
-(defvar ispell-grep-options "-i"
+
+(defcustom ispell-grep-command "egrep"
+  "Name of the grep command for search processes."
+  :type 'string
+  :group 'ispell)
+
+(defcustom ispell-grep-options "-i"
   "String of options to use when running the program in `ispell-grep-command'.
 Should probably be \"-i\" or \"-e\".
-Some machines (like the NeXT) don't support \"-i\"")
+Some machines (like the NeXT) don't support \"-i\""
+  :type 'string
+  :group 'ispell)
 
-(defvar ispell-look-command "look"
+(defcustom ispell-look-command
+  (cond ((file-exists-p "/bin/look") "/bin/look")
+	((file-exists-p "/usr/local/bin/look") "/usr/local/bin/look")
+	((file-exists-p "/usr/bin/look") "/usr/bin/look")
+	(t "look"))
   "Name of the look command for search processes.
-This must be an absolute file name.")
+This must be an absolute file name."
+  :type 'file
+  :group 'ispell)
 
-(defcustom ispell-look-p `(file-exists-p ispell-look-command)
+(defcustom ispell-look-p (file-exists-p ispell-look-command)
   "*Non-nil means use `look' rather than `grep'.
 Default is based on whether `look' seems to be available."
   :type 'boolean
   :type 'boolean
   :group 'ispell)
 
-(defvar ispell-look-options (if ispell-have-new-look "-dfr" "-df")
-  "String of command options for `ispell-look-command'.")
+(defcustom ispell-look-options (if ispell-have-new-look "-dfr" "-df")
+  "String of command options for `ispell-look-command'."
+  :type 'string
+  :group 'ispell)
 
-(defvar ispell-use-ptys-p nil
+(defcustom ispell-use-ptys-p nil
   "When non-nil, Emacs uses ptys to communicate with Ispell.
-When nil, Emacs uses pipes.")
+When nil, Emacs uses pipes."
+  :type 'boolean
+  :group 'ispell)
 
 (defcustom ispell-following-word nil
   "*Non-nil means `ispell-word' checks the word around or after point.
 
 (defcustom ispell-help-in-bufferp nil
   "*Non-nil means display interactive keymap help in a buffer.
-Otherwise use the minibuffer."
-  :type 'boolean
+The following valued are supported:
+  nil        Expand the minibuffer and display a short help message
+             there for a couple of seconds.
+  t          Pop up a new buffer and display a short help message there
+             for a couple of seconds.
+  'electric  Pop up a new buffer and display a long help message there. 
+             User can browse and then exit the help mode."
+  :type '(choice (const electric) (const t) (const nil))
+
   :group 'ispell)
 
 (defcustom ispell-quietly nil
   :type 'function
   :group 'ispell)
 
+(defcustom ispell-use-framepop-p (and window-system
+				   (condition-case () (require 'framepop)
+				     (error nil)))
+  "When non-nil ispell uses framepop to display choices in a dedicated frame."
+  :type 'boolean
+  :group 'ispell)
+
 ;;;###autoload
 (defcustom ispell-personal-dictionary nil
   "*File name of your personal spelling dictionary, or nil.
 If nil, the default personal dictionary, \"~/.ispell_DICTNAME\" is used,
 where DICTNAME is the name of your default dictionary."
-  :type 'file
+  :type '(choice file
+		 (const :tag "default" nil))
   :group 'ispell)
 
 (defcustom ispell-silently-savep nil
   :type 'boolean
   :group 'ispell)
 
-;;; This variable contains the current dictionary being used if the ispell
-;;; process is running.  Otherwise it contains the global default.
-(defvar ispell-dictionary nil
-  "If non-nil, a dictionary to use instead of the default one.
-This is passed to the ispell process using the `-d' switch and is
-used as key in `ispell-dictionary-alist' (which see).
+;;; This is the local dictionary to use.  When nil the default dictionary will
+;;; be used.  Change set-default call to use a new default dictionary.
+(defcustom ispell-local-dictionary nil
+  "If non-nil, the dictionary to be used for Ispell commands.
+The value must be a string dictionary name in `ispell-dictionary-alist'.
+This variable becomes buffer-local when set in any fashion.
 
-You should set this variable before your first use of Emacs spell-checking
-commands in the Emacs session, or else use the \\[ispell-change-dictionary]
-command to change it.  Otherwise, this variable only takes effect in a newly
-started Ispell process.")
+Setting ispell-local-dictionary to a value has the same effect as
+calling \\[ispell-change-dictionary] with that value.  This variable
+is automatically set when defined in the file with either
+`ispell-dictionary-keyword' or the Local Variable syntax.
+
+To create a non-standard default dictionary (not from ispell-dictionary-alist)
+call function set-default with the new dictionary name."
+  :type '(choice string
+		 (const :tag "default" nil))
+  :group 'ispell)
+
+(make-variable-buffer-local 'ispell-local-dictionary)
+
+;; Call this function set up the default dictionary if not English.
+;;(set-default 'ispell-local-dictionary nil)
+
 
 (defcustom ispell-extra-args nil
   "*If non-nil, a list of extra switches to pass to the Ispell program.
 ;;; so that it can set up the menus and determine keyboard equivalents.
 
 ;;;###autoload
-(defvar ispell-dictionary-alist-1	; sk  9-Aug-1991 18:28
-  '((nil				; default (english.aff)
-     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil)
-    ("english"				; make english explicitly selectable
-     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil)
-    ("british"				; british version
-     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B" "-d" "british") nil)
-    ("deutsch"				; deutsch.aff
-     "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex")
+(defcustom ispell-dictionary-alist
+  '((nil				; default (English.aff)
+     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil nil)
+    ("american"				; make English explicitly selectable
+     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil nil)
+    ("british"				; British version
+     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B" "-d" "british") nil nil)
+    ("castellano"                      ; Spanish mode
+     "[A-Z\301\311\315\323\332\334\321a-z\341\351\355\363\372\374\361]"
+     "[^A-Z\301\311\315\323\332\334\321a-z\341\351\355\363\372\374\361]"
+     "[---]" nil ("-B" "-dcastellano") "~tex" iso-latin-1)
+    ("castellano8"                      ; 8 bit Spanish mode
+     "[A-Z\301\311\315\323\332\334\321a-z\341\351\355\363\372\374\361]"
+     "[^A-Z\301\311\315\323\332\334\321a-z\341\351\355\363\372\374\361]"
+     "[---]" nil ("-B" "-dcastellano") "~latin1" iso-latin-1)
+    ("dansk"				; Dansk.aff
+     "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]"
+     "[']" nil ("-C") nil iso-latin-1)
+    ("deutsch"				; Deutsch.aff
+     "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" nil)
     ("deutsch8"
      "[a-zA-Z\304\326\334\344\366\337\374]"
      "[^a-zA-Z\304\326\334\344\366\337\374]"
-     "[']" t ("-C" "-d" "deutsch") "~latin1")
-    ("nederlands"				; nederlands.aff
+     "[']" t ("-C" "-d" "deutsch") "~latin1" iso-latin-1)
+    ("english"				; make English explicitly selectable
+     "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil nil)
+    ("esperanto"
+     "[A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]"
+     "[^A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]"
+     "[-']" t ("-C") "~latin3" nil)
+    ("esperanto-tex"
+     "[A-Za-z^\\]" "[^A-Za-z^\\]" "[-'`\"]" t ("-C" "-d" "esperanto") "~tex"
+     nil)
+    ("francais7"
+     "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil nil)
+    ("francais"				; Francais.aff
+     "[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]"
+     "[^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]"
+     "[---']" t nil "~list" iso-latin-1)
+    ("francais-tex"			; Francais.aff
+     "[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\\]"
+     "[^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\\]"
+     "[---'^`\"]" t nil "~tex" iso-latin-1)
+    ("nederlands"			; Nederlands.aff
      "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
      "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
-     "[']" t ("-C") nil)
-    ("nederlands8"				; dutch8.aff
+     "[']" t ("-C") nil iso-latin-1)
+    ("nederlands8"			; Dutch8.aff
      "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
      "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
-     "[']" t ("-C") nil)))
-
-;;;###autoload
-(defvar ispell-dictionary-alist-2
-  '(("svenska"				;7 bit swedish mode
+     "[']" t ("-C") nil iso-latin-1)
+    ("norsk"                           ;8 bit Norwegian mode
+     "[A-Za-z\351\346\370\345\311\306\330\305]"
+     "[^A-Za-z\351\346\370\345\311\306\330\305]"
+     "[']" nil ("-C" "-d" "norsk") "~list" nil)
+    ("svenska"				;7 bit Swedish mode
      "[A-Za-z}{|\\133\\135\\\\]" "[^A-Za-z}{|\\133\\135\\\\]"
-     "[']" nil ("-C") nil)
-    ("svenska8"				;8 bit swedish mode
+     "[']" nil ("-C") nil nil)
+    ("svenska8"				;8 bit Swedish mode
      "[A-Za-z\345\344\366\305\304\366]"  "[^A-Za-z\345\344\366\305\304\366]"
-     "[']" nil ("-C" "-d" "svenska") "~list") ; Add `"-T" "list"' instead?
-    ("norsk"                           ;8 bit norwegian mode
-     "[A-Za-z\351\346\370\345\311\306\330\305]"  "[^A-Za-z\351\346\370\345\311\306\330\305]"
-     "[']" nil ("-C" "-d" "norsk") "~list")
-    ("francais7"
-     "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil)
-    ("francais"				; francais.aff
-     "[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]"
-     "[^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]"
-     "[---']" t nil "~list")
-    ("francais-tex"			; francais.aff
-     "[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\\]"
-     "[^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\\]"
-     "[---'^`\"]" t nil "~tex")
-    ("italiano"				; italiano.aff
-     "[A-Za-z\300\310\311\314\315\316\322\331\332\340\350\351\354\355\356\362\371\372]"
-     "[^A-Za-z\300\310\311\314\315\316\322\331\332\340\350\351\354\355\356\362\371\372]"
-     "[']" t ("-d" "italiano") "~list")
-    ("dansk"				; dansk.aff
-     "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]"
-     "" nil ("-C") nil)
-    ))
-
-
-;;; ispell-dictionary-alist is set up from two subvariables above
-;;; to avoid having very long lines in loaddefs.el.
-;;;###autoload
-(defvar ispell-dictionary-alist
-  (append ispell-dictionary-alist-1 ispell-dictionary-alist-2)
+     "[']" nil ("-C" "-d" "svenska") "~list" ; Add `"-T" "list"' instead?
+     iso-latin-1))
   "An alist of dictionaries and their associated parameters.
 
 Each element of this list is also a list:
 
 NOT-CASECHARS is the opposite regexp of CASECHARS.
 
-OTHERCHARS is a regular expression of other characters that are valid
-in word constructs.  Otherchars cannot be adjacent to each other in a
-word, nor can they begin or end a word.  This implies we can't check
-\"Stevens'\" as a correct possessive and other correct formations.
-
+OTHERCHARS are characters in the NOT-CASECHARS set but which can be used to
+construct words in some special way.  If OTHERCHARS characters follow and
+precede characters from CASECHARS, they are parsed as part of a word,
+otherwise they become word-breaks.  As an example in English, assume the
+set ['] (as a regular expression) for OTHERCHARS.  Then \"they're\" and
+\"Steven's\" are parsed as single words including the \"'\" character, but
+\"Stevens'\" does not include the quote character as part of the word.
+If you want OTHERCHARS to be empty, use nil.
 Hint: regexp syntax requires the hyphen to be declared first here.
 
-MANY-OTHERCHARS-P is non-nil if many otherchars are to be allowed in a
-word instead of only one.
+MANY-OTHERCHARS-P is non-nil when multiple OTHERCHARS are allowed in a word.
+Otherwise only a single OTHERCHARS character is allowed to be part of any
+single word.
 
 ISPELL-ARGS is a list of additional arguments passed to the ispell
 subprocess.
 Both defaults can be overruled in a buffer-local fashion. See
 `ispell-parsing-keyword' for details on this.
 
+CHARACTER-SET used for languages with multibyte characters.
+
 Note that the CASECHARS and OTHERCHARS slots of the alist should
 contain the same character set as casechars and otherchars in the
-language.aff file \(e.g., english.aff\).")
+language.aff file \(e.g., english.aff\)."
+  :type '(repeat (list (choice (string :tag "dictionary name")
+			       (const :tag "default" nil))
+		       (regexp :tag "case characters")
+		       (regexp :tag "Non case characters")
+		       (regexp :tag "other characters")
+		       (boolean :tag "many other characters")
+		       (repeat (string :tag "ispell command line arguments"))
+		       (choice (const "~tex") (const "~list") (const "~nroff")
+			       (const "~latin3") (const "~latin1")
+			       (const nil))
+		       (choice (const iso-latin-1)
+			       (const nil :tag "default"))))
+  :group 'ispell)
+
 
 ;;;###autoload
 (defvar ispell-menu-map nil "Key map for ispell menu")
 
 ;;;###autoload
-(defvar ispell-menu-xemacs nil "Spelling menu for XEmacs.")
+(defvar ispell-menu-lucid nil
+  "Spelling menu for Lucid Emacs.
+If nil when package is loaded, a standard menu will be set,
+and added as a submenu of the \"Edit\" menu.")
 
-;;; Break out XEmacs menu and split into several calls to avoid having
+;;; Break out lucid menu and split into several calls to avoid having
 ;;; long lines in loaddefs.el.  Detect need off following constant.
 
+;;; Set up dictionary
 ;;;###autoload
-(defconst ispell-menu-map-needed	; make sure this is not XEmacs
+(defconst ispell-menu-map-needed	; make sure this is not Lucid Emacs
   (and (not ispell-menu-map)
        (string-lessp "19" emacs-version)
-       ;; make sure this isn't XEmacs
-       (not (string-match "XEmacs" emacs-version))))
+       ;; make sure this isn't Lucid Emacs
+       (not (string-match "Lucid" emacs-version))))
 
-
-;;; Set up dictionary
 ;;;###autoload
 (if ispell-menu-map-needed
     (let ((dicts (reverse (cons (cons "default" nil) ispell-dictionary-alist)))
       (put 'ispell-region 'menu-enable 'mark-active)
       (fset 'ispell-menu-map (symbol-value 'ispell-menu-map))))
 
-;;; XEmacs version 19
+;;; Xemacs version 19
 (if (and (string-lessp "19" emacs-version)
 	 (string-match "Lucid" emacs-version)
-	 (not (and (boundp 'infodock-version) infodock-version))
-	 (featurep 'menubar)
-	 (or current-menubar default-menubar))
+	 (null ispell-menu-lucid)
+	 (not (and (boundp 'infodock-version) infodock-version)))
     (let ((dicts (cons (cons "default" nil) ispell-dictionary-alist))
 	  (current-menubar (or current-menubar default-menubar))
 	  (menu
 	(if (stringp name)
 	    (setq menu (append menu
 			       (list
-				(vector (concat "Select " (capitalize name))
-					(list 'ispell-change-dictionary name)
-					t))))))
-      (setq ispell-menu-xemacs menu)
+				 (vector (concat "Select " (capitalize name))
+					 (list 'ispell-change-dictionary name)
+					 t))))))
+      (setq ispell-menu-lucid menu)
       (if current-menubar
 	  (progn
 	    (delete-menu-item '("Edit" "Spell")) ; in case already defined
-	    (add-menu '("Edit") "Spell" ispell-menu-xemacs)))))
+	    (add-menu '("Edit") "Spell" ispell-menu-lucid)))))
 
 
 ;;; **********************************************************************
 ;;; There is an incompatibility between version 3.1.12 and lower versions.
 (defconst ispell-required-version '("3.1." 12)
   "Ispell versions with which this version of ispell.el is known to work.")
-(defvar ispell-offset 1
+(defvar ispell-offset -1
   "Offset that maps protocol differences between ispell 3.1 versions.")
 
+;;; This variable contains the current dictionary being used if the ispell
+;;; process is running.  Otherwise it contains the global default.
+(defvar ispell-dictionary nil
+  "The name of the current dictionary, or nil for the default.
+When ispell-local-dictionary is nil, ispell-dictionary is used to select the
+dictionary for new buffers.
+
+This is passed to the ispell process using the `-d' switch and is
+used as key in `ispell-dictionary-alist' (which see).")
+
+(defun ispell-decode-string (str)
+  "Decodes multibyte character strings."
+  (if (and (boundp 'enable-multibyte-characters)
+	   (fboundp 'decode-coding-string)
+	   enable-multibyte-characters
+	   (ispell-get-coding-system))
+      (decode-coding-string str (ispell-get-coding-system))
+    str))
+
 (defun ispell-get-casechars ()
-  (nth 1 (assoc ispell-dictionary ispell-dictionary-alist)))
+  (ispell-decode-string
+   (nth 1 (assoc ispell-dictionary ispell-dictionary-alist))))
 (defun ispell-get-not-casechars ()
-  (nth 2 (assoc ispell-dictionary ispell-dictionary-alist)))
+  (ispell-decode-string
+   (nth 2 (assoc ispell-dictionary ispell-dictionary-alist))))
 (defun ispell-get-otherchars ()
-  (nth 3 (assoc ispell-dictionary ispell-dictionary-alist)))
+  (ispell-decode-string
+   (nth 3 (assoc ispell-dictionary ispell-dictionary-alist))))
 (defun ispell-get-many-otherchars-p ()
   (nth 4 (assoc ispell-dictionary ispell-dictionary-alist)))
 (defun ispell-get-ispell-args ()
   (nth 5 (assoc ispell-dictionary ispell-dictionary-alist)))
 (defun ispell-get-extended-character-mode ()
   (nth 6 (assoc ispell-dictionary ispell-dictionary-alist)))
+(defun ispell-get-coding-system ()
+  (nth 7 (assoc ispell-dictionary ispell-dictionary-alist)))
 
 (defvar ispell-process nil
   "The process object for Ispell.")
 (defvar ispell-query-replace-marker (make-marker)
   "Marker for `query-replace' processing.")
 
+(defvar ispell-recursive-edit-marker (make-marker)
+  "Marker for return point from recursive edit.")
+
 (defvar ispell-checking-message nil
   "Non-nil when we're checking a mail message")
 
 
 ;;; *** Buffer Local Definitions ***
 
-;;; This is the local dictionary to use.  When nil the default dictionary will
-;;; be used.  Do not redefine default value or it will override the global!
-(defvar ispell-local-dictionary nil
-  "If non-nil, a dictionary to use for Ispell commands in this buffer.
-The value must be a string dictionary name in `ispell-dictionary-alist'.
-This variable becomes buffer-local when set in any fashion.
-
-Setting ispell-local-dictionary to a value has the same effect as
-calling \\[ispell-change-dictionary] with that value.  This variable
-is automatically set when defined in the file with either
-`ispell-dictionary-keyword' or the Local Variable syntax.")
-
-(make-variable-buffer-local 'ispell-local-dictionary)
-
-;; Use default directory, unless locally set.
-(set-default 'ispell-local-dictionary nil)
-
-(defconst ispell-words-keyword "LocalWords: "				      
+(defconst ispell-words-keyword "LocalWords: "                                 
   "The keyword for local oddly-spelled words to accept.
 The keyword will be followed by any number of local word spellings.
 There can be multiple of these keywords in the file.")
 
 (defconst ispell-dictionary-keyword "Local IspellDict: "
-  "The keyword for local dictionary definitions.
-There should be only one dictionary keyword definition per file, and it
-should be followed by a correct dictionary name in `ispell-dictionary-alist'.")
+  "The keyword for a local dictionary to use.
+The keyword must be followed by a correct dictionary name in
+`ispell-dictionary-alist'.  When multiple occurrences exist, the last keyword
+definition will be used.")
+
+(defconst ispell-pdict-keyword "Local IspellPersDict: "
+  "The keyword for defining buffer local dictionaries.
+Keyword must be followed by the filename of a personal dictionary.
+The last occurring definition in the buffer will be used.")
 
 (defconst ispell-parsing-keyword "Local IspellParsing: "
   "The keyword for overriding default Ispell parsing.
-Determined by the buffer's major mode and extended-character mode as well as
-the default dictionary.
-
 The above keyword string should be followed by `latex-mode' or
 `nroff-mode' to put the current buffer into the desired parsing mode.
 
 Extended character mode can be changed for this buffer by placing
-a `~' followed by an extended-character mode -- such as `~.tex'.")
-
-(defvar ispell-skip-sgml nil
-  "Skips spell checking of SGML tags and entity references when non-nil.
-This variable is set when major-mode is sgml-mode or html-mode.")
+a `~' followed by an extended-character mode -- such as `~.tex'.
+The last occurring definition in the buffer will be used.")
 
 ;;;###autoload
+(defvar ispell-skip-region-alist
+  '((ispell-words-keyword	   forward-line)
+    (ispell-dictionary-keyword	   forward-line)
+    (ispell-pdict-keyword	   forward-line)
+    (ispell-parsing-keyword	   forward-line)
+    ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*")
+    ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage"   . "^---* End of [Ff]orwarded [Mm]essage")
+    ("\\(\\w\\|-\\)*\\([.:/@]+\\(\\w\\|-\\)+\\)+")
+    ;; some valid text will be skipped, e.g. "his/herr".  This could be
+    ;; fixed up (at the expense of a more complicated regular expression)
+    ;; by not allowing "/" to be the character which triggers the
+    ;; identification of the computer name, e.g.:
+    ;; "\\(\\w\\|-\\)+[.:@]\\(\\w\\|-\\)*\\([.:/@]+\\(\\w\\|-\\)+\\)+"
+    ;; or to keep recognizing strings with an initial "/":
+    ;; "\\(/\\|\\(\\(\\w\\|-\\)+[.:@]\\)\\)\\(\\w\\|-\\)*\\([.:/@]+\\(\\w\\|-\\)+\\)+"
+    )
+  "A-list expressing begining and end of regions not to spell check.
+The alist key must be a regular expression.
+Valid forms include:
+  (KEY) - just skip the key.
+  (KEY . REGEXP) - skip to the end REGEXP.  REGEXP may be string or symbol.
+  (KEY REGEXP) - skip to end of REGEXP.  REGEXP must be a string.
+  (KEY FUNCTION ARGS) - function called with args returns end of region.")
+
+
+
+;;;###autoload
+(defvar ispell-tex-skip-alists
+  '((("%\\[" . "%\\]")
+     ("\\\\bibliographystyle"	ispell-tex-arg-end)
+     ("\\\\epsfig"		ispell-tex-arg-end)
+     ("\\\\author"		ispell-tex-arg-end)
+     ("\\\\documentclass" .	"\\\\begin[ \t\n]*{[ \t\n]*document[ \t\n]*}")
+     ("\\\\documentstyle" .	"\\\\begin[ \t\n]*{[ \t\n]*document[ \t\n]*}"))
+    ( ;; delimited with \begin
+     ("program"    .	"\\\\end[ \t\n]*{[ \t\n]*program[ \t\n]*}")
+     ("figure"		ispell-tex-arg-end 0)
+     ("table"		ispell-tex-arg-end 0)
+     ("tabular"		ispell-tex-arg-end)))
+  "*Lists of regions to be skipped in TeX mode.
+First list is used raw.
+Second list has key placed inside \begin{}.
+
+Delete or add any regions you want to be automatically selected
+for skipping in latex mode.")
+
+
+(defvar ispell-skip-sgml 'use-mode-name
+  "*Indicates whether ispell should skip spell checking of SGML markup.
+If t, always skip SGML markup; if nil, never skip; if non-t and non-nil,
+guess whether SGML markup should be skipped according to the name of the
+buffer's major-mode.")
+
 (defvar ispell-local-pdict ispell-personal-dictionary
   "A buffer local variable containing the current personal dictionary.
 If non-nil, the value must be a string, which is a file name.
 
 (make-variable-buffer-local 'ispell-local-pdict)
 
-(defconst ispell-pdict-keyword "Local IspellPersDict: "
-  "The keyword for defining buffer local dictionaries.")
-
 (defvar ispell-buffer-local-name nil
   "Contains the buffer name if local word definitions were used.
 Ispell is then restarted because the local words could conflict.")
      (not (boundp 'epoch::version))
      (defalias 'ispell 'ispell-buffer))
 
-
-;; XEmacs: \M-$ for whatever reason, drives `make autoloads' bonkers
+(if (not (fboundp 'buffer-substring-no-properties))
+    (defun buffer-substring-no-properties (start end)
+      (buffer-substring start end)))
 
 ;;;###autoload
-(define-key global-map [(meta ?\$)] 'ispell-word)
+(define-key global-map "\M-$" 'ispell-word)
 
 ;;;###autoload
 (defun ispell-word (&optional following quietly continue)
     (ispell-accept-buffer-local-defs)	; use the correct dictionary
     (let ((cursor-location (point))	; retain cursor location
 	  (word (ispell-get-word following))
-	  start end poss replace)
-      ;; destructure return word info list.
+	  start end poss new-word replace)
+      ;; De-structure return word info list.
       (setq start (car (cdr word))
 	    end (car (cdr (cdr word)))
 	    word (car word))
 	       (accept-process-output ispell-process)
 	       (not (string= "" (car ispell-filter)))))
       ;;(process-send-string ispell-process "!\n") ;back to terse mode.
-      (setq ispell-filter (cdr ispell-filter))
+      (setq ispell-filter (cdr ispell-filter)) ; remove extra \n
       (if (listp ispell-filter)
 	  (setq poss (ispell-parse-output (car ispell-filter))))
       (cond ((eq poss t)
 			  (funcall ispell-format-word poss))))
 	    ((null poss) (message "Error in ispell process"))
 	    (ispell-check-only		; called from ispell minor mode.
-	     (beep))
+	     (beep)
+	     (message "%s is incorrect" (funcall ispell-format-word word)))
 	    (t				; prompt for correct word.
 	     (save-window-excursion
 	       (setq replace (ispell-command-loop
 	     (cond ((equal 0 replace)
 		    (ispell-add-per-file-word-list (car poss)))
 		   (replace
-		    (setq word (if (atom replace) replace (car replace))
+		    (setq new-word (if (atom replace) replace (car replace))
 			  cursor-location (+ (- (length word) (- end start))
 					     cursor-location))
-		    (if (not (equal word (car poss)))
+		    (if (not (equal new-word (car poss)))
 			(progn
 			  (delete-region start end)
-			  (insert word)))
+			  (setq start (point))
+			  (insert new-word)
+			  (setq end (point))))
 		    (if (not (atom replace)) ; recheck spelling of replacement
 			(progn
-			  (goto-char cursor-location)
-			  (ispell-word following quietly)))))
+			  (if (car (cdr replace)) ; query replace requested
+			      (save-window-excursion
+				(query-replace word new-word t)))
+			  (ispell-region start end)))))
 	     (if (get-buffer ispell-choices-buffer)
 		 (kill-buffer ispell-choices-buffer))))
       (goto-char cursor-location)	; return to original location
 	(error "No word found to check!"))
     (setq start (match-beginning 0)
 	  end (point)
-	  word (buffer-substring start end))
+	  word (buffer-substring-no-properties start end))
     (list word start end)))
 
 
 ;;; a value or a list, whose value is the state of whether the
 ;;; dictionary needs to be saved.
 
+;;; ###autoload
 (defun ispell-pdict-save (&optional no-query force-save)
   "Check to see if the personal dictionary has been modified.
 If so, ask if it needs to be saved."
 Returns 0 to insert locally into buffer-local dictionary.
 Returns string for new chosen word.
 Returns list for new replacement word (will be rechecked).
+  Query-replace when list length is 2.
+  Automatic query-replace when second element is 'query-replace.
 Highlights the word, which is assumed to run from START to END.
 Global `ispell-pdict-modified-p' becomes a list where the only value
 indicates whether the dictionary has been modified when option `a' or `i' is
-used."
+used.
+Global `ispell-quit' set to start location to continue spell session."
   (let ((textbuf (current-buffer))
 	(count ?0)
 	(line 2)
 	(window-min-height (min window-min-height
 				ispell-choices-win-default-height))
 	(command-characters '( ?  ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m ))
+	(dedicated (window-dedicated-p (selected-window)))
 	(skipped 0)
-	char num result textwin highlighted)
+	char num result textwin dedicated-win highlighted)
 
     ;; setup the *Choices* buffer with valid data.
     (save-excursion
       (set-buffer (get-buffer-create ispell-choices-buffer))
       (setq mode-line-format (concat "--  %b  --  word: " word))
-      ;; XEmacs: turn off the modeline
-      (and (fboundp 'set-specifier)
+      (and (fboundp 'set-specifier)	; prevent XEmacs modeline hiding
 	   (set-specifier has-modeline-p (cons (current-buffer) nil)))
       (erase-buffer)
       (if guess
 		     max-lines))
 	;; not so good if there are over 20 or 30 options, but then, if
 	;; there are that many you don't want to scan them all anyway...
-	(when (integerp count)
-	  (setq count (int-char count)))
 	(while (memq count command-characters) ; skip command characters.
-	  (setq count (int-char (1+ count))
+	  (setq count (1+ count)
 		skipped (1+ skipped)))
 	(insert "(" count ") " (car choices) "  ")
 	(setq choices (cdr choices)
 	      count (1+ count)))
-      (setq count (int-char (- count ?0 skipped))))
+      (setq count (- count ?0 skipped)))
 
     ;; Assure word is visible
     (if (not (pos-visible-in-window-p end))
 	(sit-for 0))
+    
+    ;; allow temporary split of dedicated windows...
+    (if dedicated
+	(progn
+	  (setq dedicated-win (selected-window))
+	  (set-window-dedicated-p dedicated-win nil)))
+
     ;; Display choices for misspelled word.
-    (let ((choices-window (get-buffer-window ispell-choices-buffer)))
-      (if choices-window
-	  (if (= line (window-height choices-window))
-	      (select-window choices-window)
-	    ;; *Choices* window changed size.  Adjust the choices window
-	    ;; without scrolling the spelled window when possible
-	    (let ((window-line (- line (window-height choices-window)))
-		  (visible (progn (forward-line -1) (point))))
-	      (if (< line ispell-choices-win-default-height)
-		  (setq window-line (+ window-line
-				       (- ispell-choices-win-default-height
-					  line))))
-	      (move-to-window-line 0)
-	      (forward-line window-line)
-	      (set-window-start (selected-window)
-				(if (> (point) visible) visible (point)))
-	      (goto-char end)
-	      (select-window (previous-window)) ; *Choices* window
-	      (enlarge-window window-line)))
-	;; Overlay *Choices* window when it isn't showing
-	(ispell-overlay-window (max line ispell-choices-win-default-height)))
-      (switch-to-buffer ispell-choices-buffer)
-      (goto-char (point-min)))
+    (ispell-show-choices line end)
 
     (select-window (setq textwin (next-window)))
 
     ;; highlight word, protecting current buffer status
     (unwind-protect
 	(progn
-	  (if ispell-highlight-p
-	      (ispell-highlight-spelling-error start end t))
+	  (and ispell-highlight-p
+	       (ispell-highlight-spelling-error start end t))
 	  ;; Loop until a valid choice is made.
 	  (while
 	      (eq
 		result
 		(progn
 		  (undo-boundary)
-		  (message (concat "C-h or ? for more options; SPC to leave "
-				   "unchanged, Character to replace word"))
+		  (let (message-log-max)
+		    (message (concat "C-h or ? for more options; SPC to leave "
+				     "unchanged, Character to replace word")))
 		  (let ((inhibit-quit t))
 		    (setq char (if (fboundp 'read-char-exclusive)
 				   (read-char-exclusive)
 				 (read-char))
 			  skipped 0)
-		    (if (or quit-flag (eq char ?\C-g)) ; C-g is like typing X
+		    (if (or quit-flag (= char ?\C-g)) ; C-g is like typing X
 			(setq char ?X
 			      quit-flag nil)))
 		  ;; Adjust num to array offset skipping command characters.
 		    (setq num (- char ?0 skipped)))
 
 		  (cond
-		   ((eq char ? ) nil)	; accept word this time only
-		   ((eq char ?i)	; accept and insert word into pers dict
+		   ((= char ? ) nil)	; accept word this time only
+		   ((= char ?i)		; accept and insert word into pers dict
 		    (process-send-string ispell-process (concat "*" word "\n"))
 		    (setq ispell-pdict-modified-p '(t)) ; dictionary modified!
 		    nil)
-		   ((or (eq char ?a) (eq char ?A)) ; accept word without insert
+		   ((or (= char ?a) (= char ?A)) ; accept word without insert
 		    (process-send-string ispell-process (concat "@" word "\n"))
 		    (if (null ispell-pdict-modified-p)
 			(setq ispell-pdict-modified-p
 			      (list ispell-pdict-modified-p)))
-		    (if (eq char ?A) 0)) ; return 0 for ispell-add buffer-local
-		   ((or (eq char ?r) (eq char ?R)) ; type in replacement
-		    (if (or (eq char ?R) ispell-query-replace-choices)
-			(list (read-string "Query-replacement for: " word) t)
-		      (cons (read-string "Replacement for: " word) nil)))
-		   ((or (eq char ??)
-			;; XEmacs change: help-char may not be an int.
-			(eq char (event-to-character
-				  (character-to-event help-char)))
-			(eq char ?\C-h))
+		    (if (= char ?A) 0))	; return 0 for ispell-add buffer-local
+		   ((or (= char ?r) (= char ?R)) ; type in replacement
+		    (and (eq 'block ispell-highlight-p) ; refresh tty's
+			 (ispell-highlight-spelling-error start end nil t))
+		    (let ((result
+			   (if (or (= char ?R) ispell-query-replace-choices)
+			       (list (read-string "Query-replacement for: "
+						  word) t)
+			     (cons (read-string "Replacement for: " word)
+				   nil))))
+		      (and (eq 'block ispell-highlight-p)
+			   (ispell-highlight-spelling-error start end nil
+							    'block))
+		      result))
+		   ((or (= char ??) (= char help-char) (= char ?\C-h))
+		    (and (eq 'block ispell-highlight-p)
+			 (ispell-highlight-spelling-error start end nil t))
 		    (ispell-help)
+		    (and (eq 'block ispell-highlight-p)
+			 (ispell-highlight-spelling-error start end nil
+							  'block))
 		    t)
 		   ;; Quit and move point back.
-		   ((eq char ?x)
+		   ((= char ?x)
 		    (ispell-pdict-save ispell-silently-savep)
 		    (message "Exited spell-checking")
 		    (setq ispell-quit t)
 		    nil)
 		   ;; Quit and preserve point.
-		   ((eq char ?X)
+		   ((= char ?X)
 		    (ispell-pdict-save ispell-silently-savep)
 		    (message "%s"
 		     (substitute-command-keys
 		      (concat "Spell-checking suspended;"
 			      " use C-u \\[ispell-word] to resume")))
-		    (setq ispell-quit (max (point-min)
-					   (- (point) (length word))))
+		    (setq ispell-quit start)
 		    nil)
-		   ((eq char ?q)
+		   ((= char ?q)
 		    (if (y-or-n-p "Really kill Ispell process? ")
 			(progn
 			  (ispell-kill-ispell t) ; terminate process.
 						(point))
 				ispell-pdict-modified-p nil))
 		      t))		; continue if they don't quit.
-		   ((eq char ?l)
+		   ((= char ?l)
+		    (and (eq 'block ispell-highlight-p) ; refresh tty displays
+			 (ispell-highlight-spelling-error start end nil t))
 		    (let ((new-word (read-string
 				     "Lookup string (`*' is wildcard): "
 				     word))
 					       new-line)
 					     max-lines))
 				(while (memq count command-characters)
-				  (setq count (int-char (1+ count))
+				  (setq count (1+ count)
 					skipped (1+ skipped)))
 				(insert "(" count ") " (car choices) "  ")
 				(setq choices (cdr choices)
 				    (shrink-window (- line new-line shr-bl)))
 				  (setq line new-line)))
 			    (select-window (next-window)))))
+		    (and (eq 'block ispell-highlight-p)
+			 (ispell-highlight-spelling-error start end nil
+							  'block))
 		    t)			; reselect from new choices
-		   ((eq char ?u)
+		   ((= char ?u)
 		    (process-send-string ispell-process
 					 (concat "*" (downcase word) "\n"))
 		    (setq ispell-pdict-modified-p '(t)) ; dictionary modified!
 		    nil)
-		   ((eq char ?m)	; type in what to insert
+		   ((= char ?m)		; type in what to insert
 		    (process-send-string
 		     ispell-process (concat "*" (read-string "Insert: " word)
 					    "\n"))
 		    (if ispell-query-replace-choices ; Query replace flag
 			(list (nth num miss) 'query-replace)
 		      (nth num miss)))
-		   ((eq char ?\C-l)
+		   ((= char ?\C-l)
 		    (redraw-display) t)
-		   ((eq char ?\C-r)
-		    (save-window-excursion (recursive-edit)) t)
-		   ((eq char ?\C-z)
+		   ((= char ?\C-r)
+		    (if (marker-position ispell-recursive-edit-marker)
+			(progn
+			  (message "Only one recursive edit session supported")
+			  (beep))
+		      (set-marker ispell-recursive-edit-marker start)
+		      ;;(set-marker ispell-region-end reg-end)
+		      (and ispell-highlight-p		; unhighlight
+			   (ispell-highlight-spelling-error start end))
+		      (unwind-protect
+			  (progn
+			    (save-window-excursion (save-excursion
+						     (recursive-edit)) t)
+			    (if (not (equal (marker-buffer
+					     ispell-recursive-edit-marker)
+					    (current-buffer)))
+				(error
+				 "Cannot continue ispell from this buffer."))
+			    (goto-char ispell-recursive-edit-marker))
+			(set-marker ispell-recursive-edit-marker nil)))
+		    (cons word nil))	; recheck starting at this word.
+		   ((= char ?\C-z)
 		    (funcall (key-binding "\C-z"))
 		    t)
 		   (t (ding) t))))))
 	  result)
       ;; protected
-      (if ispell-highlight-p		; unhighlight
-	  (save-window-excursion
-	    (select-window textwin)
-	    (ispell-highlight-spelling-error start end))))))
+      (and ispell-highlight-p		; unhighlight
+	   (save-window-excursion
+	     (select-window textwin)
+	     (ispell-highlight-spelling-error start end)))
+      (if dedicated
+	  (set-window-dedicated-p dedicated-win t)))))
+
+
+
+(defun ispell-show-choices (line end)
+  "Shows the choices in another buffer or frame."
+  (if ispell-use-framepop-p
+      (progn
+	(framepop-display-buffer (get-buffer ispell-choices-buffer))
+	(get-buffer-window ispell-choices-buffer t)
+	(select-window (previous-window))) ; *Choices* window
+    ;; standard selection by splitting a small buffer out of this window.
+    (let ((choices-window (get-buffer-window ispell-choices-buffer)))
+      (if choices-window
+	  (if (= line (window-height choices-window))
+	      (select-window choices-window)
+	    ;; *Choices* window changed size.  Adjust the choices window
+	    ;; without scrolling the spelled window when possible
+	    (let ((window-line (- line (window-height choices-window)))
+		  (visible (progn (forward-line -1) (point))))
+	      (if (< line ispell-choices-win-default-height)
+		  (setq window-line (+ window-line
+				       (- ispell-choices-win-default-height
+					  line))))
+	      (move-to-window-line 0)
+	      (forward-line window-line)
+	      (set-window-start (selected-window)
+				(if (> (point) visible) visible (point)))
+	      (goto-char end)
+	      (select-window (previous-window)) ; *Choices* window
+	      (enlarge-window window-line)))
+	;; Overlay *Choices* window when it isn't showing
+	(ispell-overlay-window (max line ispell-choices-win-default-height)))
+      (switch-to-buffer ispell-choices-buffer)
+      (goto-char (point-min)))))
 
 
 ;;;###autoload
 `q':   Quit spelling session (Kills ispell process).
 `l':   Look up typed-in replacement in alternate dictionary.  Wildcards okay.
 `u':   Like `i', but the word is lower-cased first.
-`m':   Like `i', but allows one to include dictionary completion information.
+`m':   Place typed-in value in personal dictionary, then recheck current word.
 `C-l':  redraws screen
 `C-r':  recursive edit
 `C-z':  suspend emacs or iconify frame"
 
-  (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
-			"[i]nsert into private dictionary"))
-	(help-2 (concat "[l]ook a word up in alternate dictionary;  "
-			"e[x/X]it;  [q]uit session"))
-	(help-3 (concat "[u]ncapitalized insert into dictionary.  "
-			"Type 'C-h d ispell-help' for more help")))
-    (save-window-excursion
-      (if ispell-help-in-bufferp
-	  (progn
-	    (ispell-overlay-window 4)
-	    (switch-to-buffer (get-buffer-create "*Ispell Help*"))
-	    (insert (concat help-1 "\n" help-2 "\n" help-3))
-	    (sit-for 5)
-	    (kill-buffer "*Ispell Help*"))
-	(select-window (minibuffer-window))
-	;;(enlarge-window 2)
-	(erase-buffer)
-	(cond ((and (< emacs-minor-version 12)
-		    (string-match "Lucid" emacs-version))
-	       (message help-3)
-	       (enlarge-window 1)
-	       (message help-2)
-	       (enlarge-window 1)
-	       (message help-1)
-	       (goto-char (point-min)))
-	      (t
-	       (if (string-lessp "19" emacs-version)
-		   (message nil))
-	       (enlarge-window 2)
-	       ;; Make sure we display the minibuffer
-	       ;; in this window, not some other.
-	       (if (fboundp 'set-minibuffer-window)
-		   (set-minibuffer-window (selected-window)))
-	       (insert (concat help-1 "\n" help-2 "\n" help-3))))
-	(sit-for 5)
-	(erase-buffer)))))
+  (if (equal ispell-help-in-bufferp 'electric)
+      (progn
+	(require 'ehelp)
+	(with-electric-help 
+	 (function (lambda ()
+		     ;;This shouldn't be necessary: with-electric-help needs
+		     ;; an optional argument telling it about the smallest
+		     ;; acceptable window-height of the help buffer.
+		     (if (< (window-height) 15)
+			 (enlarge-window (- 15 (window-height))))
+		     (princ "Selections are:
+
+DIGIT: Replace the word with a digit offered in the *Choices* buffer.
+SPC:   Accept word this time.
+`i':   Accept word and insert into private dictionary.
+`a':   Accept word for this session.
+`A':   Accept word and place in `buffer-local dictionary'.
+`r':   Replace word with typed-in value.  Rechecked.
+`R':   Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+`?':   Show these commands.
+`x':   Exit spelling buffer.  Move cursor to original point.
+`X':   Exit spelling buffer.  Leaves cursor at the current point, and permits
+        the aborted check to be completed later.
+`q':   Quit spelling session (Kills ispell process).
+`l':   Look up typed-in replacement in alternate dictionary.  Wildcards okay.
+`u':   Like `i', but the word is lower-cased first.
+`m':   Place typed-in value in personal dictionary, then recheck current word.
+`C-l':  redraws screen
+`C-r':  recursive edit
+`C-z':  suspend emacs or iconify frame")
+		     nil	;undocumented requirement of with-electric-help
+		     ))))
+
+
+    (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
+			  "[i]nsert into private dictionary"))
+	  (help-2 (concat "[l]ook a word up in alternate dictionary;  "
+			  "e[x/X]it;  [q]uit session"))
+	  (help-3 (concat "[u]ncapitalized insert into dict.  "
+			  "Type 'x C-h d ispell-help' for more help")))
+      (save-window-excursion
+	(if ispell-help-in-bufferp
+	    (progn
+	      (ispell-overlay-window 4)
+	      (switch-to-buffer (get-buffer-create "*Ispell Help*"))
+	      (insert (concat help-1 "\n" help-2 "\n" help-3))
+	      (sit-for 5)
+	      (kill-buffer "*Ispell Help*"))
+	  (select-window (minibuffer-window))
+	  ;;(enlarge-window 2)
+	  (erase-buffer)
+	  (cond ((string-match "Lucid" emacs-version)
+		 (message help-3)
+		 (enlarge-window 1)
+		 (message help-2)
+		 (enlarge-window 1)
+		 (message help-1)
+		 (goto-char (point-min)))
+		(t
+		 (if (string-lessp "19" emacs-version)
+		     (message nil))
+		 ;;(set-minibuffer-window (selected-window))
+		 (enlarge-window 2)
+		 (insert (concat help-1 "\n" help-2 "\n" help-3))))
+	  (sit-for 5)
+	  (erase-buffer))))))
 
 
 (defun lookup-words (word &optional lookup-dict)
 	    (while (not (bobp))
 	      (setq loc (point))
 	      (forward-line -1)
-	      (setq results (cons (buffer-substring (point) (1- loc))
+	      (setq results (cons (buffer-substring-no-properties (point)
+								  (1- loc))
 				  results)))))
       ;; protected
       (kill-buffer ispell-grep-buffer)
 ;;;   multiple lines.
 ;;; "ispell-filter-continue" is true when we have received only part of a
 ;;;   line as output from a generating function ("output" did not end with \n)
-;;; THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESN'T END WITH \n!
+;;; THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESNT END WITH \n!
 ;;;   This is the case when a process dies or fails. The default behavior
 ;;;   in this case treats the next input received as fresh input.
 
 
 ;;; This function destroys the mark location if it is in the word being
 ;;; highlighted.
-(defun ispell-highlight-spelling-error-generic (start end &optional highlight)
+(defun ispell-highlight-spelling-error-generic (start end &optional highlight
+						      refresh)
   "Highlight the word from START to END with a kludge using `inverse-video'.
 When the optional third arg HIGHLIGHT is set, the word is highlighted;
-otherwise it is displayed normally."
+otherwise it is displayed normally.
+Uses block cursor to highlight one charcater.
+Optional REFRESH will unhighlighted then highlight, using block cursor
+ highlighting when REFRESH is equal to 'block."
+  (and (eq 'block ispell-highlight-p)
+       (or (eq 'block refresh)
+	   (setq start (1+ start))))	; On block non-refresh, inc start.
   (let ((modified (buffer-modified-p))	; don't allow this fn to modify buffer
 	(buffer-read-only nil)		; Allow highlighting read-only buffers.
-	(text (buffer-substring start end)) ; Save highlight region
+	(text (buffer-substring-no-properties start end)) ; Save hilight region
 	(inhibit-quit t)		; inhibit interrupt processing here.
 	(buffer-undo-list t))		; don't clutter the undo list.
+    (goto-char end)
     (delete-region start end)
-    (insert-char ?  (- end start))	; mimimize amount of redisplay
+    (insert-char ?  (- end start))	; minimize amount of redisplay
     (sit-for 0)				; update display
     (if highlight (setq inverse-video (not inverse-video))) ; toggle video
     (delete-region start end)		; delete whitespace
     (insert text)			; insert text in inverse video.
     (sit-for 0)				; update display showing inverse video.
-    (if highlight (setq inverse-video (not inverse-video))) ; toggle video
-    (set-buffer-modified-p modified)))	; don't modify if flag not set.
+    (if (not highlight)
+	(goto-char end)
+      (setq inverse-video (not inverse-video)) ; toggle video
+      (and (eq 'block ispell-highlight-p)
+	   (goto-char (1- start))))	; use block cursor to "highlight" char
+    (set-buffer-modified-p modified)	; don't modify if flag not set.
+    (and refresh			; re-highlight
+	 (ispell-highlight-spelling-error-generic
+	  (if (eq 'block refresh) start (- start 2)) end t))))
 
 
 (defun ispell-highlight-spelling-error-lucid (start end &optional highlight)
     (delete-overlay ispell-overlay)))
 
 
-(defun ispell-highlight-spelling-error (start end &optional highlight)
+(defun ispell-highlight-spelling-error (start end &optional highlight refresh)
   (cond
    ((string-match "Lucid" emacs-version)
     (ispell-highlight-spelling-error-lucid start end highlight))
    ((and (string-lessp "19" emacs-version)
 	 (featurep 'faces) window-system)
     (ispell-highlight-spelling-error-overlay start end highlight))
-   (t (ispell-highlight-spelling-error-generic start end highlight))))
+   (t (ispell-highlight-spelling-error-generic start end highlight refresh))))
 
 
 (defun ispell-overlay-window (height)
       ;; hidden by new window, scroll it to just below new win
       ;; otherwise set top line of other win so it doesn't scroll.
       (if (< oldot top) (setq top oldot))
-      ;; NB: Lemacs 19.9 bug: If a window of size N (N includes the mode
+      ;; NB: xemacs 19.9 bug: If a window of size N (N includes the mode
       ;; line) is demanded, the last line is not visible.
-      ;; At least this happens on AIX 3.2, lemacs w/ Motif, font 9x15.
+      ;; At least this happens on AIX 3.2, xemacs w/ Motif, font 9x15.
       ;; So we increment the height for this case.
       (if (string-match "19\.9.*Lucid" (emacs-version))
 	  (setq height (1+ height)))
-      (split-window nil height)
+      ;; if frame is unsplitable, temporarily disable that...
+      (if (cdr (assq 'unsplittable (frame-parameters (selected-frame))))
+	  (let ((frame (selected-frame)))
+	    (modify-frame-parameters frame '((unsplittable . nil)))
+	    (split-window nil height)
+	    (modify-frame-parameters frame '((unsplittable . t))))
+	(split-window nil height))
       (set-window-start (next-window) top))))
 
 
 ;;; Should we add a compound word match return value?
 (defun ispell-parse-output (output)
-  "Parse the OUTPUT string from Ispell and return:
+  "Parse the OUTPUT string from Ispell process and return:
 1: t for an exact match.
-2: A string containing the root word for a match via suffix removal.
+2: A string containing the root word matched via suffix removal.
 3: A list of possible correct spellings of the format:
    '(\"ORIGINAL-WORD\" OFFSET MISS-LIST GUESS-LIST)
    ORIGINAL-WORD is a string of the possibly misspelled word.
    OFFSET is an integer giving the line offset of the word.
-   MISS-LIST and GUESS-LIST are possibly null lists of guesses and misses."
+   MISS-LIST and GUESS-LIST are possibly null lists of guesses and misses.
+4: Nil when an error has occurred."
   (cond
    ((string= output "") t)		; for startup with pipes...
    ((string= output "*") t)		; exact match
-   ((string= output "-") t)             ; compound word match
-   ((string= (substring output 0 1) "+") ; found cuz of root word
+   ((string= output "-") t)		; compound word match
+   ((string= (substring output 0 1) "+") ; found because of root word
     (substring output 2))		; return root word
+   ((equal 0 (string-match "[
+    (ding)				; error message from ispell!
+    (message (concat "Ispell error: " output))
+    (sit-for 5)
+    nil)
    (t					; need to process &, ?, and #'s
     (let ((type (substring output 0 1))	; &, ?, or #
 	  (original-word (substring output 2 (string-match " " output 2)))
       (list original-word offset miss-list guess-list)))))
 
 
-(defun check-ispell-version ()
+(defun check-ispell-version (&optional interactivep)
   ;; This is a little wasteful as we actually launch ispell twice: once
   ;; to make sure it's the right version, and once for real.  But people
   ;; get confused by version mismatches *all* the time (and I've got the
   ;; option is the only way I can think of to do this that works with
   ;; all versions, since versions earlier than 3.0.09 didn't identify
   ;; themselves on startup.
+  (interactive "p")
   (save-excursion
-    (let ((case-fold-search t)
+    (let (case-fold-search status
 	  ;; avoid bugs when syntax of `.' changes in various default modes
 	  (default-major-mode 'fundamental-mode)
-	  status)
+	  (result t))
       (set-buffer (get-buffer-create " *ispell-tmp*"))
+      (setq case-fold-search t)
       (erase-buffer)
       (setq status (call-process ispell-program-name nil t nil "-v"))
       (goto-char (point-min))
+      (if interactivep
+	  (progn
+	    (end-of-line)
+	    (setq result (concat (buffer-substring-no-properties (point-min)
+								 (point))
+				 ", "
+				 ispell-version))
+	    (message result)
+	    (goto-char (point-min))))
       (if (not (memq status '(0 nil)))
 	  (error "%s exited with %s %s" ispell-program-name
 		 (if (stringp status) "signal" "code") status))
       (if (not (re-search-forward
-		(concat "\\b\\("
+		(concat "\\<\\("
 			(regexp-quote (car ispell-required-version))
-			"\\)\\([0-9]*\\)\\b")
+			"\\)\\([0-9]*\\)\\>")
 		nil t))
-	  (error
-	   "%s version %s* is required: try renaming ispell4.el to ispell.el"
-	   ispell-program-name (car ispell-required-version))
+	  (error "%s version 3 release %s%s or greater is required"
+		 ispell-program-name (car ispell-required-version)
+		 (car (cdr ispell-required-version)))
 	;; check that it is the correct version.
-	(if (< (car (read-from-string (buffer-substring
+	(if (< (car (read-from-string (buffer-substring-no-properties
 				       (match-beginning 2) (match-end 2))))
 	       (car (cdr ispell-required-version)))
 	    (setq ispell-offset 0)))
-      (kill-buffer (current-buffer)))))
+      (kill-buffer (current-buffer))
+      result)))
 
 
 (defun ispell-init-process ()
 	  ispell-filter-continue nil
 	  ispell-process-directory default-directory)
     (set-process-filter ispell-process 'ispell-filter)
-    (accept-process-output ispell-process) ; Get version ID line
+    (if (and (boundp 'enable-multibyte-characters)
+	     (fboundp 'set-process-coding-system)
+	     enable-multibyte-characters
+	     (ispell-get-coding-system))
+	(set-process-coding-system ispell-process (ispell-get-coding-system)))
+    (if (string-lessp "19" emacs-version) ; Get version ID line
+	(accept-process-output ispell-process 5)
+      (accept-process-output ispell-process))
+    ;; get more output if filter empty?
+    (if (null ispell-filter) (accept-process-output ispell-process 5))
     (cond ((null ispell-filter)
 	   (error "%s did not output version line" ispell-program-name))
 	  ((and
 	    (stringp (car ispell-filter))
 	    (if (string-match "warning: " (car ispell-filter))
 		(progn
-		  (accept-process-output ispell-process 5) ; 1st was warn msg.
+		  (if (string-lessp "19" emacs-version)
+		      (accept-process-output ispell-process 5) ; was warn msg.
+		    (accept-process-output ispell-process))
 		  (stringp (car ispell-filter)))
 	      (null (cdr ispell-filter)))
 	    (string-match "^@(#) " (car ispell-filter)))
 		   (setq ispell-dictionary dict))
 	       (if (null arg)		; set local dictionary
 		   (setq ispell-local-dictionary dict)))
-	   (error "Illegal dictionary: %s" dict))
+	   (error "Undefined dictionary: %s" dict))
 	 (ispell-kill-ispell t)
 	 (message "(Next %sIspell command will use %s dictionary)"
 		  (cond ((equal ispell-local-dictionary ispell-dictionary)
 	(save-window-excursion
 	  (goto-char reg-start)
 	  (let ((transient-mark-mode nil)
-		ref-type)
-	    (while (and (not ispell-quit) (< (point) reg-end))
-	      (let ((start (point))
-		    (offset-change 0)
-		    (end (save-excursion (end-of-line) (min (point) reg-end)))
-		    (ispell-casechars (ispell-get-casechars))
-		    string)
-		(cond			; LOOK AT THIS LINE AND SKIP OR PROCESS
-		 ((eolp)		; END OF LINE, just go to next line.
-		  (forward-char 1))
-		 ((and (null ispell-check-comments) ; SKIPPING COMMENTS
-		       comment-start	; skip comments that start on the line.
-		       (search-forward comment-start end t)) ; or found here.
-		  (if (= (- (point) start) (length comment-start))
-		      ;; comment starts the line.  Skip entire line or region
-		      (if (string= "" comment-end) ; skip to next line
-			  (beginning-of-line 2)	; or jump to comment end.
-			(search-forward comment-end reg-end 'limit))
-		    ;; Comment later in line.  Check spelling before comment.
-		    (let ((limit (- (point) (length comment-start))))
-		      (goto-char (1- limit))
-		      (if (looking-at "\\\\") ; "quoted" comment, don't skip
-			  ;; quoted comment.  Skip over comment-start
-			  (if (= start (1- limit))
-			      (setq limit (+ limit (length comment-start)))
-			    (setq limit (1- limit))))
-		      (goto-char start)
-		      ;; Only check when "casechars" or math before comment
-		      (if (or (re-search-forward ispell-casechars limit t)
-			      (re-search-forward "[][()$]" limit t))
-			  (setq string
-				(concat "^" (buffer-substring start limit)
-					"\n")
-				offset-change (- offset-change ispell-offset)))
-		      (goto-char limit))))
-		 ((looking-at "[---#@*+!%~^]") ; SKIP SPECIAL ISPELL CHARACTERS
-		  (forward-char 1))
-		 ((or (and ispell-skip-tib ; SKIP TIB REFERENCES OR SGML MARKUP
-			   (re-search-forward ispell-tib-ref-beginning end t)
-			   (setq ref-type 'tib))
-		      (and ispell-skip-sgml
-			   (re-search-forward "[<&]" end t)
-			   (setq ref-type 'sgml)))
-		  (if (or (and (eq 'tib ref-type) ; tib tag is 2 chars.
-			       (= (- (point) 2) start))
-			  (and (eq 'sgml ref-type) ; sgml skips 1 char.
-			       (= (- (point) 1) start)))
-		      ;; Skip to end of reference, not necessarily on this line
-		      ;; Return an error if tib/sgml reference not found
-		      (if (or
-			   (and
-			    (eq 'tib ref-type)
-			    (not
-			     (re-search-forward ispell-tib-ref-end reg-end t)))
-			   (and (eq 'sgml ref-type)
-				(not (re-search-forward "[>;]" reg-end t))))
-			  (progn
-			    (ispell-pdict-save ispell-silently-savep)
-			    (ding)
-			    (message
-			     (concat
-			      "Open tib or SGML command.  Fix buffer or set "
-			      (if (eq 'tib ref-type)
-				  "ispell-skip-tib"
-				"ispell-skip-sgml")
-			      " to nil"))
-			    ;; keep cursor at error location
-			    (setq ispell-quit (- (point) 2))))
-		    ;; Check spelling between reference and start of the line.
-		    (let ((limit (- (point) (if (eq 'tib ref-type) 2 1))))
-		      (goto-char start)
-		      (if (or (re-search-forward ispell-casechars limit t)
-			      (re-search-forward "[][()$]" limit t))
-			  (setq string
-				(concat "^" (buffer-substring start limit)
-					"\n")
-				offset-change (- offset-change ispell-offset)))
-		      (goto-char limit))))
-		 ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS
-		      (re-search-forward "[][()$]" end t)) ; or MATH COMMANDS
-		  (setq string (concat "^" (buffer-substring start end) "\n")
-			offset-change (- offset-change ispell-offset))
-		  (goto-char end))
-		 (t (beginning-of-line 2))) ; EMPTY LINE, skip it.
-
-		(setq end (point))	; "end" tracks end of region to check.
-
-		(if string		; there is something to spell!
-		    (let (poss)
-		      ;; send string to spell process and get input.
-		      (process-send-string ispell-process string)
-		      (while (progn
-			       (accept-process-output ispell-process)
-			       ;; Last item of output contains a blank line.
-			       (not (string= "" (car ispell-filter)))))
-		      ;; parse all inputs from the stream one word at a time.
-		      ;; Place in FIFO order and remove the blank item.
-		      (setq ispell-filter (nreverse (cdr ispell-filter)))
-		      (while (and (not ispell-quit) ispell-filter)
-			(setq poss (ispell-parse-output (car ispell-filter)))
-			(if (listp poss) ; spelling error occurred.
-			    (let* ((word-start (+ start offset-change
-						  (car (cdr poss))))
-				   (word-end (+ word-start
-						(length (car poss))))
-				   replace)
-			      (goto-char word-start)
-			      ;; Adjust the horizontal scroll & point
-			      (ispell-horiz-scroll)
-			      (goto-char word-end)
-			      (ispell-horiz-scroll)
-			      (goto-char word-start)
-			      (ispell-horiz-scroll)
-			      (if (/= word-end
-				      (progn
-					(search-forward (car poss) word-end t)
-					(point)))
-				  ;; This occurs due to filter pipe problems
-				  (error
-				   (concat "Ispell misalignment: word "
-					   "`%s' point %d; please retry")
-				   (car poss) word-start))
-			      (if (not (pos-visible-in-window-p))
-				  (sit-for 0))
-			      (if ispell-keep-choices-win
-				  (setq replace
-					(ispell-command-loop
-					 (car (cdr (cdr poss)))
-					 (car (cdr (cdr (cdr poss))))
-					 (car poss) word-start word-end))
-				(save-window-excursion
-				  (setq replace
-					(ispell-command-loop
-					 (car (cdr (cdr poss)))
-					 (car (cdr (cdr (cdr poss))))
-					 (car poss) word-start word-end))))
-			      (cond
-			       ((and replace (listp replace))
-				;; REPLACEMENT WORD entered.  Recheck line
-				;; starting with the replacement word.
-				(setq ispell-filter nil
-				      string (buffer-substring word-start
-							       word-end))
-				(let ((change (- (length (car replace))
-						 (length (car poss)))))
-				  ;; adjust regions
-				  (setq reg-end (+ reg-end change)
-					offset-change (+ offset-change
-							 change)))
-				(if (not (equal (car replace) (car poss)))
-				    (progn
-				      (delete-region word-start word-end)
-				      (insert (car replace))))
-				;; I only need to recheck typed-in replacements
-				(if (not (eq 'query-replace
-					     (car (cdr replace))))
-				    (backward-char (length (car replace))))
-				(setq end (point)) ; reposition for recheck
-				;; when second arg exists, query-replace, saving regions
-				(if (car (cdr replace))
-				    (unwind-protect
-					(save-window-excursion
-					  (set-marker
-					   ispell-query-replace-marker reg-end)
-					  ;; Assume case-replace &
-					  ;; case-fold-search correct?
-					  (query-replace string (car replace)
-							 t))
-				      (setq reg-end
-					    (marker-position
-					     ispell-query-replace-marker))
-				      (set-marker ispell-query-replace-marker
-						  nil))))
-			       ((or (null replace)
-				    (equal 0 replace)) ; ACCEPT/INSERT
-				(if (equal 0 replace) ; BUFFER-LOCAL DICT ADD
-				    (setq reg-end
-					  (ispell-add-per-file-word-list
-					   (car poss) reg-end)))
-				;; This avoids pointing out the word that was
-				;; just accepted (via 'i' or 'a') if it follows
-				;; on the same line.
-				;; Redo check following the accepted word.
-				(if (and ispell-pdict-modified-p
-					 (listp ispell-pdict-modified-p))
-				    ;; Word accepted.  Recheck line.
-				    (setq ispell-pdict-modified-p ; update flag
-					  (car ispell-pdict-modified-p)
-					  ispell-filter nil ; discontinue check
-					  end word-start))) ; reposition loc.
-			       (replace	; STRING REPLACEMENT for this word.
-				(delete-region word-start word-end)
-				(insert replace)
-				(let ((change (- (length replace)
-						 (length (car poss)))))
-				  (setq reg-end (+ reg-end change)
-					offset-change (+ offset-change change)
-					end (+ end change)))))
-			      (if (not ispell-quit)
-				  (message "Continuing spelling check using %s dictionary..."
-					   (or ispell-dictionary "default")))
-			      (sit-for 0)))
-			;; finished with line!
-			(setq ispell-filter (cdr ispell-filter)))))
+		(skip-region-start (make-marker))
+		(skip-regexp (ispell-begin-skip-region-regexp))
+		(skip-alist ispell-skip-region-alist)
+		key)
+	    (if (eq ispell-parser 'tex)
+		(setq skip-alist
+		      (append (car ispell-tex-skip-alists)
+			      (car (cdr ispell-tex-skip-alists))
+			      skip-alist)))
+	    (let (message-log-max)
+	      (message "searching for regions to skip"))
+	    (if (re-search-forward skip-regexp reg-end t)
+		(progn
+		  (setq key (buffer-substring-no-properties
+			     (match-beginning 0) (match-end 0)))
+		  (set-marker skip-region-start (- (point) (length key)))
+		  (goto-char reg-start)))
+	    (let (message-log-max)
+	      (message "Continuing spelling check using %s dictionary..."
+		       (or ispell-dictionary "default")))
+	    (set-marker ispell-region-end reg-end)
+	    (while (and (not ispell-quit)
+			(< (point) ispell-region-end))
+	      ;; spell-check region with skipping
+	      (if (and (marker-position skip-region-start)
+		       (<= skip-region-start (point)))
+		  (progn
+		    (ispell-skip-region key skip-alist) ; moves pt past region.
+		    (setq reg-start (point))
+		    (if (and (< reg-start ispell-region-end)
+			     (re-search-forward skip-regexp
+						ispell-region-end t))
+			(progn
+			  (setq key (buffer-substring-no-properties
+				     (car (match-data))
+				     (car (cdr (match-data)))))
+			  (set-marker skip-region-start
+				      (- (point) (length key)))
+			  (goto-char reg-start))
+		      (set-marker skip-region-start nil))))
+	      (setq reg-end (if (marker-position skip-region-start)
+				(min skip-region-start ispell-region-end)
+			      (marker-position ispell-region-end)))
+	      (let* ((start (point))
+		     (end (save-excursion (end-of-line) (min (point) reg-end)))
+		     (string (ispell-get-line start end reg-end)))
+		(setq end (point))	; "end" tracks region retrieved.
+		(if string		; there is something to spell check!
+		    (ispell-process-line string)) ; (special start end)
 		(goto-char end)))))
-	(not ispell-quit))
+	;;(not ispell-quit) ??? kss
+	)
     ;; protected
     (if (get-buffer ispell-choices-buffer)
 	(kill-buffer ispell-choices-buffer))
 	  ;; preserve or clear the region for ispell-continue.
 	  (if (not (numberp ispell-quit))
 	      (set-marker ispell-region-end nil)
-	    ;; Enable ispell-continue.
-	    (set-marker ispell-region-end reg-end)
+	    ;; Ispell-continue enabled - ispell-region-end is set.
 	    (goto-char ispell-quit))
 	  ;; Check for aborting
 	  (if (and ispell-checking-message (numberp ispell-quit))
       (message "Spell-checking done"))))
 
 
+;;; Creates the regexp for skipping a region.
+;;; Makes the skip-regxp local for tex buffers adding in the
+;;; tex expressions to skip as well.
+;;; Call AFTER ispell-buffer-local-parsing.
+(defun ispell-begin-skip-region-regexp ()
+  (let ((skip-regexp (ispell-begin-skip-region)))
+    (if (and (null ispell-check-comments) comment-start)
+	(setq skip-regexp (concat (regexp-quote comment-start) "\\|"
+				  skip-regexp)))
+    (if (and (eq 'exclusive ispell-check-comments) comment-start)
+	(setq skip-regexp (concat (if (string= "" comment-end) "^"
+				    (regexp-quote comment-end))
+				  "\\|" skip-regexp)))
+    (if ispell-skip-tib
+	(setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp)))
+    (if ispell-skip-sgml
+	(setq skip-regexp (concat "[<&]\\|" skip-regexp)))
+    (if (eq ispell-parser 'tex)
+	(setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|"
+				  skip-regexp)))
+    skip-regexp))
+
+
+;;; Regular expression of tex commands to skip.
+;;; Generated from `ispell-tex-skip-alists'
+(defun ispell-begin-tex-skip-regexp ()
+  (concat
+   (mapconcat (function (lambda (lst) (car lst)))
+	      (car ispell-tex-skip-alists)
+	      "\\|")
+   "\\|"
+   (mapconcat (function (lambda (lst)
+			  (concat "\\\\begin[ \t\n]*{[ \t\n]*"
+				  (car lst)
+				  "[ \t\n]*}")))
+	      (car (cdr ispell-tex-skip-alists))
+	      "\\|")))
+
+
+;;; Regular expression of regions to skip for all buffers.
+;;; Each selection should be a key of `ispell-skip-region-alist'
+;;; otherwise, the current line is skipped.
+(defun ispell-begin-skip-region ()