(font-lock-comment-face): Change dark-background,
[bpt/emacs.git] / lisp / dabbrev.el
index fdb9e27..542f657 100644 (file)
@@ -1,26 +1,30 @@
-;;; new-dabbrev.el --- dynamic abbreviation package
-;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+;;; dabbrev.el --- dynamic abbreviation package
+
+;; Copyright (C) 1985, 86, 92, 94, 96, 1997, 2000
+;;   Free Software Foundation, Inc.
 
 ;; Author: Don Morrison
 ;; Maintainer: Lars Lindberg <Lars.Lindberg@sypro.cap.se>
 ;; Created: 16 Mars 1992
-;; Version: 4.4.2 beta
-(defun dabbrev--version () "4.4.2 beta")
-;; Keywords: abbrev expand completion
+;; Lindberg's last update version: 5.7
+;; Keywords: abbrev expand completion convenience
+
+;; This file is part of GNU Emacs.
 
-;; This program is free software; you can redistribute it and/or modify
+;; 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 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
+;; 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 this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
 
 ;; To expand a word, just put the point right after the word and press
 ;; M-/ (dabbrev-expand) or M-C-/ (dabbrev-completion).
 ;;
-;; There are powerful things in this package that aren't turned on by
-;; default. I recommend you to do the following.
-;;
-;; Put the following 2 lines in your .emacs file:
-;; (setq dabbrev-always-check-other-buffers t)
-;; (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
-;;
-;; Dabbrev will now search in all buffers with the same major mode for
-;; your expansions. It will also search for complete symbols, the old
-;; dabbrev package only looked half-heartedly for symbols.
-;;
 ;; Check out the customizable variables below to learn about all the
 ;; features of this package.
 
@@ -53,7 +46,7 @@
 ;;
 ;; Set the variables you want special for your mode like this:
 ;; (set (make-local-variable 'dabbrev-case-replace) nil)
-;; Then you don't interfer with other modes.
+;; Then you don't interfere with other modes.
 ;;
 ;; If your mode handles buffers that refers to other buffers
 ;; (i.e. compilation-mode, gud-mode), then try to set
 ;;           (set-buffer buffer)
 ;;           (memq major-mode '(news-reply-mode gnus-article-mode)))))
 
-;;; Change Log
-;;  4.4.2 1994-11-25
-;;      Added new variable; `dabbrev-check-rest-of-buffers'.
-;;  4.4.1 1994-11-24
-;;      Now has correct creation date.
-;;      Added kill-ring idea to "Future enhancements".
-;;  4.4 1994-11-22
-;;     Changed the copyright text.  Thanks [hymie].
-;;     new-dabbrev now handles abbrevs that starts with symbol
-;;     syntax. Thanks [burgett] for kicking me to do it.
-;;     Now also handles `dabbrev-abbrev-skip-leading-regexp' better.
-;;  4.3 1994-11-14
-;;     Now only displays "Expansion found in <buffer>" when the
-;;     expansion has been found in buffers that hasn't been examined
-;;     yet. Thanks [kifer].
-;;      Added a new variable; `dabbrev-search-these-buffers-only'.
-;;      Fixed bug in mini-buffer completion. Thanks [kifer].
-;;      Found a real time-waster when using `dabbrev-completion'.
-;;      Thanks for the elp.el package Barry Warsaw!
-;;     Found bug that made point move in other buffers.
-;;      Now handles Lucid emacs define-key style.
-;;      Thanks [jules].
-;;      Now uses the `<symbol>' syntax in doc strings.
-;;      Cosmetic bugs and syntactical bugs in documentation strings.
-;;      Thanks [hawley].
-;;  4.2 1994-03-04
-;;      Now searches other buffers again. Thanks [ake].
-;;  4.1 1994-02-22
-;;      Introduced the new variables `dabbrev-case-fold-search' and
-;;      `dabbrev-case-replace'.
-;;      Introduced the new variable `dabbrev-select-buffers-function'.
-;;      Introduced the new variable `dabbrev-abbrev-skip-leading-regexp'.
-;;      Changed `dabbrev-always-check-other-buffers' to not buffer local.
-;;      Thanks [kifer].
-;;      Bug in `dabbrev-completion', x expanded to xxy instead of xy.
-;;      Thanks [kifer].
-;;      Added `dabbrev-submit-feedback' for better error-reporting.
-;;      The hooks (`dabbrev-select-buffers-function' and
-;;      `dabbrev-friend-buffer-function') are now not automatically
-;;      buffer local.
-;;      Now provides dabbrev too.
-;;  3.2 1993-12-14
-;;      Message for expansion found in buffer other than current.
-;;     Minor bugs.
-;;  3.1 1993-12-13
-;;      Better comment for `dabbrev-abbrev-char-regexp'.
-;;  3.0 1993-12-09
-;;      Freshed things up for the release.
-;;      `dabbrev-completion' now doesn't have to use the minibuffer.
-;;      Thanks [alon].
-;;  2.0 1993-12-02 Lars Lindberg <lli@sypro.cap.se>
-;;      Searches in other buffers for the expansion.
-;;      Works also for the minibuffer.
-;;      Added `dabbrev-completion'.
-;;      More efficient code.
-;;      Found minor bugs.
-;;  1.0 converted to Emacs Lisp by Spencer Thomas.
-;;      Thoroughly cleaned up by Richard Stallman.
-;;  0.0
-;;      DABBREVS - "Dynamic abbreviations" hack, originally written by
-;;      Don Morrison for Twenex Emacs.  Converted to mlisp by Russ Fish.
-;;      Supports the table feature to avoid hitting the same expansion on
-;;      re-expand, and the search size limit variable.
 
 ;; Known bugs and limitations.
 ;; - Possible to do several levels of `dabbrev-completion' in the
 ;;  - Check the tags-files? Like tags-complete?
 ;;  - Add the possibility of searching both forward and backward to
 ;;    the nearest expansion.
-;;  - Check the kill-ring when everything else fails. (Maybe something
-;;  for hippie-expand?). [Bng] <boris@cs.rochester.edu>
+;;  - Check the kill-ring when everything else fails.  (Maybe something
+;;  for hippie-expand?).  [Bng] <boris@cs.rochester.edu>
 
-;;; Thanks goes to
+;;; These people gave suggestions:
 ;;  [hymie]    Hyman Rosen <marks!hymie@jyacc.jyacc.com>
 ;;  [burgett]  Steve Burgett <burgett@bizet.eecs.berkeley.edu>
 ;;  [jules]    Julian Gosnell <jules@x.co.uk>
 ;;  [tromey]   Tom Tromey <tromey@busco.lanl.gov>
 ;;  [Rolf]     Rolf Schreiber <rolf@mathematik.uni-stuttgart.de>
 ;;  [Petri]    Petri Raitio <per@tekla.fi>
-;;  [ejb]      Jay Berkenbilt <ejb@ERA.COM>
+;;  [ejb]      Jay Berkenbilt <ejb@ql.org>
 ;;  [hawley]   Bob Hawley <rth1@quartet.mt.att.com>
 ;;  ... and to all the people who have participated in the beta tests.
 
 ;;; Code:
-(require 'cl)
-
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-;;; Customization variables
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-(defvar dabbrev-backward-only nil
-  "*If non-NIL, `dabbrev-expand' only looks backwards.")
-
-(defvar dabbrev-limit nil
-  "*Limits region searched by `dabbrev-expand' to this many chars away.")
 
-(defvar dabbrev-abbrev-skip-leading-regexp nil
-  "*Regexp for skipping leading characters of an abbreviation.
+;;----------------------------------------------------------------
+;; Customization variables
+;;----------------------------------------------------------------
 
-Example: Set this to \"\\\\$\" for programming languages that sometimes
-has and sometimes has not a leading $ for variable names.
+(defgroup dabbrev nil
+  "Dynamic Abbreviations"
+  :tag "Dynamic Abbreviations"
+  :group 'abbrev
+  :group 'convenience)
 
-Set this to nil if no characters should be skipped.")
+(defcustom dabbrev-backward-only nil
+  "*If non-nil, `dabbrev-expand' only looks backwards."
+  :type 'boolean
+  :group 'dabbrev)
 
-;; I recommend that you set this to nil.
-(defvar dabbrev-case-fold-search 'case-fold-search
-  "*T if dabbrev searches should ignore case.
-nil if case is significant.
-Non-nil and not t means evaluate for value.
+(defcustom dabbrev-limit nil
+  "*Limits region searched by `dabbrev-expand' to this many chars away."
+  :type '(choice (const :tag "off" nil)
+                integer)
+  :group 'dabbrev)
 
-Example:Setting this to 'case-fold-search means evaluate that variable
-to see if it is t or non-nil.")
+(defcustom dabbrev-abbrev-skip-leading-regexp nil
+  "*Regexp for skipping leading characters of an abbreviation.
 
-(defvar dabbrev-upcase-means-case-search nil
+Example: Set this to \"\\\\$\" for programming languages
+in which variable names may appear with or without a leading `$'.
+\(For example, in Makefiles.\)
+
+Set this to nil if no characters should be skipped."
+  :type '(choice regexp
+                (const :tag "off" nil))
+  :group 'dabbrev)
+
+(defcustom dabbrev-case-fold-search 'case-fold-search
+  "*Control whether dabbrev searches should ignore case.
+A value of nil means case is significant.
+A value of `case-fold-search' means case is significant
+ if `case-fold-search' is nil.
+Any other non-nil version means case is not significant."
+  :type '(choice (const :tag "off" nil)
+                (const :tag "like search" case-fold-search)
+                (other :tag "on" t))
+  :group 'dabbrev)
+
+(defcustom dabbrev-upcase-means-case-search nil
   "*The significance of an uppercase character in an abbreviation.
-
-This variable only makes sense when the value of
-`dabbrev-case-fold-search' evaluates to t.
-
-nil = case fold search
-t = case sensitive search")
-
-;; I recommend that you set this to nil.
-(defvar dabbrev-case-replace 'case-replace
-  "*T if dabbrev should preserve case when expanding the abbreviation.
-nil if it should not.
-Non-nil and not t means evaluate for value.
-
-This variable only makes sense when the value of
-`dabbrev-case-fold-search' evaluates to t.
-
-Example: Setting this to 'case-replace means evaluate that variable to
-see if it is t or non-nil.")
-
-;; I recommend that you set this to "\\sw\\|\\s_"
-(defvar dabbrev-abbrev-char-regexp nil
-  "*A regexp that recognizes a character in an abbreviation or an
-expansion.  Will be surrounded with \\\\( ... \\\\) when used.
-
-Set this to \"\\\\sw\" if you want ordinary words or
-\"\\\\sw\\\\|\\\\s_\" if you want symbols.
-
-You can also set it to nil if you want old-style dabbrev searching
-(the abbreviation is from point to previous word-start, the
-search is for symbols).
-
-For instance, if you are programming in Lisp, yes-or-no-p is a symbol,
-while 'yes', 'or', 'no' and 'p' are considered words.  If you set this
-variable to nil, then expanding yes-or-no- will look for a symbol
-starting with or containing 'no-'.  If you set this variable to
-\"\\\\sw\\\\|\\\\s_\" dabbrev will look for a symbol starting with
-\"yes-or-no-\". Finally, if you set this variable to \"\\\\sw\", then an
-error will be signalled, because \"-\" is not part of a word but if you
-try to expand \"yes-or-no\", dabbrev will look for a word starting with
-\"no\".
-
-The recommended value is \"\\\\sw\\\\|\\\\s_\".")
-
-;; I recommend that you set this to t.
-(defvar dabbrev-check-rest-of-buffers nil
-  "*Should dabbrev package search in all buffers?.
-
-Non-nil means first look in buffers pointed out by
-`dabbrev-select-buffers-function' and then look in the rest of the
-buffers.")
-
-
-;; I recommend that you set this to t.
-(defvar dabbrev-always-check-other-buffers nil
+nil means case fold search, non-nil means case sensitive search.
+
+This variable has an effect only when the value of
+`dabbrev-case-fold-search' says to ignore case."
+  :type 'boolean
+  :group 'dabbrev)
+
+(defcustom dabbrev-case-replace 'case-replace
+  "*Controls whether dabbrev preserves case when expanding the abbreviation.
+A value of nil means preserve case.
+A value of `case-replace' means preserve case if `case-replace' is nil.
+Any other non-nil version means do not preserve case.
+
+This variable has an effect only when the value of
+`dabbrev-case-fold-search' specifies to ignore case."
+  :type '(choice (const :tag "off" nil)
+                (const :tag "like M-x query-replace" case-replace)
+                (other :tag "on" t))
+  :group 'dabbrev)
+
+(defcustom dabbrev-abbrev-char-regexp nil
+  "*Regexp to recognize a character in an abbreviation or expansion.
+This regexp will be surrounded with \\\\( ... \\\\) when actually used.
+
+Set this variable to \"\\\\sw\" if you want ordinary words or
+\"\\\\sw\\\\|\\\\s_\" if you want symbols (including characters whose
+syntax is \"symbol\" as well as those whose syntax is \"word\".
+
+The value nil has a special meaning: the abbreviation is from point to
+previous word-start, but the search is for symbols.
+
+For instance, if you are programming in Lisp, `yes-or-no-p' is a symbol,
+while `yes', `or', `no' and `p' are considered words.  If this
+variable is nil, then expanding `yes-or-no-' looks for a symbol
+starting with or containing `no-'.  If you set this variable to
+\"\\\\sw\\\\|\\\\s_\", that expansion looks for a symbol starting with
+`yes-or-no-'.  Finally, if you set this variable to \"\\\\sw\", then
+expanding `yes-or-no-' signals an error because `-' is not part of a word;
+but expanding `yes-or-no' looks for a word starting with `no'.
+
+The recommended value is \"\\\\sw\\\\|\\\\s_\"."
+  :type '(choice (const nil)
+                regexp)
+  :group 'dabbrev)
+
+(defcustom dabbrev-check-all-buffers t
+  "*Non-nil means dabbrev package should search *all* buffers.
+
+Dabbrev always searches the current buffer first.  Then, if
+`dabbrev-check-other-buffers' says so, it searches the buffers
+designated by `dabbrev-select-buffers-function'.
+
+Then, if `dabbrev-check-all-buffers' is non-nil, dabbrev searches
+all the other buffers, except those named in `dabbrev-ignored-buffer-names',
+or matched by `dabbrev-ignored-regexps'."
+  :type 'boolean
+  :group 'dabbrev)
+
+(defcustom dabbrev-ignored-buffer-names '("*Messages*" "*Buffer List*")
+  "*List of buffer names that dabbrev should not check.
+See also `dabbrev-ignored-regexps'."
+  :type '(repeat (string :tag "Buffer name"))
+  :group 'dabbrev
+  :version "20.3")
+
+(defcustom dabbrev-ignored-regexps nil
+  "*List of regexps matching names of buffers that dabbrev should not check.
+See also `dabbrev-ignored-buffer-names'."
+  :type '(repeat regexp)
+  :group 'dabbrev
+  :version "21.1")
+
+(defcustom dabbrev-check-other-buffers t
   "*Should \\[dabbrev-expand] look in other buffers?\
-nil = Don't look in other buffers.\n\
-t = Look in other buffers.\n\
-Value other than nil and t = ask the user if he want's to look in
-other buffers.
 
-The recommended value is t.")
+nil: Don't look in other buffers.
+t: Also look for expansions in the buffers pointed out by
+   `dabbrev-select-buffers-function'.
+Anything else: When we can't find any more expansions in
+the current buffer, then ask the user whether to look in other
+buffers too.
+
+The default value is t."
+  :type '(choice (const :tag "off" nil)
+                (const :tag "on" t)
+                (other :tag "ask" other))
+  :group 'dabbrev)
 
 ;; I guess setting this to a function that selects all C- or C++-
 ;; mode buffers would be a good choice for a debugging buffer,
 ;; when debugging C- or C++-code.
 (defvar dabbrev-select-buffers-function 'dabbrev--select-buffers
   "A function that selects buffers that should be searched by dabbrev.
-
 The function should take no arguments and return a list of buffers to
 search for expansions.  Have a look at `dabbrev--select-buffers' for
 an example.
 
 A mode setting this variable should make it buffer local.")
 
-(defvar dabbrev-friend-buffer-function 'dabbrev--same-major-mode-p
-  "*A function to check if OTHER-BUFFER should be searched by dabbrev.
-
+(defcustom dabbrev-friend-buffer-function 'dabbrev--same-major-mode-p
+  "*A function to decide whether dabbrev should search OTHER-BUFFER.
 The function should take one argument, OTHER-BUFFER, and return
 non-nil if that buffer should be searched.  Have a look at
 `dabbrev--same-major-mode-p' for an example.
 
-Setting this makes sense only if the function pointed out by
-`dabbrev-select-buffers-function' uses it.  The package function
-`dabbrev--select-buffers' is such a function.
+The value of `dabbrev-friend-buffer-function' has an effect only if
+the value of `dabbrev-select-buffers-function' uses it.  The function
+`dabbrev--select-buffers' is one function you can use here.
 
-A mode setting this variable should make it buffer local.")
+A mode setting this variable should make it buffer local."
+  :type 'function
+  :group 'dabbrev)
 
-(defvar dabbrev-search-these-buffers-only nil
-  "Should be a list of buffers if non-nil.
+(defcustom dabbrev-search-these-buffers-only nil
+  "If non-nil, a list of buffers which dabbrev should search.
+If this variable is non-nil, dabbrev will only look in these buffers.
+It will not even look in the current buffer if it is not a member of
+this list.")
 
-Dabbrev search will only look in these buffers. It will not even look
-in the current buffer if it is not a member of this list.")
-
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-;;; Internal variables
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
+;;----------------------------------------------------------------
+;; Internal variables
+;;----------------------------------------------------------------
 
 ;; Last obarray of completions in `dabbrev-completion'
 (defvar dabbrev--last-obarray nil)
@@ -328,55 +297,75 @@ in the current buffer if it is not a member of this list.")
 ;; The buffer we last did a completion in.
 (defvar dabbrev--last-completion-buffer nil)
 
-;; Same as dabbrev-always-check-other-buffers, but is set for every expand.
-(defvar dabbrev--check-other-buffers dabbrev-always-check-other-buffers)
+;; Non-nil means we should upcase
+;; when copying successive words.
+(defvar dabbrev--last-case-pattern nil)
+
+;; Same as dabbrev-check-other-buffers, but is set for every expand.
+(defvar dabbrev--check-other-buffers dabbrev-check-other-buffers)
 
 ;; The regexp for recognizing a character in an abbreviation.
 (defvar dabbrev--abbrev-char-regexp nil)
 
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-;;; Macros
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
+;;----------------------------------------------------------------
+;; Macros
+;;----------------------------------------------------------------
 
 ;;; Get the buffer that mini-buffer was activated from
 (defsubst dabbrev--minibuffer-origin ()
   (car (cdr (buffer-list))))
 
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-;;; Exported functions
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
+;; Make a list of some of the elements of LIST.
+;; Check each element of LIST, storing it temporarily in the
+;; variable ELEMENT, and include it in the result
+;; if CONDITION evaluates non-nil.
+(defmacro dabbrev-filter-elements (element list condition)
+  `(let (dabbrev-result dabbrev-tail ,element)
+    (setq dabbrev-tail ,list)
+    (while dabbrev-tail
+      (setq ,element (car dabbrev-tail))
+      (if ,condition
+          (setq dabbrev-result (cons ,element dabbrev-result)))
+      (setq dabbrev-tail (cdr dabbrev-tail)))
+    (nreverse dabbrev-result)))
+
+;;----------------------------------------------------------------
+;; Exported functions
+;;----------------------------------------------------------------
 
 ;;;###autoload
 (define-key esc-map "/" 'dabbrev-expand)
+;;;??? Do we want this?
 ;;;###autoload
-(if (string-match "Lucid$" emacs-version)
-    (define-key esc-map [(control /)] 'dabbrev-completion)
-  (define-key esc-map [?\C-/] 'dabbrev-completion))
+(define-key esc-map [?\C-/] 'dabbrev-completion)
 
 ;;;###autoload
 (defun dabbrev-completion (&optional arg)
   "Completion on current word.
-
 Like \\[dabbrev-expand] but finds all expansions in the current buffer
 and presents suggestions for completion.
 
-If you call this function with prefix ARG, then it searches all
-buffers accepted by the function pointed out by
-`dabbrev-friend-buffer-function' to find the completions.
+With a prefix argument, it searches all buffers accepted by the
+function pointed out by `dabbrev-friend-buffer-function' to find the
+completions.
+
+If the prefix argument is 16 (which comes from C-u C-u),
+then it searches *all* buffers.
 
-With no prefix ARG it tries to reuse the old completion list
-before making a new one."
+With no prefix argument, it reuses an old completion list
+if there is a suitable one already."
 
   (interactive "*P")
-  (let* ((dabbrev-always-check-other-buffers (and arg t))
+  (dabbrev--reset-global-variables)
+  (let* ((dabbrev-check-other-buffers (and arg t))
+        (dabbrev-check-all-buffers
+         (and arg (= (prefix-numeric-value arg) 16)))
         (abbrev (dabbrev--abbrev-at-point))
-        (ignore-case-p  (and (eval dabbrev-case-fold-search)
-                               (or (not dabbrev-upcase-means-case-search)
-                                   (string= abbrev (downcase abbrev)))))
+        (ignore-case-p (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+                                case-fold-search
+                              dabbrev-case-fold-search)
+                            (or (not dabbrev-upcase-means-case-search)
+                                (string= abbrev (downcase abbrev)))))
         (my-obarray dabbrev--last-obarray)
         init)
     (save-excursion
@@ -392,22 +381,20 @@ before making a new one."
                        (substring abbrev 0
                                   (length dabbrev--last-abbreviation)))
               (setq init (try-completion abbrev my-obarray)))
-         ;;--------------------------------
-         ;; This is a continue.
-         ;;--------------------------------
-         (progn)
+         ;; We can reuse the existing completion list.
+         nil
        ;;--------------------------------
        ;; New abbreviation to expand.
        ;;--------------------------------
-       (dabbrev--reset-global-variables)
        (setq dabbrev--last-abbreviation abbrev)
        ;; Find all expansion
        (let ((completion-list
-              (dabbrev--find-all-expansions abbrev ignore-case-p)))
+              (dabbrev--find-all-expansions abbrev ignore-case-p))
+             (completion-ignore-case ignore-case-p))
          ;; Make an obarray with all expansions
          (setq my-obarray (make-vector (length completion-list) 0))
          (or (> (length my-obarray) 0)
-             (error "No dynamic expansion for \"%s\" found%s."
+             (error "No dynamic expansion for \"%s\" found%s"
                     abbrev
                     (if dabbrev--check-other-buffers "" " in this-buffer")))
          (cond
@@ -415,20 +402,20 @@ before making a new one."
                (not dabbrev-case-replace))
            (mapc (function (lambda (string)
                              (intern string my-obarray)))
-                 completion-list))
+                   completion-list))
           ((string= abbrev (upcase abbrev))
            (mapc (function (lambda (string)
                              (intern (upcase string) my-obarray)))
-                 completion-list))
+                   completion-list))
           ((string= (substring abbrev 0 1)
                     (upcase (substring abbrev 0 1)))
            (mapc (function (lambda (string)
-                             (intern (dabbrev--capitalize string) my-obarray)))
-                 completion-list))
+                             (intern (capitalize string) my-obarray)))
+                   completion-list))
           (t
            (mapc (function (lambda (string)
                              (intern (downcase string) my-obarray)))
-                 completion-list)))
+                   completion-list)))
          (setq dabbrev--last-obarray my-obarray)
          (setq dabbrev--last-completion-buffer (current-buffer))
          ;; Find the longest common string.
@@ -443,7 +430,8 @@ before making a new one."
      ((and (not (string-equal init ""))
           (not (string-equal (downcase init) (downcase abbrev))))
       (if (> (length (all-completions init my-obarray)) 1)
-         (message "Repeat '%s' to see all completions" this-command)
+         (message "Repeat `%s' to see all completions"
+                  (key-description (this-command-keys)))
        (message "The only possible completion"))
       (dabbrev--substitute-expansion nil abbrev init))
      (t
@@ -451,7 +439,7 @@ before making a new one."
       (message "Making completion list...")
       (with-output-to-temp-buffer " *Completions*"
        (display-completion-list (all-completions init my-obarray)))
-      (message "Making completion list... Done.")))
+      (message "Making completion list...done")))
     (and (window-minibuffer-p (selected-window))
         (message nil))))
 
@@ -465,7 +453,7 @@ considered.  If still no suitable word is found, then look in the
 buffers accepted by the function pointed out by variable
 `dabbrev-friend-buffer-function'.
 
-A positive prefix argument, N, says to take the Nth backward _distinct_
+A positive prefix argument, N, says to take the Nth backward *distinct*
 possibility.  A negative argument says search forward.
 
 If the cursor has not moved from the end of the previous expansion and
@@ -475,156 +463,185 @@ with the next possible expansion not yet tried.
 The variable `dabbrev-backward-only' may be used to limit the
 direction of search to backward if set non-nil.
 
-To make it more powerful, make sure that
-`dabbrev-always-check-other-buffers' is set to t.
-
-Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
+See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
   (interactive "*P")
-  (let (abbrev expansion old direction)
+  (let (abbrev record-case-pattern
+              expansion old direction (orig-point (point)))
     ;; abbrev -- the abbrev to expand
     ;; expansion -- the expansion found (eventually) or nil until then
     ;; old -- the text currently in the buffer
     ;;    (the abbrev, or the previously-made expansion)
     (save-excursion
       (if (and (null arg)
-              dabbrev--last-abbrev-location
+              (markerp dabbrev--last-abbrev-location)
+              (marker-position dabbrev--last-abbrev-location)
               (or (eq last-command this-command)
                   (and (window-minibuffer-p (selected-window))
                        (= dabbrev--last-abbrev-location
                           (point)))))
-         ;;--------------------------------
-         ;; This is a redo.
-         ;;--------------------------------
+         ;; Find a different expansion for the same abbrev as last time.
          (progn
            (setq abbrev dabbrev--last-abbreviation)
            (setq old dabbrev--last-expansion)
            (setq direction dabbrev--last-direction))
-       ;;--------------------------------
-       ;; New abbreviation to expand.
-       ;;--------------------------------
-       (dabbrev--reset-global-variables)
-       (setq direction (if (null arg)
-                           (if dabbrev-backward-only 1 0)
-                         (prefix-numeric-value arg)))
-       (setq abbrev (dabbrev--abbrev-at-point))
-       (setq old nil))
+       ;; If the user inserts a space after expanding
+       ;; and then asks to expand again, always fetch the next word.
+       (if (and (eq (preceding-char) ?\ )
+                (markerp dabbrev--last-abbrev-location)
+                (marker-position dabbrev--last-abbrev-location)
+                (= (point) (1+ dabbrev--last-abbrev-location)))
+           (progn
+             ;; The "abbrev" to expand is just the space.
+             (setq abbrev " ")
+             (save-excursion
+               (if dabbrev--last-buffer
+                   (set-buffer dabbrev--last-buffer))
+               ;; Find the end of the last "expansion" word.
+               (if (or (eq dabbrev--last-direction 1)
+                       (and (eq dabbrev--last-direction 0)
+                            (< dabbrev--last-expansion-location (point))))
+                   (setq dabbrev--last-expansion-location
+                         (+ dabbrev--last-expansion-location
+                            (length dabbrev--last-expansion))))
+               (goto-char dabbrev--last-expansion-location)
+               ;; Take the following word, with intermediate separators,
+               ;; as our expansion this time.
+               (re-search-forward
+                (concat "\\(\\(" dabbrev--abbrev-char-regexp "\\)+\\)"))
+               (setq expansion (buffer-substring-no-properties
+                                dabbrev--last-expansion-location (point)))
+               (if dabbrev--last-case-pattern
+                   (setq expansion (upcase expansion)))
+
+               ;; Record the end of this expansion, in case we repeat this.
+               (setq dabbrev--last-expansion-location (point)))
+             ;; Indicate that dabbrev--last-expansion-location is
+             ;; at the end of the expansion.
+             (setq dabbrev--last-direction -1))
+
+         ;; We have a different abbrev to expand.
+         (dabbrev--reset-global-variables)
+         (setq direction (if (null arg)
+                             (if dabbrev-backward-only 1 0)
+                           (prefix-numeric-value arg)))
+         (setq abbrev (dabbrev--abbrev-at-point))
+         (setq record-case-pattern t)
+         (setq old nil)))
 
       ;;--------------------------------
       ;; Find the expansion
       ;;--------------------------------
-      (setq expansion
-           (dabbrev--find-expansion abbrev direction
-                                    (and (eval dabbrev-case-fold-search)
-                                         (or (not dabbrev-upcase-means-case-search)
-                                             (string= abbrev (downcase abbrev)))))))
+      (or expansion
+         (setq expansion
+               (dabbrev--find-expansion abbrev direction
+                                        (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+                                                 case-fold-search
+                                               dabbrev-case-fold-search)
+                                             (or (not dabbrev-upcase-means-case-search)
+                                                 (string= abbrev (downcase abbrev))))))))
     (cond
      ((not expansion)
       (dabbrev--reset-global-variables)
       (if old
          (save-excursion
-           (search-backward (substring old (length abbrev)))
-           (delete-region (match-beginning 0) (match-end 0))))
-      (error "No%s dynamic expansion for \"%s\" found."
+           (setq buffer-undo-list (cons orig-point buffer-undo-list))
+           ;; Put back the original abbrev with its original case pattern.
+           (search-backward old)
+           (insert abbrev)
+           (delete-region (point) (+ (point) (length old)))))
+      (error "No%s dynamic expansion for `%s' found"
             (if old " further" "") abbrev))
      (t
-      (if (not (eq dabbrev--last-buffer dabbrev--last-buffer-found))
+      (if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found)
+                  (minibuffer-window-active-p (selected-window))))
          (progn
            (message "Expansion found in '%s'"
                     (buffer-name dabbrev--last-buffer))
            (setq dabbrev--last-buffer-found dabbrev--last-buffer))
        (message nil))
+      (if (and (or (eq (current-buffer) dabbrev--last-buffer)
+                  (null dabbrev--last-buffer))
+              (numberp dabbrev--last-expansion-location)
+              (and (> dabbrev--last-expansion-location (point))))
+         (setq dabbrev--last-expansion-location
+               (copy-marker dabbrev--last-expansion-location)))
       ;; Success: stick it in and return.
+      (setq buffer-undo-list (cons orig-point buffer-undo-list))
       (dabbrev--substitute-expansion old abbrev expansion)
+
+      ;; If we are not copying successive words now,
+      ;; set dabbrev--last-case-pattern.
+      (and record-case-pattern
+          (setq dabbrev--last-case-pattern
+                (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+                         case-fold-search
+                       dabbrev-case-fold-search)
+                     (not dabbrev-upcase-means-case-search)
+                     (equal abbrev (upcase abbrev)))))
+
       ;; Save state for re-expand.
-      (setq dabbrev--last-expansion expansion) 
+      (setq dabbrev--last-expansion expansion)
       (setq dabbrev--last-abbreviation abbrev)
       (setq dabbrev--last-abbrev-location (point-marker))))))
 
-(eval-when-compile (require 'reporter))
-(defun dabbrev-submit-feedback ()
-  "Submit via mail a bug report on the dabbrev package."
-  (interactive)
-  (require 'reporter)
-  (and (y-or-n-p "Do you really want to submit a report on the dabbrev package? ")
-       (reporter-submit-bug-report
-       "Lars Lindberg <lli@sypro.cap.se>"
-       (format "new-dabbrev.el (Release %s)" (dabbrev--version))
-       '(dabbrev-backward-only
-         dabbrev-limit
-         dabbrev-case-fold-search
-         dabbrev-case-replace
-         dabbrev-upcase-means-case-search
-         dabbrev-abbrev-char-regexp
-         dabbrev-always-check-other-buffers
-         dabbrev-select-buffers-function
-         dabbrev-friend-buffer-function)
-       nil nil nil)))
-
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-;;; Local functions
-;;;----------------------------------------------------------------
-;;;----------------------------------------------------------------
-
-(defun dabbrev--capitalize (string)
-  ;; Capitalize STRING (See capitalize-word)
-  (let ((new-string ""))
-    (save-match-data
-      (while (string-match "\\w+" string)
-       (let* ((mb (match-beginning 0))
-              (me (match-end 0))
-              (ms (substring string mb me)))
-         (setq new-string
-               (concat new-string
-                       (substring string 0 mb)
-                       (upcase (substring ms 0 1))
-                       (downcase (substring ms 1))))
-         (setq string (substring string me)))))
-    new-string))
+;;----------------------------------------------------------------
+;; Local functions
+;;----------------------------------------------------------------
 
 ;;; Checks if OTHER-BUFFER has the same major mode as current buffer.
 (defun dabbrev--same-major-mode-p (other-buffer)
-  (let ((orig-mode major-mode))
-    (save-excursion
-      (set-buffer other-buffer)
-      (eq orig-mode major-mode))))
+  (eq major-mode
+      (save-excursion
+       (set-buffer other-buffer)
+       major-mode)))
 
 ;;; Back over all abbrev type characters and then moves forward over
 ;;; all skip characters.
 (defun dabbrev--goto-start-of-abbrev ()
   ;; Move backwards over abbrev chars
   (save-match-data
-    (when (not (bobp))
-      (forward-char -1)
-      (while (and (looking-at dabbrev--abbrev-char-regexp)
-                 (not (bobp)))
-       (forward-char -1))
-      (or (looking-at dabbrev--abbrev-char-regexp)
-         (forward-char 1)))
+    (if (not (bobp))
+       (progn
+         (forward-char -1)
+         (while (and (looking-at dabbrev--abbrev-char-regexp)
+                     (not (bobp)))
+           (forward-char -1))
+         (or (looking-at dabbrev--abbrev-char-regexp)
+             (forward-char 1))))
     (and dabbrev-abbrev-skip-leading-regexp
         (while (looking-at dabbrev-abbrev-skip-leading-regexp)
           (forward-char 1)))))
 
-;;; Extract the symbol at point to serve as abbrevitation.
+;;; Extract the symbol at point to serve as abbreviation.
 (defun dabbrev--abbrev-at-point ()
   ;; Check for error
-  (save-excursion
-    (save-match-data
-      (if (or (bobp)
-             (progn 
-               (forward-char -1)
-               (not (looking-at (concat "\\("
-                                        (or dabbrev-abbrev-char-regexp
-                                            "\\sw\\|\\s_")
-                                        "\\)+")))))
-         (error "Not positioned immediately after an abbreviation."))))
+  (if (bobp)
+      (error "No possible abbreviation preceding point"))
   ;; Return abbrev at point
   (save-excursion
+    ;; Record the end of the abbreviation.
     (setq dabbrev--last-abbrev-location (point))
-    (buffer-substring (point) 
-                     (progn (dabbrev--goto-start-of-abbrev)
-                            (point)))))
-       
+    ;; If we aren't right after an abbreviation,
+    ;; move point back to just after one.
+    ;; This is so the user can get successive words
+    ;; by typing the punctuation followed by M-/.
+    (save-match-data
+      (if (save-excursion
+           (forward-char -1)
+           (not (looking-at (concat "\\("
+                                    (or dabbrev-abbrev-char-regexp
+                                        "\\sw\\|\\s_")
+                                    "\\)+"))))
+         (if (re-search-backward (or dabbrev-abbrev-char-regexp
+                                     "\\sw\\|\\s_")
+                                 nil t)
+             (forward-char 1)
+           (error "No possible abbreviation preceding point"))))
+    ;; Now find the beginning of that one.
+    (dabbrev--goto-start-of-abbrev)
+    (buffer-substring-no-properties
+     dabbrev--last-abbrev-location (point))))
+
 ;;; Initializes all global variables
 (defun dabbrev--reset-global-variables ()
   ;; dabbrev--last-obarray and dabbrev--last-completion-buffer
@@ -640,7 +657,7 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
        dabbrev--last-buffer-found nil
        dabbrev--abbrev-char-regexp (or dabbrev-abbrev-char-regexp
                                        "\\sw\\|\\s_")
-       dabbrev--check-other-buffers dabbrev-always-check-other-buffers))
+       dabbrev--check-other-buffers dabbrev-check-other-buffers))
 
 ;;; Find all buffers that are considered "friends" according to the
 ;;; function pointed out by dabbrev-friend-buffer-function.
@@ -649,40 +666,31 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
     (and (window-minibuffer-p (selected-window))
         (set-buffer (dabbrev--minibuffer-origin)))
     (let ((orig-buffer (current-buffer)))
-      (loop for buffer
-           in (buffer-list)
-           if (and (not (eq orig-buffer buffer))
-                   (boundp 'dabbrev-friend-buffer-function)
-                   (funcall dabbrev-friend-buffer-function buffer))
-           collect buffer))))
-
-;;; Try to find ABBREV in REVERSE direction N times.
+      (dabbrev-filter-elements
+       buffer (buffer-list)
+       (and (not (eq orig-buffer buffer))
+           (boundp 'dabbrev-friend-buffer-function)
+           (funcall dabbrev-friend-buffer-function buffer))))))
+
+;;; Search for ABBREV, N times, normally looking forward,
+;;; but looking in reverse instead if REVERSE is non-nil.
 (defun dabbrev--try-find (abbrev reverse n ignore-case)
   (save-excursion
-    (let ((case-fold-search-is-local (memq 'case-fold-search
-                                          (buffer-local-variables)))
-         (expansion nil))
-      (and dabbrev--last-expansion-location
-          (goto-char dabbrev--last-expansion-location))
-      (unwind-protect
-         (progn
-           (or case-fold-search-is-local
-               (make-local-variable 'case-fold-search))
-           ;; Tricky! If `case-fold-search' isn't buffer-local, then
-           ;; this innocent let creates a buffer-local variable and
-           ;; when the let returns, it is still there!  The
-           ;; unwind-protect stuff around this makes sure that there
-           ;; exists one before the let, and removes it afterwards.
-           (let ((case-fold-search ignore-case))
-             (loop repeat n
-                   while (setq expansion (dabbrev--search abbrev
-                                                          reverse
-                                                          ignore-case)))))
-       (or case-fold-search-is-local
-           (kill-local-variable 'case-fold-search)))
-      (and expansion
-          (setq dabbrev--last-expansion-location (point)))
-      expansion)))
+    (save-restriction
+      (widen)
+      (let ((expansion nil))
+       (and dabbrev--last-expansion-location
+            (goto-char dabbrev--last-expansion-location))
+       (let ((case-fold-search ignore-case)
+             (count n))
+         (while (and (> count 0)
+                     (setq expansion (dabbrev--search abbrev
+                                                      reverse
+                                                      ignore-case)))
+           (setq count (1- count))))
+       (and expansion
+            (setq dabbrev--last-expansion-location (point)))
+       expansion))))
 
 ;;; Find all expansions of ABBREV
 (defun dabbrev--find-all-expansions (abbrev ignore-case)
@@ -691,11 +699,11 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
     (save-excursion
       (goto-char (point-min))
       (while (setq expansion (dabbrev--find-expansion abbrev -1 ignore-case))
-       (push expansion all-expansions)))
+       (setq all-expansions (cons expansion all-expansions))))
     all-expansions))
 
 (defun dabbrev--scanning-message ()
-  (message "Scanning '%s'" (buffer-name (current-buffer))))
+  (message "Scanning `%s'" (buffer-name (current-buffer))))
 
 ;;; Find one occasion of ABBREV.
 ;;; DIRECTION > 0 means look that many times backwards.
@@ -755,20 +763,39 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
            (not (or (eq dabbrev--check-other-buffers t)
                     (progn
                       (setq dabbrev--check-other-buffers
-                            (y-or-n-p "Check in other buffers this time? ")))))
+                            (y-or-n-p "Scan other buffers also? ")))))
            (let* (friend-buffer-list non-friend-buffer-list)
              (setq dabbrev--friend-buffer-list
                    (funcall dabbrev-select-buffers-function))
-             (when dabbrev-check-rest-of-buffers
-               (setq non-friend-buffer-list
-                     (nreverse
-                      (loop for buffer
-                            in (buffer-list)
-                            if (not (memq buffer dabbrev--friend-buffer-list))
-                            collect buffer)))
-               (setq dabbrev--friend-buffer-list
-                     (append dabbrev--friend-buffer-list
-                             non-friend-buffer-list)))))
+             (if dabbrev-check-all-buffers
+                 (setq non-friend-buffer-list
+                       (nreverse
+                        (dabbrev-filter-elements
+                         buffer (buffer-list)
+                         (let ((bn (buffer-name buffer)))
+                           (and (not (member bn dabbrev-ignored-buffer-names))
+                                (not (memq buffer dabbrev--friend-buffer-list))
+                                (not
+                                 (let ((tail dabbrev-ignored-regexps)
+                                       (match nil))
+                                   (while (and tail (not match))
+                                     (setq match (string-match (car tail) bn)
+                                           tail (cdr tail)))
+                                   match))))))
+                       dabbrev--friend-buffer-list
+                       (append dabbrev--friend-buffer-list
+                               non-friend-buffer-list)))))
+       ;; Move buffers that are visible on the screen
+       ;; to the front of the list.  Remove the current buffer.
+       (when dabbrev--friend-buffer-list
+         (walk-windows (lambda (w)
+                         (unless (eq w (selected-window))
+                           (setq dabbrev--friend-buffer-list
+                                 (cons (window-buffer w)
+                                       (delq (window-buffer w)
+                                             dabbrev--friend-buffer-list))))))
+         (setq dabbrev--friend-buffer-list
+               (delq (current-buffer) dabbrev--friend-buffer-list)))
        ;; Walk through the buffers
        (while (and (not expansion) dabbrev--friend-buffer-list)
          (setq dabbrev--last-buffer
@@ -781,8 +808,6 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
          (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case)))
        expansion)))))
 
-(eval-when-compile (require 'picture))
-
 (defun dabbrev--safe-replace-match (string &optional fixedcase literal)
   (if (eq major-mode 'picture-mode)
       (picture-replace-match string fixedcase literal)
@@ -795,17 +820,40 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
 ;;; EXPANSION is the expansion substring.
 (defun dabbrev--substitute-expansion (old abbrev expansion)
   ;;(undo-boundary)
-  (let ((use-case-replace (and (eval dabbrev-case-fold-search)
+  (let ((use-case-replace (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+                                  case-fold-search
+                                dabbrev-case-fold-search)
                               (or (not dabbrev-upcase-means-case-search)
                                   (string= abbrev (downcase abbrev)))
-                              (eval dabbrev-case-replace))))
+                              (if (eq dabbrev-case-replace 'case-replace)
+                                  case-replace
+                                dabbrev-case-replace))))
     (and nil use-case-replace
         (setq old (concat abbrev (or old "")))
         (setq expansion (concat abbrev expansion)))
+    ;; If the expansion has mixed case
+    ;; and it is not simply a capitalized word,
+    ;; or if the abbrev has mixed case,
+    ;; and if the given abbrev's case pattern
+    ;; matches the start of the expansion,
+    ;; copy the expansion's case
+    ;; instead of downcasing all the rest.
+    (let ((expansion-rest (substring expansion 1)))
+      (if (and (not (and (or (string= expansion-rest (downcase expansion-rest))
+                            (string= expansion-rest (upcase expansion-rest)))
+                        (or (string= abbrev (downcase abbrev))
+                            (string= abbrev (upcase abbrev)))))
+              (string= abbrev
+                       (substring expansion 0 (length abbrev))))
+         (setq use-case-replace nil)))
+    (if (equal abbrev " ")
+       (setq use-case-replace nil))
+    (if use-case-replace
+       (setq expansion (downcase expansion)))
     (if old
        (save-excursion
          (search-backward old))
-      ;;(store-match-data (list (point-marker) (point-marker)))
+      ;;(set-match-data (list (point-marker) (point-marker)))
       (search-backward abbrev))
     ;; Make case of replacement conform to case of abbreviation
     ;; provided (1) that kind of thing is enabled in this buffer
@@ -818,9 +866,9 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
 ;;;----------------------------------------------------------------
 ;;; Search function used by dabbrevs library.
 
-;;; ABBREV is string to find as prefix of word. Second arg, REVERSE,
+;;; ABBREV is string to find as prefix of word.  Second arg, REVERSE,
 ;;; is t for reverse search, nil for forward.  Variable dabbrev-limit
-;;; controls the maximum search region size.  Third argment IGNORE-CASE
+;;; controls the maximum search region size.  Third argument IGNORE-CASE
 ;;; non-nil means treat case as insignificant while looking for a match
 ;;; and when comparing with previous matches.  Also if that's non-nil
 ;;; and the match is found at the beginning of a sentence and is in
@@ -853,42 +901,44 @@ Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
                    (if reverse
                        (re-search-backward pattern1 nil t)
                      (re-search-forward pattern1 nil t)))
-         (cond
-          ((progn
-             (goto-char (match-beginning 0))
-             (dabbrev--goto-start-of-abbrev)
-             (/= (point) (match-beginning 0)))
-           ;; Prefix of found abbreviation not OK
-           nil)
-          (t
-           (goto-char (match-beginning 0))
+         (goto-char (match-beginning 0))
+         ;; In case we matched in the middle of a word,
+         ;; back up to start of word and verify we still match.
+         (dabbrev--goto-start-of-abbrev)
+
+         (if (not (looking-at pattern1))
+             nil
+           ;; We have a truly valid match.  Find the end.
            (re-search-forward pattern2)
-           (setq found-string
-                 (buffer-substring (match-beginning 1) (match-end 1)))
+           (setq found-string (buffer-substring-no-properties
+                               (match-beginning 1) (match-end 1)))
            (and ignore-case (setq found-string (downcase found-string)))
-           ;; Throw away if found in table
-           (when (some
-                 (function
-                  (lambda (table-string) (string= found-string table-string)))
-                 dabbrev--last-table)
-             (setq found-string nil))))
+           ;; Ignore this match if it's already in the table.
+           (if (dabbrev-filter-elements
+                table-string dabbrev--last-table
+                (string= found-string table-string))
+               (setq found-string nil)))
+         ;; Prepare to continue searching.
          (if reverse
              (goto-char (match-beginning 0))
            (goto-char (match-end 0))))
-       (cond
-        (found-string
-         ;;--------------------------------
-         ;; Put in `dabbrev--last-table' and decide if we should return
-         ;; result or (downcase result)
-         ;;--------------------------------
-         (push found-string dabbrev--last-table)
-         (let ((result (buffer-substring (match-beginning 0) (match-end 0))))
-           (if (and ignore-case (eval dabbrev-case-replace))
-               (downcase result)
-             result))))))))
-
-(provide 'new-dabbrev)
-(provide 'dabbrev)
-;; new-dabbrev.el ends here
+       ;; If we found something, use it.
+       (if found-string
+           ;; Put it into `dabbrev--last-table'
+           ;; and return it (either downcased, or as is).
+           (let ((result (buffer-substring-no-properties
+                          (match-beginning 0) (match-end 0))))
+             (setq dabbrev--last-table
+                   (cons found-string dabbrev--last-table))
+             (if (and ignore-case (eval dabbrev-case-replace))
+                 result
+               result)))))))
+
+(dolist (mess '("^No dynamic expansion for .* found$"
+               "^No further dynamic expansion for .* found$"
+               "^No possible abbreviation preceding point$"))
+  (add-to-list 'debug-ignored-errors mess))
 
+(provide 'dabbrev)
 
+;;; dabbrev.el ends here