;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2
-;; Copyright (C) 1994-1995, 1997-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1994-1995, 1997-2012 Free Software Foundation, Inc.
;; Author: Ken Stevens <k.stevens@ieee.org>
;; Maintainer: Ken Stevens <k.stevens@ieee.org>
;;; ******* THIS FILE IS WRITTEN FOR ISPELL VERSION 3.1+
(defcustom ispell-highlight-p 'block
- "*Highlight spelling errors when non-nil.
+ "Highlight spelling errors when non-nil.
When set to `block', assumes a block cursor with TTY displays."
:type '(choice (const block) (const :tag "off" nil) (const :tag "on" t))
:group 'ispell)
(defcustom ispell-lazy-highlight (boundp 'lazy-highlight-cleanup)
- "*Controls the lazy-highlighting of spelling errors.
+ "Controls the lazy-highlighting of spelling errors.
When non-nil, all text in the buffer matching the current spelling
error is highlighted lazily using isearch lazy highlighting (see
`lazy-highlight-initial-delay' and `lazy-highlight-interval')."
:version "22.1")
(defcustom ispell-highlight-face (if ispell-lazy-highlight 'isearch 'highlight)
- "*The face used for Ispell highlighting. For Emacsen with overlays.
+ "The face used for Ispell highlighting. For Emacsen with overlays.
Possible values are `highlight', `modeline', `secondary-selection',
`region', and `underline'.
This variable can be set by the user to whatever face they desire.
:group 'ispell)
(defcustom ispell-check-comments t
- "*Spelling of comments checked when non-nil.
+ "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."
(lambda (a) (memq a '(nil t exclusive))))
(defcustom ispell-query-replace-choices nil
- "*Corrections made throughout region when non-nil.
+ "Corrections made throughout region when non-nil.
Uses `query-replace' (\\[query-replace]) for corrections."
:type 'boolean
:group 'ispell)
(defcustom ispell-skip-tib nil
- "*Does not spell check `tib' bibliography references when non-nil.
+ "Does not spell check `tib' bibliography references when non-nil.
Skips any text between strings matching regular expressions
`ispell-tib-ref-beginning' and `ispell-tib-ref-end'.
-TeX users beware: Any field starting with [. will skip until a .] -- even
-your whole buffer -- unless you set `ispell-skip-tib' to nil. That includes
-a [.5mm] type of number...."
+TeX users beware: Any text between [. and .] will be skipped -- even if
+that's your whole buffer -- unless you set `ispell-skip-tib' to nil.
+That includes the [.5mm] type of number..."
:type 'boolean
:group 'ispell)
"Regexp matching the end of a Tib reference.")
(defcustom ispell-keep-choices-win t
- "*When non-nil, the `*Choices*' window remains for spelling session.
+ "If non-nil, keep the `*Choices*' window for the entire spelling session.
This minimizes redisplay thrashing."
:type 'boolean
:group 'ispell)
(defcustom ispell-choices-win-default-height 2
- "*The default size of the `*Choices*' window, including mode line.
+ "The default size of the `*Choices*' window, including the mode line.
Must be greater than 1."
:type 'integer
:group 'ispell)
((file-readable-p "/usr/share/lib/dict/words")
"/usr/share/lib/dict/words")
((file-readable-p "/sys/dict") "/sys/dict"))
- "*Alternate plain word-list dictionary for spelling help."
+ "Alternate plain word-list dictionary for spelling help."
:type '(choice file (const :tag "None" nil))
:group 'ispell)
(defcustom ispell-complete-word-dict nil
- "*Plain word-list dictionary used for word completion if
+ "Plain word-list dictionary used for word completion if
different from `ispell-alternate-dictionary'."
:type '(choice file (const :tag "None" nil))
:group 'ispell)
(defcustom ispell-message-dictionary-alist nil
- "*List used by `ispell-message' to select a new dictionary.
+ "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.
(defcustom ispell-message-fcc-skip 50000
- "*Query before saving Fcc message copy if attachment larger than this value.
+ "Query before saving Fcc message copy if attachment larger than this value.
Always stores Fcc copy of message when nil."
:type '(choice integer (const :tag "off" nil))
:group 'ispell)
:group 'ispell)
(defcustom ispell-look-p (file-exists-p ispell-look-command)
- "*Non-nil means use `look' rather than `grep'.
+ "Non-nil means use `look' rather than `grep'.
Default is based on whether `look' seems to be available."
:type 'boolean
:group 'ispell)
(defcustom ispell-have-new-look nil
- "*Non-nil means use the `-r' option (regexp) when running `look'."
+ "Non-nil means use the `-r' option (regexp) when running `look'."
:type 'boolean
:group 'ispell)
:group 'ispell)
(defcustom ispell-following-word nil
- "*Non-nil means `ispell-word' checks the word around or after point.
+ "Non-nil means `ispell-word' checks the word around or after point.
Otherwise `ispell-word' checks the preceding word."
:type 'boolean
:group 'ispell)
(defcustom ispell-help-in-bufferp nil
- "*Non-nil means display interactive keymap help in a buffer.
+ "Non-nil means display interactive keymap help in a buffer.
The following values are supported:
nil Expand the minibuffer and display a short help message
there for a couple of seconds.
:group 'ispell)
(defcustom ispell-quietly nil
- "*Non-nil means suppress messages in `ispell-word'."
+ "Non-nil means suppress messages in `ispell-word'."
:type 'boolean
:group 'ispell)
(defcustom ispell-format-word-function (function upcase)
- "*Formatting function for displaying word being spell checked.
+ "Formatting function for displaying word being spell checked.
The function must take one string argument and return a string."
:type 'function
:group 'ispell)
;;;###autoload
(defcustom ispell-personal-dictionary nil
- "*File name of your personal spelling dictionary, or nil.
+ "File name of your personal spelling dictionary, or nil.
If nil, the default personal dictionary, (\"~/.ispell_DICTNAME\" for ispell or
\"~/.aspell.LANG.pws\" for aspell) is used, where DICTNAME is the name of your
default dictionary and LANG the two letter language code."
:group 'ispell)
(defcustom ispell-silently-savep nil
- "*When non-nil, save the personal dictionary without confirmation."
+ "When non-nil, save personal dictionary without asking for confirmation."
:type 'boolean
:group 'ispell)
:group 'ispell)
(defcustom ispell-extra-args nil
- "*If non-nil, a list of extra switches to pass to the Ispell program.
+ "If non-nil, a list of extra switches to pass to the Ispell program.
For example, (\"-W\" \"3\") to cause it to accept all 1-3 character
words as correct. See also `ispell-dictionary-alist', which may be used
for language-specific arguments."
(defcustom ispell-skip-html 'use-mode-name
- "*Indicates whether ispell should skip spell checking of SGML markup.
+ "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."
(defcustom ispell-local-dictionary-alist nil
- "*List of local or customized dictionary definitions.
+ "List of local or customized dictionary definitions.
These can override the values in `ispell-dictionary-alist'.
To make permanent changes to your dictionary definitions, you
(defvar ispell-dictionary-base-alist
- '((nil
+ '((nil ; default
;; The default dictionary. It may be English.aff, or any other
;; dictionary depending on locale and such things. We should probably
;; ask ispell what dictionary it's using, but until we do that, let's
- ;; just use an approximate regexp.
- "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-B") nil iso-8859-1)
+ ;; just use a minimal regexp. [:alpha:] will later be set if possible.
+ "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
("american" ; Yankee English
"[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
("brasileiro" ; Brazilian mode
("svenska" ; Swedish mode
"[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
"[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
- "[']" nil ("-C") "~list" iso-8859-1))
+ "[']" nil ("-C") "~list" iso-8859-1)
+ ("hebrew" "[\340\341\342\343\344\345\346\347\350\351\353\352\354\356\355\360\357\361\362\364\363\367\366\365\370\371\372]" "[^\340\341\342\343\344\345\346\347\350\351\353\352\354\356\355\360\357\361\362\364\363\367\366\365\370\371\372]" "" nil ("-B") nil cp1255))
"Base value for `ispell-dictionary-alist'.")
(defvar ispell-dictionary-alist nil
CASECHARS, NOT-CASECHARS, and OTHERCHARS must be unibyte strings
containing bytes of CHARACTER-SET. In addition, if they contain
-a non-ASCII byte, the regular expression must be a single
+non-ASCII bytes, the regular expression must be a single
`character set' construct that doesn't specify a character range
for non-ASCII bytes.
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.
+CHARACTER-SET used to encode text sent to the ispell subprocess
+when the language uses non-ASCII 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\).")
+Note that with \"ispell\" as the speller, 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\). aspell and hunspell don't have this limitation.")
(defvar ispell-really-aspell nil) ; Non-nil if we can use aspell extensions.
(defvar ispell-really-hunspell nil) ; Non-nil if we can use hunspell extensions.
(defvar ispell-encoding8-command nil
- "Command line option prefix to select UTF-8 if supported, nil otherwise.
-If UTF-8 if supported by spellchecker and is selectable from the command line
-this variable will contain \"--encoding=\" for aspell and \"-i \" for hunspell,
-so UTF-8 or other mime charsets can be selected. That will be set for hunspell
->=1.1.6 or aspell >= 0.60 in `ispell-check-version'.
-
-For aspell non-nil means to try to automatically find aspell dictionaries.
-Earlier aspell versions do not consistently support UTF-8. Handling
+ "Command line option prefix to select encoding if supported, nil otherwise.
+If setting the encoding is supported by spellchecker and is selectable from
+the command line, this variable will contain \"--encoding=\" for aspell
+and \"-i \" for hunspell, so the appropriate mime charset can be selected.
+That will be set in `ispell-check-version' for hunspell >= 1.1.6 and
+aspell >= 0.60.
+
+For aspell, non-nil also means to try to automatically find its dictionaries.
+
+Earlier aspell versions do not consistently support charset encoding. Handling
this would require some extra guessing in `ispell-aspell-find-dictionary'.")
(defvar ispell-aspell-supports-utf8 nil
- "Non nil if aspell has consistent command line UTF-8 support. Obsolete.
+ "Non-nil if aspell has consistent command line UTF-8 support. Obsolete.
ispell.el and flyspell.el will use for this purpose the more generic
variable `ispell-encoding8-command' for both aspell and hunspell. Is left
here just for backwards compatibility.")
(make-obsolete-variable 'ispell-aspell-supports-utf8
'ispell-encoding8-command "23.1")
+(defvar ispell-emacs-alpha-regexp
+ (if (string-match "^[[:alpha:]]+$" "abcde")
+ "[[:alpha:]]"
+ nil)
+ "[[:alpha:]] if Emacs supports [:alpha:] regexp, nil
+otherwise (current XEmacs does not support it).")
;;; **********************************************************************
;;; The following are used by ispell, and should not be changed.
(defun ispell-check-version (&optional interactivep)
- "Ensure that `ispell-program-name' is valid and the correct version.
+ "Ensure that `ispell-program-name' is valid and has the correct version.
Returns version number if called interactively.
Otherwise returns the library directory name, if that is defined."
;; This is a little wasteful as we actually launch ispell twice: once
(setq ispell-really-aspell nil)))
(ispell-really-hunspell
(if (ispell-check-minver hunspell8-minver ispell-really-hunspell)
- (setq ispell-encoding8-command "-i ")
+ (setq ispell-encoding8-command "-i")
(setq ispell-really-hunspell nil))))))
result))
(defun ispell-aspell-find-dictionary (dict-name)
"For aspell dictionary DICT-NAME, return a list of parameters if an
- associated data file is found or nil otherwise. List format is
- that of `ispell-dictionary-base-alist' elements."
+associated data file is found or nil otherwise. List format is that
+of `ispell-dictionary-base-alist' elements."
;; Make sure `ispell-aspell-data-dir' is defined
(or ispell-aspell-data-dir
(setq ispell-aspell-data-dir
(error nil))
ispell-really-aspell
ispell-encoding8-command
- ;; XEmacs does not like [:alpha:] regexps.
- (string-match "^[[:alpha:]]+$" "abcde"))
+ ispell-emacs-alpha-regexp)
(unless ispell-aspell-dictionary-alist
(ispell-find-aspell-dictionaries)))
ispell-dictionary-base-alist))
(unless (assoc (car dict) all-dicts-alist)
(add-to-list 'all-dicts-alist dict)))
- (setq ispell-dictionary-alist all-dicts-alist))))
-
+ (setq ispell-dictionary-alist all-dicts-alist))
+
+ ;; If Emacs flavor supports [:alpha:] use it for global dicts. If
+ ;; spellchecker also supports UTF-8 via command-line option use it
+ ;; in communication. This does not affect definitions in ~/.emacs.
+ (if ispell-emacs-alpha-regexp
+ (let (tmp-dicts-alist)
+ (dolist (adict ispell-dictionary-alist)
+ (add-to-list 'tmp-dicts-alist
+ (list
+ (nth 0 adict) ; dict name
+ "[[:alpha:]]" ; casechars
+ "[^[:alpha:]]" ; not-casechars
+ (nth 3 adict) ; otherchars
+ (nth 4 adict) ; many-otherchars-p
+ (nth 5 adict) ; ispell-args
+ (nth 6 adict) ; extended-character-mode
+ (if ispell-encoding8-command
+ 'utf-8
+ (nth 7 adict)))))
+ (setq ispell-dictionary-alist tmp-dicts-alist)))))
(defun ispell-valid-dictionary-list ()
"Return a list of valid dictionaries.
-The variable `ispell-library-directory' defines the library location."
+The variable `ispell-library-directory' defines their location."
;; Initialize variables and dictionaries alists for desired spellchecker.
;; Make sure ispell.el is loaded to avoid some autoload loops in XEmacs
;; (and may be others)
(let* ((slot (or
(assoc ispell-current-dictionary ispell-local-dictionary-alist)
(assoc ispell-current-dictionary ispell-dictionary-alist)
- (error "No match for the current dictionary")))
+ (error "No data for dictionary \"%s\", neither in `ispell-local-dictionary-alist' nor in `ispell-dictionary-alist'"
+ ispell-current-dictionary)))
(str (nth n slot)))
(when (and (> (length str) 0)
(not (multibyte-string-p str)))
(nth 5 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist)
(assoc ispell-current-dictionary ispell-dictionary-alist))))
(defun ispell-get-extended-character-mode ()
- (nth 6 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist)
- (assoc ispell-current-dictionary ispell-dictionary-alist))))
+ (if ispell-really-hunspell ;; hunspell treats ~word as ordinary words
+ nil ;; in pipe mode. Disable extended-char-mode
+ (nth 6 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist)
+ (assoc ispell-current-dictionary ispell-dictionary-alist)))))
(defun ispell-get-coding-system ()
(nth 7 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist)
(assoc ispell-current-dictionary ispell-dictionary-alist))))
(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.")
+There can be multiple instances of this keyword in the file.")
(defconst ispell-dictionary-keyword "Local IspellDict: "
"The keyword for a local dictionary to use.
("list" ispell-tex-arg-end 2)
("program" . "\\\\end[ \t\n]*{[ \t\n]*program[ \t\n]*}")
("verbatim\\*?" . "\\\\end[ \t\n]*{[ \t\n]*verbatim\\*?[ \t\n]*}"))))
- "*Lists of regions to be skipped in TeX mode.
+ "Lists of regions to be skipped in TeX mode.
First list is used raw.
Second list has key placed inside \\begin{}.
("<[tT][tT]/" "/")
("<[^ \t\n>]" ">")
("&[^ \t\n;]" "[; \t\n]"))
- "*Lists of start and end keys to skip in HTML buffers.
+ "Lists of start and end keys to skip in HTML buffers.
Same format as `ispell-skip-region-alist'.
Note - substrings of other matches must come last
(e.g. \"<[tT][tT]/\" and \"<[^ \\t\\n>]\").")
Ispell is then restarted because the local words could conflict.")
(defvar ispell-parser 'use-mode-name
- "*Indicates whether ispell should parse the current buffer as TeX Code.
+ "Indicates whether ispell should parse the current buffer as TeX Code.
Special value `use-mode-name' tries to guess using the name of `major-mode'.
Default parser is `nroff'.
Currently the only other valid parser is `tex'.
is non-nil when called interactively, then the following word
\(rather than preceding\) is checked when the cursor is not over a word.
Optional second argument contains otherchars that can be included in word
-many times.
+many times (see the doc string of `ispell-dictionary-alist' for details
+about otherchars).
Word syntax is controlled by the definition of the chosen dictionary,
which is in `ispell-local-dictionary-alist' or `ispell-dictionary-alist'."
;; 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))
- ;; if frame is unsplitable, temporarily disable that...
+ ;; if frame is unsplittable, temporarily disable that...
(if (cdr (assq 'unsplittable (frame-parameters (selected-frame))))
(let ((frame (selected-frame)))
(modify-frame-parameters frame '((unsplittable . nil)))
;; right encoding for communication. ispell or older aspell/hunspell
;; does not support this.
(if ispell-encoding8-command
- (list
- (concat ispell-encoding8-command
- (symbol-name (ispell-get-coding-system)))))
+ (if ispell-really-hunspell
+ (list ispell-encoding8-command
+ (upcase (symbol-name (ispell-get-coding-system))))
+ (list
+ (concat ispell-encoding8-command
+ (symbol-name (ispell-get-coding-system))))))
ispell-extra-args)))
;; Initially we don't know any buffer's local words.
(defun ispell-internal-change-dictionary ()
"Update the dictionary and the personal dictionary used by Ispell.
-This may kill the Ispell process; if so,
-a new one will be started when needed."
+This may kill the Ispell process; if so, a new one will be started
+when needed."
(let ((dict (or ispell-local-dictionary ispell-dictionary))
(pdict (or ispell-local-pdict ispell-personal-dictionary)))
(unless (and (equal ispell-current-dictionary dict)
;;;###autoload
(defun ispell-region (reg-start reg-end &optional recheckp shift)
"Interactively check a region for spelling errors.
-Return nil if spell session is quit,
- otherwise returns shift offset amount for last line processed."
+Return nil if spell session was terminated, otherwise returns shift offset
+amount for last line processed."
(interactive "r") ; Don't flag errors on read-only bufs.
(ispell-set-spellchecker-params) ; Initialize variables and dicts alists
(if (not recheckp)
(defun ispell-begin-skip-region-regexp ()
"Return a regexp of the search keys for region skipping.
Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys.
-Must call after `ispell-buffer-local-parsing' due to dependence on mode."
+Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
(mapconcat
'identity
(delq nil
`ispell-html-skip-alists', and `ispell-checking-message'.
Manual checking must include comments and tib references.
The list is of the form described by variable `ispell-skip-region-alist'.
-Must call after `ispell-buffer-local-parsing' due to dependence on mode."
+Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
(let ((skip-alist ispell-skip-region-alist))
;; only additional explicit region definition is tex.
(if (eq ispell-parser 'tex)
(defun ispell-ignore-fcc (start end)
"Delete the Fcc: message header when large attachments are included.
-Return value `nil' if file with large attachments are saved.
+Return value `nil' if file with large attachments is saved.
This can be used to avoid multiple questions for multiple large attachments.
Returns point to starting location afterwards."
(let ((result t))
coding)))))
(defun ispell-process-line (string shift)
- "Send STRING, a line of text, to ispell and processes the result.
+ "Send STRING, a line of text, to ispell and process the result.
This will modify the buffer for spelling errors.
Requires variables ISPELL-START and ISPELL-END to be defined in its
dynamic scope.
positive, and disable it otherwise. If called from Lisp, enable
the mode if ARG is omitted or nil.
-Ispell minor mode is a buffer-local mior mode. When enabled,
+Ispell minor mode is a buffer-local minor mode. When enabled,
typing SPC or RET warns you if the previous word is incorrectly
spelled.
nil " Spell" ispell-minor-keymap)
(defun ispell-minor-check ()
- "Check previous word then continue with the normal binding of this key.
+ "Check previous word, then continue with the normal binding of this key.
Don't check previous word when character before point is a space or newline.
Don't read buffer-local settings or word lists."
(interactive "*")
;; Matches commonly used "cut" boundaries
"^\\(- \\)?[-=_]+\\s ?\\(cut here\\|Environment Follows\\)")
"\\|")
- "*End of text which will be checked in `ispell-message'.
-If it is a string, limit at first occurrence of that regular expression.
+ "Text beyond which `ispell-message' will not spell-check.
+If it is a string, limit is the first occurrence of that regular expression.
Otherwise, it must be a function which is called to get the limit.")
(put 'ispell-message-text-end 'risky-local-variable t)
To abort spell checking of a message region and send the message anyway,
use the `x' command. (Any subsequent regions will be checked.)
-The `X' command aborts the message send so that you can edit the buffer.
+The `X' command aborts sending the message so that you can edit the buffer.
To spell-check whenever a message is sent, include the appropriate lines
in your .emacs file:
(defun ispell-buffer-local-parsing ()
"Place Ispell into parsing mode for this buffer.
Overrides the default parsing mode.
-Includes Latex/Nroff modes and extended character mode."
+Includes LaTeX/Nroff modes and extended character mode."
;; (ispell-init-process) must already be called.
(ispell-send-string "!\n") ; Put process in terse mode.
;; We assume all major modes with "tex-mode" in them should use latex parsing
(defun ispell-buffer-local-dict (&optional no-reload)
"Initializes local dictionary and local personal dictionary.
-If optional NO-RELOAD is non-nil, do not make any dictionary reloading.
+If optional NO-RELOAD is non-nil, do not reload any dictionary.
When a dictionary is defined in the buffer (see variable
`ispell-dictionary-keyword'), it will override the local setting
from \\[ispell-change-dictionary].
; LocalWords: AMStex hspace includeonly nocite epsfig displaymath eqnarray reg
; LocalWords: minipage modeline pers dict unhighlight buf grep sync prev inc
; LocalWords: fn oldot NB AIX msg init read's bufs pt cmd Quinlan eg
-; LocalWords: uuencoded unidiff sc nn VM SGML eval IspellPersDict unsplitable
+; LocalWords: uuencoded unidiff sc nn VM SGML eval IspellPersDict
; LocalWords: lns XEmacs HTML casechars Multibyte
;;; ispell.el ends here