]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/ispell.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / textmodes / ispell.el
index 87c2a95da49991bb7fc7d9c063332f21b90bb9b1..284fea4acd59f7b69e84b44b5f7951dba26d3a5a 100644 (file)
@@ -1,6 +1,6 @@
-;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2
+;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1994-1995, 1997-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1994-1995, 1997-2016 Free Software Foundation, Inc.
 
 ;; Author:           Ken Stevens <k.stevens@ieee.org>
 ;; Maintainer:       Ken Stevens <k.stevens@ieee.org>
@@ -46,9 +46,9 @@
 ;; your own dictionaries.
 
 ;;  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)
+;;  (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
 ;; Fixed bug in returning to nroff mode from tex mode.
 
 ;;; Compatibility code for XEmacs and (not too) older emacsen:
-
-(eval-and-compile ;; Protect against declare-function undefined in XEmacs
-  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
-
-(declare-function ispell-check-minver "ispell" (v1 v2))
-(declare-function ispell-looking-back "ispell"
-                 (regexp &optional limit &rest ignored))
-
-(if (fboundp 'version<=)
-    (defalias 'ispell-check-minver 'version<=)
-  (defun ispell-check-minver (minver version)
-    "Check if string VERSION is at least string MINVER.
+(defalias 'ispell-check-minver
+  (if (fboundp 'version<=) 'version<=
+    (lambda (minver version)
+      "Check if string VERSION is at least string MINVER.
 Both must be in [0-9]+.[0-9]+... format.  This is a fallback
 compatibility function in case `version<=' is not available."
-    (let ((pending t)
-         (return t)
-         start-ver start-mver)
-      ;; Loop until an absolute greater or smaller condition is reached
-      ;; or until no elements are left in any of version and minver. In
-      ;; this case version is exactly the minimal, so return OK.
-      (while pending
-       (let (ver mver)
-         (if (string-match "[0-9]+" version start-ver)
-             (setq start-ver (match-end 0)
-                   ver (string-to-number (match-string 0 version))))
-         (if (string-match "[0-9]+" minver start-mver)
-             (setq start-mver (match-end 0)
-                   mver (string-to-number (match-string 0 minver))))
-
-         (if (or ver mver)
-             (progn
-               (or ver  (setq ver 0))
-               (or mver (setq mver 0))
-               ;; If none of below conditions match, this element is the
-               ;; same. Go checking next element.
-               (if (> ver mver)
-                   (setq pending nil)
-                 (if (< ver mver)
-                     (setq pending nil
-                           return nil))))
-           (setq pending nil))))
-      return)))
+      (let ((pending t)
+            (return t)
+            start-ver start-mver)
+        ;; Loop until an absolute greater or smaller condition is reached
+        ;; or until no elements are left in any of version and minver. In
+        ;; this case version is exactly the minimal, so return OK.
+        (while pending
+          (let (ver mver)
+            (if (string-match "[0-9]+" version start-ver)
+                (setq start-ver (match-end 0)
+                      ver (string-to-number (match-string 0 version))))
+            (if (string-match "[0-9]+" minver start-mver)
+                (setq start-mver (match-end 0)
+                      mver (string-to-number (match-string 0 minver))))
+
+            (if (or ver mver)
+                (progn
+                  (or ver  (setq ver 0))
+                  (or mver (setq mver 0))
+                  ;; If none of below conditions match, this element is the
+                  ;; same. Go checking next element.
+                  (if (> ver mver)
+                      (setq pending nil)
+                    (if (< ver mver)
+                        (setq pending nil
+                              return nil))))
+              (setq pending nil))))
+        return))))
 
 ;; XEmacs does not have looking-back
-(if (fboundp 'looking-back)
-    (defalias 'ispell-looking-back 'looking-back)
-  (defun ispell-looking-back (regexp &optional limit &rest ignored)
-    "Return non-nil if text before point matches regular expression REGEXP.
+(defalias 'ispell-looking-back
+  (if (fboundp 'looking-back) 'looking-back
+    (lambda (regexp &optional limit &rest ignored)
+      "Return non-nil if text before point matches regular expression REGEXP.
 Like `looking-at' except matches before point, and is slower.
 LIMIT if non-nil speeds up the search by specifying a minimum
 starting position, to avoid checking matches that would start
@@ -251,8 +243,8 @@ before LIMIT.
 
 This is a stripped down compatibility function for use when
 full featured `looking-back' function is missing."
-    (save-excursion
-      (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t))))
+      (save-excursion
+        (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)))))
 
 ;;; XEmacs21 does not have `with-no-warnings'. Taken from org mode.
 (defmacro ispell-with-no-warnings (&rest body)
@@ -260,6 +252,8 @@ full featured `looking-back' function is missing."
 
 ;;; Code:
 
+(eval-when-compile (require 'cl-lib))
+
 (defvar mail-yank-prefix)
 
 (defgroup ispell nil
@@ -699,8 +693,8 @@ re-start Emacs."
 
 Each element of this list is also a list:
 
-\(DICTIONARY-NAME CASECHARS NOT-CASECHARS OTHERCHARS MANY-OTHERCHARS-P
-        ISPELL-ARGS EXTENDED-CHARACTER-MODE CHARACTER-SET\)
+ (DICTIONARY-NAME CASECHARS NOT-CASECHARS OTHERCHARS MANY-OTHERCHARS-P
+        ISPELL-ARGS EXTENDED-CHARACTER-MODE CHARACTER-SET)
 
 DICTIONARY-NAME is a possible string value of variable `ispell-dictionary',
 nil means the default dictionary.
@@ -747,7 +741,7 @@ when the language uses non-ASCII characters.
 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.")
+english.aff).  Aspell and Hunspell don't have this limitation.")
 
 (defvar ispell-really-aspell nil
   "Non-nil if we can use Aspell extensions.")
@@ -942,6 +936,8 @@ Otherwise returns the library directory name, if that is defined."
       (setq default-directory (expand-file-name "~/")))
     (apply 'call-process-region args)))
 
+(defvar ispell-debug-buffer)
+
 (defun ispell-create-debug-buffer (&optional append)
   "Create an ispell debug buffer for debugging output.
 If APPEND is non-nil, append the info to previous buffer if exists,
@@ -1000,7 +996,7 @@ and added as a submenu of the \"Edit\" menu.")
 (defvar ispell-async-processp (and (fboundp 'delete-process)
                                   (fboundp 'process-send-string)
                                   (fboundp 'accept-process-output)
-                                  ;;(fboundp 'start-process)
+                                  ;;(fboundp 'make-process)
                                   ;;(fboundp 'set-process-filter)
                                   ;;(fboundp 'process-kill-without-query)
                                   )
@@ -1182,15 +1178,15 @@ all uninitialized dicts using that affix file."
                (if (cadr (assoc tmp-dict ispell-dictionary-alist))
                    (ispell-print-if-debug
                      "ispell-hfde: %s already expanded; skipping.\n" tmp-dict)
-                 (add-to-list 'use-for-dicts tmp-dict))))))
+                 (cl-pushnew tmp-dict use-for-dicts :test #'equal))))))
       (ispell-print-if-debug
        "ispell-hfde: Filling %s entry.  Use for %s.\n" dict use-for-dicts)
       ;; The final loop.
       (dolist (entry ispell-dictionary-alist)
-       (if (member (car entry) use-for-dicts)
-           (add-to-list 'newlist
-                        (append (list (car entry)) dict-args-cdr))
-         (add-to-list 'newlist entry)))
+       (cl-pushnew (if (member (car entry) use-for-dicts)
+                        (cons (car entry) dict-args-cdr)
+                      entry)
+                    newlist :test #'equal))
       (setq ispell-dictionary-alist newlist))))
 
 (defun ispell-parse-hunspell-affix-file (dict-key)
@@ -1235,7 +1231,7 @@ did."
                        (chars-list (append otherchars-string nil)))
                   (setq chars-list (delq ?\  chars-list))
                   (dolist (ch chars-list)
-                    (add-to-list 'otherchars-list ch)))))
+                    (cl-pushnew ch otherchars-list :test #'equal)))))
           ;; Cons the argument for the -d switch.
           (setq dict-arg (concat dict-arg
                                  (if (> (length dict-arg) 0) ",")
@@ -1246,7 +1242,7 @@ did."
           "[[:alpha:]]"
           "[^[:alpha:]]"
           (if otherchars-list
-              (regexp-opt (mapcar 'char-to-string otherchars-list))
+              (regexp-opt (mapcar #'char-to-string otherchars-list))
             "")
           t                   ; many-otherchars-p: We can't tell, set to t.
           (list "-d" dict-arg)
@@ -1268,7 +1264,7 @@ in the list must have an affix file where Hunspell affix files are kept."
     (or (assoc first-dict ispell-local-dictionary-alist)
         (assoc first-dict ispell-dictionary-alist)
         (error "Unknown dictionary: %s" first-dict)))
-  (add-to-list 'ispell-dictionary-alist (list dict '()))
+  (cl-pushnew (list dict '()) ispell-dictionary-alist :test #'equal)
   (ispell-hunspell-fill-dictionary-entry dict))
 
 (defun ispell-find-hunspell-dictionaries ()
@@ -1308,8 +1304,8 @@ entries if a specific dictionary was found."
                (ispell-print-if-debug
                  "++ ispell-fhd: dict-entry:%s name:%s basename:%s affix-file:%s\n"
                  dict full-name basename affix-file)
-               (add-to-list 'ispell-hunspell-dict-paths-alist
-                            (list basename affix-file)))
+               (cl-pushnew (list basename affix-file)
+                            ispell-hunspell-dict-paths-alist :test #'equal))
            (ispell-print-if-debug
              "-- ispell-fhd: Skipping entry: %s\n" dict)))))
     ;; Remove entry from aliases alist if explicit dict was found.
@@ -1319,7 +1315,7 @@ entries if a specific dictionary was found."
            (ispell-print-if-debug
              "-- ispell-fhd: Excluding %s alias.  Standalone dict found.\n"
              (car dict))
-         (add-to-list 'newlist dict)))
+         (cl-pushnew dict newlist :test #'equal)))
       (setq ispell-dicts-name2locale-equivs-alist newlist))
     ;; Add known hunspell aliases
     (dolist (dict-equiv ispell-dicts-name2locale-equivs-alist)
@@ -1337,22 +1333,20 @@ entries if a specific dictionary was found."
                                            ispell-hunspell-dict-paths-alist))))
              (ispell-print-if-debug "++ ispell-fhd: Adding alias %s -> %s.\n"
                                      dict-equiv-key affix-file)
-             (add-to-list
-              'ispell-hunspell-dict-paths-alist
-              (list dict-equiv-key affix-file))))))
+             (cl-pushnew (list dict-equiv-key affix-file)
+                          ispell-hunspell-dict-paths-alist :test #'equal)))))
     ;; Parse and set values for default dictionary.
     (setq hunspell-default-dict (car hunspell-default-dict))
     (setq hunspell-default-dict-entry
          (ispell-parse-hunspell-affix-file hunspell-default-dict))
     ;; Create an alist of found dicts with only names, except for default dict.
     (setq ispell-hunspell-dictionary-alist
-         (list (append (list nil) (cdr hunspell-default-dict-entry))))
-    (dolist (dict (mapcar 'car ispell-hunspell-dict-paths-alist))
-      (if (string= dict hunspell-default-dict)
-         (add-to-list 'ispell-hunspell-dictionary-alist
-                      hunspell-default-dict-entry)
-       (add-to-list 'ispell-hunspell-dictionary-alist
-                    (list dict))))))
+         (list (cons nil (cdr hunspell-default-dict-entry))))
+    (dolist (dict (mapcar #'car ispell-hunspell-dict-paths-alist))
+      (cl-pushnew (if (string= dict hunspell-default-dict)
+                      hunspell-default-dict-entry
+                    (list dict))
+                  ispell-hunspell-dictionary-alist :test #'equal))))
 
 ;; Set params according to the selected spellchecker
 
@@ -1443,17 +1437,17 @@ aspell is used along with Emacs).")
                      (setq skip-dict t)))
 
                (unless skip-dict
-                 (add-to-list 'tmp-dicts-alist
-                              (list
-                               dict-name      ; dict name
-                               (nth 1 adict)  ; casechars
-                               (nth 2 adict)  ; not-casechars
-                               (nth 3 adict)  ; otherchars
-                               (nth 4 adict)  ; many-otherchars-p
-                               ispell-args    ; ispell-args
-                               (nth 6 adict)  ; extended-character-mode
-                               (nth 7 adict)  ; dict encoding
-                               ))))
+                 (cl-pushnew (list
+                               dict-name      ; dict name
+                               (nth 1 adict)  ; casechars
+                               (nth 2 adict)  ; not-casechars
+                               (nth 3 adict)  ; otherchars
+                               (nth 4 adict)  ; many-otherchars-p
+                               ispell-args    ; ispell-args
+                               (nth 6 adict)  ; extended-character-mode
+                               (nth 7 adict)  ; dict encoding
+                               )
+                              tmp-dicts-alist :test #'equal)))
              (setq ispell-dictionary-base-alist tmp-dicts-alist))))
 
       (run-hooks 'ispell-initialize-spellchecker-hook)
@@ -1463,7 +1457,7 @@ aspell is used along with Emacs).")
                            ispell-base-dicts-override-alist
                            ispell-dictionary-base-alist))
        (unless (assoc (car dict) all-dicts-alist)
-         (add-to-list 'all-dicts-alist dict)))
+         (push dict all-dicts-alist)))
       (setq ispell-dictionary-alist all-dicts-alist))
 
     ;; If Emacs flavor supports [:alpha:] use it for global dicts.  If
@@ -1473,20 +1467,20 @@ aspell is used along with Emacs).")
     (if ispell-emacs-alpha-regexp
        (let (tmp-dicts-alist)
          (dolist (adict ispell-dictionary-alist)
-           (if (cadr adict) ;; Do not touch hunspell uninitialized entries
-               (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))))
-             (add-to-list 'tmp-dicts-alist adict)))
+           (cl-pushnew (if (cadr adict) ;; Do not touch hunspell uninitialized entries
+                            (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)))
+                          adict)
+                        tmp-dicts-alist :test #'equal))
          (setq ispell-dictionary-alist tmp-dicts-alist)))))
 
 (defun ispell-valid-dictionary-list ()
@@ -1782,6 +1776,51 @@ Extended character mode can be changed for this buffer by placing
 a `~' followed by an extended-character mode -- such as `~.tex'.
 The last occurring definition in the buffer will be used.")
 
+(defun ispell--\\w-filter (char)
+  "Return CHAR in a string when CHAR doesn't have \"word\" syntax,
+nil otherwise.  CHAR must be a character."
+  (let ((str (string char)))
+    (and
+     (not (string-match "\\w" str))
+     str)))
+
+(defun ispell--make-\\w-expression (chars)
+  "Make a regular expression like \"\\(\\w\\|[-_]\\)\".
+This (parenthesized) expression matches either a character of
+\"word\" syntax or one in CHARS.
+
+CHARS is a string of characters.  A member of CHARS is omitted
+from the expression if it already has word syntax.  (Be careful
+about special characters such as ?\\, ?^, ?], and ?- in CHARS.)
+If after this filtering there are no chars left, or only one, a
+special form of the expression is generated."
+  (let ((filtered
+        (mapconcat #'ispell--\\w-filter chars "")))
+    (concat
+     "\\(\\w"
+     (cond
+      ((equal filtered "")
+       "\\)")
+      ((eq (length filtered) 1)
+       (concat "\\|" filtered "\\)"))
+      (t
+       (concat "\\|[" filtered "]\\)"))))))
+
+(defun ispell--make-filename-or-URL-re ()
+  "Construct a regexp to match some file names or URLs or email addresses.
+The expression is crafted to match as great a variety of these
+objects as practicable, without too many false matches happening."
+  (concat ;"\\(--+\\|_+\\|"
+          "\\(/\\w\\|\\("
+          (ispell--make-\\w-expression "-_")
+          "+[.:@]\\)\\)"
+          (ispell--make-\\w-expression "-_")
+          "*\\([.:/@]+"
+          (ispell--make-\\w-expression "-_~=?&")
+          "+\\)+"
+          ;"\\)"
+          ))
+
 ;;;###autoload
 (defvar ispell-skip-region-alist
   `((ispell-words-keyword         forward-line)
@@ -1798,7 +1837,7 @@ The last occurring definition in the buffer will be used.")
     ;; Matches e-mail addresses, file names, http addresses, etc.  The
     ;; `-+' `_+' patterns are necessary for performance reasons when
     ;; `-' or `_' part of word syntax.
-    (,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)"))
+;    (,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)"))
     ;; above checks /.\w sequences
     ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
     ;; This is a pretty complex regexp.  It can be simplified to the following:
@@ -1830,6 +1869,7 @@ Valid forms include:
      ("\\\\add\\(tocontents\\|vspace\\)" ispell-tex-arg-end)
      ("\\\\\\([aA]lph\\|arabic\\)"      ispell-tex-arg-end)
      ;;("\\\\author"                    ispell-tex-arg-end)
+     ("\\\\cref"                        ispell-tex-arg-end)
      ("\\\\bibliographystyle"           ispell-tex-arg-end)
      ("\\\\makebox"                     ispell-tex-arg-end 0)
      ("\\\\e?psfig"                     ispell-tex-arg-end)
@@ -1934,7 +1974,7 @@ and pass it the output of the last Ispell invocation."
 
 (defun ispell-send-replacement (misspelled replacement)
   "Notify Aspell that MISSPELLED should be spelled REPLACEMENT.
-This allows to improve the suggestion list based on actual misspellings."
+This allows improving the suggestion list based on actual misspellings."
   (and ispell-really-aspell
        (ispell-send-string (concat "$$ra " misspelled "," replacement "\n"))))
 
@@ -2024,7 +2064,7 @@ in a window allowing you to choose one.
 
 If optional argument FOLLOWING is non-nil or if `ispell-following-word'
 is non-nil when called interactively, then the following word
-\(rather than preceding\) is checked when the cursor is not over a word.
+\(rather than preceding) is checked when the cursor is not over a word.
 When the optional argument QUIETLY is non-nil or `ispell-quietly' is non-nil
 when called interactively, non-corrective messages are suppressed.
 
@@ -2044,7 +2084,7 @@ Return values:
 nil           word is correct or spelling is accepted.
 0             word is inserted into buffer-local definitions.
 \"word\"        word corrected from word list.
-\(\"word\" arg\)  word is hand entered.
+\(\"word\" arg)  word is hand entered.
 quit          spell session exited."
   (interactive (list ispell-following-word ispell-quietly current-prefix-arg t))
   (cond
@@ -2162,7 +2202,7 @@ quit          spell session exited."
   "Return the word for spell-checking according to ispell syntax.
 If optional argument FOLLOWING is non-nil or if `ispell-following-word'
 is non-nil when called interactively, then the following word
-\(rather than preceding\) is checked when the cursor is not over a 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 (see the doc string of `ispell-dictionary-alist' for details
 about otherchars).
@@ -2248,6 +2288,11 @@ If so, ask if it needs to be saved."
   (setq ispell-pdict-modified-p nil))
 
 
+(defvar ispell-update-post-hook nil
+  "A normal hook invoked from the ispell command loop.
+It is called once per iteration, before displaying a prompt to
+the user.")
+
 (defun ispell-command-loop (miss guess word start end)
   "Display possible corrections from list MISS.
 GUESS lists possibly valid affix construction of WORD.
@@ -2315,8 +2360,10 @@ Global `ispell-quit' set to start location to continue spell session."
              count (ispell-int-char (1+ count))))
       (setq count (ispell-int-char (- count ?0 skipped))))
 
+    (run-hooks 'ispell-update-post-hook)
+
     ;; ensure word is visible
-    (if (not (pos-visible-in-window-p end))
+    (if (not (pos-visible-in-window-group-p end))
        (sit-for 0))
 
     ;; Display choices for misspelled word.
@@ -2375,7 +2422,8 @@ Global `ispell-quit' set to start location to continue spell session."
                    nil)
                   ((or (= char ?a) (= char ?A)) ; accept word without insert
                    (ispell-send-string (concat "@" word "\n"))
-                   (add-to-list 'ispell-buffer-session-localwords word)
+                   (cl-pushnew word ispell-buffer-session-localwords
+                                :test #'equal)
                    (and (fboundp 'flyspell-unhighlight-at)
                         (flyspell-unhighlight-at start))
                    (or ispell-buffer-local-name ; session localwords might conflict
@@ -2708,7 +2756,7 @@ if defined."
 ;;   This is the case when a process dies or fails. The default behavior
 ;;   in this case treats the next input received as fresh input.
 
-(defun ispell-filter (process output)
+(defun ispell-filter (_process output)
   "Output filter function for ispell, grep, and look."
   (let ((start 0)
        (continue t)
@@ -2809,6 +2857,7 @@ The variable `ispell-highlight-face' selects the face to use for highlighting."
                  (regexp-quote (buffer-substring-no-properties start end))
                  "\\b"))
                (isearch-regexp t)
+               (isearch-regexp-function nil)
                (isearch-case-fold-search nil)
                (isearch-forward t)
                (isearch-other-end start)
@@ -2844,13 +2893,20 @@ Also position fit window to BUFFER and select it."
                     (prog1
                         (condition-case nil
                             (split-window
-                             nil (- ispell-choices-win-default-height) 'above)
+                              ;; Chose the last of a window group, since
+                              ;; otherwise, the lowering of another window's
+                              ;; TL corner would cause the logical order of
+                              ;; the windows to be changed.
+                             (car (last (selected-window-group)))
+                              (- ispell-choices-win-default-height) 'above)
                           (error nil))
                       (modify-frame-parameters frame '((unsplittable . t))))))
              (and (not unsplittable)
                   (condition-case nil
                       (split-window
-                       nil (- ispell-choices-win-default-height) 'above)
+                        ;; See comment above.
+                       (car (last (selected-window-group)))
+                        (- ispell-choices-win-default-height) 'above)
                     (error nil)))
              (display-buffer buffer))))
     (if (not window)
@@ -2980,14 +3036,13 @@ Keeps argument list for future Ispell invocations for no async support."
       (ispell-send-string "\032\n")    ; so Ispell prints version and exits
       t)))
 
-
 (defun ispell-init-process ()
   "Check status of Ispell process and start if necessary."
   (let* (;; Basename of dictionary used by the spell-checker
         (dict-bname (or (car (cdr (member "-d" (ispell-get-ispell-args))))
                         ispell-current-dictionary))
         ;; The directory where process was started.
-        (current-ispell-directory default-directory)
+        (current-ispell-directory default-directory) ;FIXME: Unused?
         ;; The default directory for the process.
         ;; Use "~/" as default-directory unless using Ispell with per-dir
         ;; personal dictionaries and not in a minibuffer under XEmacs
@@ -3090,7 +3145,7 @@ Keeps argument list for future Ispell invocations for no async support."
             ;; Otherwise we get cool errors like "Can't open ".
             (sleep-for 1)
             (ispell-accept-output 3)
-            (error "%s" (mapconcat 'identity ispell-filter "\n"))))
+            (error "%s" (mapconcat #'identity ispell-filter "\n"))))
       (setq ispell-filter nil)         ; Discard version ID line
       (let ((extended-char-mode (ispell-get-extended-character-mode)))
        (if extended-char-mode          ; ~ extended character mode
@@ -3146,7 +3201,7 @@ By just answering RET you can find out what the current dictionary is."
    (list (completing-read
          "Use new dictionary (RET for current, SPC to complete): "
          (and (fboundp 'ispell-valid-dictionary-list)
-              (mapcar 'list (ispell-valid-dictionary-list)))
+              (mapcar #'list (ispell-valid-dictionary-list)))
          nil t)
         current-prefix-arg))
   (ispell-set-spellchecker-params) ; Initialize variables and dicts alists
@@ -3352,7 +3407,7 @@ ispell-region: Search for first region to skip after (ispell-begin-skip-region-r
 Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys.
 Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
   (mapconcat
-   'identity
+   #'identity
    (delq nil
          (list
           ;; messages
@@ -3373,7 +3428,8 @@ Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
               (if (string= "" comment-end) "^" (regexp-quote comment-end)))
           (if (and (null ispell-check-comments) comment-start)
               (regexp-quote comment-start))
-          (ispell-begin-skip-region ispell-skip-region-alist)))
+          (ispell-begin-skip-region ispell-skip-region-alist)
+          (ispell--make-filename-or-URL-re)))
    "\\|"))
 
 
@@ -3412,6 +3468,8 @@ Manual checking must include comments and tib references.
 The list is of the form described by variable `ispell-skip-region-alist'.
 Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
   (let ((skip-alist ispell-skip-region-alist))
+    (setq skip-alist (append (list (list (ispell--make-filename-or-URL-re)))
+                             skip-alist))
     ;; only additional explicit region definition is tex.
     (if (eq ispell-parser 'tex)
        (setq case-fold-search nil
@@ -3806,7 +3864,7 @@ Standard ispell choices are then available."
           (setq case-fold-search nil)  ; Try and respect case of word.
           (cond
            ((string-equal (upcase word) word)
-            (setq possibilities (mapcar 'upcase possibilities)))
+            (setq possibilities (mapcar #'upcase possibilities)))
            ((eq (upcase (aref word 0)) (aref word 0))
              (setq possibilities (mapcar (function
                                           (lambda (pos)
@@ -4040,10 +4098,10 @@ 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 init file:
-   (add-hook \\='message-send-hook \\='ispell-message)  ;; GNUS 5
-   (add-hook \\='news-inews-hook \\='ispell-message)    ;; GNUS 4
-   (add-hook \\='mail-send-hook  \\='ispell-message)
-   (add-hook \\='mh-before-send-letter-hook \\='ispell-message)
+   (add-hook \\='message-send-hook #\\='ispell-message)  ;; GNUS 5
+   (add-hook \\='news-inews-hook #\\='ispell-message)    ;; GNUS 4
+   (add-hook \\='mail-send-hook  #\\='ispell-message)
+   (add-hook \\='mh-before-send-letter-hook #\\='ispell-message)
 
 You can bind this to the key C-c i in GNUS or mail by adding to
 `news-reply-mode-hook' or `mail-mode-hook' the following lambda expression:
@@ -4105,9 +4163,10 @@ You can bind this to the key C-c i in GNUS or mail by adding to
                      (ispell-non-empty-string vm-included-text-prefix)))
             (t default-prefix)))
           (ispell-skip-region-alist
-           (cons (list (concat "^\\(" cite-regexp "\\)")
-                       (function forward-line))
-                 ispell-skip-region-alist))
+           (cons (list (ispell--make-filename-or-URL-re))
+                  (cons (list (concat "^\\(" cite-regexp "\\)")
+                              (function forward-line))
+                        ispell-skip-region-alist)))
           (old-case-fold-search case-fold-search)
           (dictionary-alist ispell-message-dictionary-alist)
           (ispell-checking-message t))
@@ -4364,6 +4423,7 @@ Both should not be used to define a buffer-local dictionary."
                          (insert comment-end)))))
              (insert (concat " " word))))))))
 
+;;FIXME: Use `user-error' instead!
 (add-to-list 'debug-ignored-errors "^No word found to check!$")
 
 (provide 'ispell)