]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/ispell.el
Doc fix in Commentary section.
[gnu-emacs] / lisp / textmodes / ispell.el
index 940915672ee3d2309d60d629b53cc461978ebbe6..60cf46da30d006f03f2f79671f6f876419c30006 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ispell.el --- spell checking using Ispell
 
-;; Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
 
 ;; Authors         : Ken Stevens <k.stevens@ieee.org>
 ;; Last Modified On: Tue Jun 13 12:05:28 EDT 1995
@@ -80,6 +80,7 @@
 ;;   ispell-region
 ;;   ispell-buffer
 ;;   ispell-message
+;;   ispell-comments-and-strings
 ;;   ispell-continue
 ;;   ispell-complete-word
 ;;   ispell-complete-word-interior-frag
@@ -455,7 +456,8 @@ The function must take one string argument and return a string."
   "*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
@@ -502,15 +504,15 @@ for language-specific arguments."
     ("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")
+     "[']" t ("-C" "-d" "deutsch") "~latin1" 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)
+     "[']" 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)))
+     "[']" t ("-C") nil iso-latin-1)))
 
 ;;;###autoload
 (defvar ispell-dictionary-alist-2
@@ -519,20 +521,21 @@ for language-specific arguments."
      "[']" nil ("-C") 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?
+     "[']" nil ("-C" "-d" "svenska") "~list" ; Add `"-T" "list"' instead?
+     iso-latin-1)
     ("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")
+     "[---']" 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")
+     "[---'^`\"]" t nil "~tex" 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)
+      "[']" nil ("-C") nil iso-latin-1)
     ))
 
 
@@ -556,15 +559,19 @@ word.
 
 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.
@@ -702,18 +709,30 @@ language.aff file \(e.g., english.aff\).")
 (defvar ispell-offset 1
   "Offset that maps protocol differences between ispell 3.1 versions.")
 
+(defun ispell-decode-string (str)
+  (let (coding-system)
+    (if (and enable-multibyte-characters
+            (setq coding-system (ispell-get-coding-system)))
+       (decode-coding-string str 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.")
@@ -975,7 +994,7 @@ Word syntax described by `ispell-dictionary-alist' (which see)."
        (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)))
 
 
@@ -1019,6 +1038,8 @@ used."
                                ispell-choices-win-default-height))
        (command-characters '( ?  ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m ))
        (skipped 0)
+       (window (selected-window))
+       (dedicated (window-dedicated-p (selected-window)))
        char num result textwin highlighted)
 
     ;; setup the *Choices* buffer with valid data.
@@ -1246,7 +1267,8 @@ used."
       (if ispell-highlight-p           ; unhighlight
          (save-window-excursion
            (select-window textwin)
-           (ispell-highlight-spelling-error start end))))))
+           (ispell-highlight-spelling-error start end)))
+      (set-window-dedicated-p window dedicated))))
 
 
 ;;;###autoload
@@ -1479,8 +1501,13 @@ scrolling the current window.  Leave the new window selected."
       ;; So we increment the height for this case.
       (if (string-match "19\.9.*Lucid" (emacs-version))
          (setq height (1+ height)))
-      (let ((frame-override-unsplittable t))
-       (split-window nil height))
+      (split-window nil height)
+      ;; The lower of the two windows is the logical successor
+      ;; of the original window, so move the dedicated flag to there.
+      ;; The new upper window should not be dedicated.
+      (set-window-dedicated-p (next-window)
+                             (window-dedicated-p (selected-window)))
+      (set-window-dedicated-p (selected-window) nil)
       (set-window-start (next-window) top))))
 
 
@@ -1602,6 +1629,9 @@ scrolling the current window.  Leave the new window selected."
          ispell-filter-continue nil
          ispell-process-directory default-directory)
     (set-process-filter ispell-process 'ispell-filter)
+    (if (and enable-multibyte-characters
+            ispell-dictionary)
+       (set-process-coding-system ispell-process (ispell-get-coding-system)))
     (accept-process-output ispell-process) ; Get version ID line
     (cond ((null ispell-filter)
           (error "%s did not output version line" ispell-program-name))
@@ -1679,7 +1709,7 @@ With prefix argument, set the default directory."
                   (setq ispell-dictionary dict))
               (if (null arg)           ; set local dictionary
                   (setq ispell-local-dictionary dict)))
-          (error "Illegal dictionary: %s" dict))
+          (error "Invalid Ispell dictionary: %s" dict))
         (ispell-kill-ispell t)
         (message "(Next %sIspell command will use %s dictionary)"
                  (cond ((equal ispell-local-dictionary ispell-dictionary)
@@ -1811,8 +1841,20 @@ With prefix argument, set the default directory."
                      (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))))
+                           (let* ((word-start
+                                   (if (and enable-multibyte-characters
+                                            (ispell-get-coding-system))
+                                       ;; OFFSET returned by ispell
+                                       ;; counts non-ASCII chars as
+                                       ;; one, so just adding OFFSET
+                                       ;; to START will cause an
+                                       ;; error.
+                                       (save-excursion
+                                         (goto-char (+ start offset-change))
+                                         (forward-char (car (cdr poss)))
+                                         (point))
+                                     (+ start offset-change
+                                        (car (cdr poss)))))
                                   (word-end (+ word-start
                                                (length (car poss))))
                                   replace)
@@ -1940,6 +1982,25 @@ With prefix argument, set the default directory."
       (message "Spell-checking done"))))
 
 
+;;;###autoload
+(defun ispell-comments-and-strings ()
+  "Check comments and strings in the current buffer for spelling errors."
+  (interactive)
+  (goto-char (point-min))
+  (let (state done)
+    (while (not done)
+      (setq done t)
+      (setq state (parse-partial-sexp (point) (point-max)
+                                     nil nil state 'syntax-table))
+      (when (or (nth 3 state) (nth 4 state))
+       (let ((start (point)))
+         (setq state (parse-partial-sexp start (point-max)
+                                         nil nil state 'syntax-table))
+         (when (or (nth 3 state) (nth 4 state))
+           (error "Unterminated string or comment."))
+         (save-excursion
+           (setq done (not (ispell-region start (point))))))))))
+
 
 ;;;###autoload
 (defun ispell-buffer ()
@@ -2319,7 +2380,7 @@ Includes latex/nroff modes and extended character mode."
                 (process-send-string ispell-process "-\n~nroff"))
                ((string-match "~" string) ; Set extended character mode.
                 (process-send-string ispell-process (concat string "\n")))
-               (t (message "Illegal Ispell Parsing argument!")
+               (t (message "Invalid Ispell Parsing argument!")
                   (sit-for 2))))))))
 
 
@@ -2340,13 +2401,15 @@ Both should not be used to define a buffer-local dictionary."
        (setq end (save-excursion (end-of-line) (point)))
        (if (re-search-forward " *\\([^ \"]+\\)" end t)
            (setq ispell-local-dictionary
-                 (buffer-substring (match-beginning 1) (match-end 1)))))
+                 (buffer-substring-no-properties (match-beginning 1)
+                                                 (match-end 1)))))
       (goto-char (point-min))
       (while (search-forward ispell-pdict-keyword nil t)
        (setq end (save-excursion (end-of-line) (point)))
        (if (re-search-forward " *\\([^ \"]+\\)" end t)
            (setq ispell-local-pdict
-                 (buffer-substring (match-beginning 1) (match-end 1)))))))
+                 (buffer-substring-no-properties (match-beginning 1)
+                                                 (match-end 1)))))))
   ;; Reload if new personal dictionary defined.
   (if (and ispell-local-pdict
           (not (equal ispell-local-pdict ispell-personal-dictionary)))