emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] xwidget 8628a48 2/2: Merge branch 'master' into xwidget


From: Joakim Verona
Subject: [Emacs-diffs] xwidget 8628a48 2/2: Merge branch 'master' into xwidget
Date: Tue, 20 Jan 2015 23:36:15 +0000

branch: xwidget
commit 8628a48fec7fcd8bdbbf6ce5808fc574631d1541
Merge: ffd9ee1 0dd19ac
Author: Joakim Verona <address@hidden>
Commit: Joakim Verona <address@hidden>

    Merge branch 'master' into xwidget
---
 etc/NEWS                          |   15 +-
 lisp/ChangeLog                    |   83 ++++-
 lisp/descr-text.el                |   96 ++++
 lisp/emacs-lisp/bytecomp.el       |    2 +-
 lisp/emacs-lisp/cl-generic.el     |   23 +-
 lisp/emacs-lisp/eieio-compat.el   |  246 ++++++++++
 lisp/emacs-lisp/eieio-core.el     |   87 +++-
 lisp/emacs-lisp/eieio-generic.el  |  907 -------------------------------------
 lisp/emacs-lisp/eieio.el          |    1 -
 lisp/emacs-lisp/eldoc.el          |    7 +-
 lisp/emacs-lisp/macroexp.el       |   39 +-
 lisp/hexl.el                      |    4 +-
 lisp/ielm.el                      |    6 +-
 lisp/progmodes/cfengine.el        |    3 +-
 lisp/progmodes/elisp-mode.el      |    4 +-
 lisp/progmodes/etags.el           |   24 +-
 lisp/progmodes/octave.el          |    3 +-
 lisp/progmodes/python.el          |    4 +-
 lisp/progmodes/xref.el            |    6 +-
 lisp/simple.el                    |    4 +-
 lisp/textmodes/paragraphs.el      |    4 +-
 lisp/textmodes/tildify.el         |  105 +++++-
 lisp/vc/vc-dir.el                 |    2 +-
 src/ChangeLog                     |   54 +++
 src/alloc.c                       |    4 +-
 src/coding.c                      |    4 +-
 src/dispnew.c                     |   16 +-
 src/gtkutil.c                     |    2 +-
 src/lisp.h                        |    8 +-
 src/minibuf.c                     |    2 +-
 src/nsfont.m                      |    2 +-
 src/nsterm.m                      |    5 +-
 src/w32fns.c                      |    2 +-
 src/xdisp.c                       |   39 +-
 src/xfns.c                        |    6 +-
 test/ChangeLog                    |   26 +
 test/automated/descr-text-test.el |   94 ++++
 test/automated/package-test.el    |   17 -
 test/automated/tildify-tests.el   |   71 +++
 39 files changed, 983 insertions(+), 1044 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 4551c9c..548b54d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -208,6 +208,8 @@ If you need your objects to be named, do it by inheriting 
from `eieio-named'.
 *** The <class>-list-p and <class>-child-p functions are declared obsolete.
 *** The <class> variables are declared obsolete.
 *** The <initarg> variables are declared obsolete.
+*** defgeneric and defmethod are declared obsolete.
+
 ** ido
 *** New command `ido-bury-buffer-at-head' bound to C-S-b
 Bury the buffer at the head of `ido-matches', analogous to how C-k
@@ -238,8 +240,12 @@ typing RET.
 result of the calculation into the current buffer.
 
 ** ElDoc
-*** New minor mode global-eldoc-mode
-*** eldoc-documentation-function now defaults to nil
+*** New minor mode `global-eldoc-mode'
+*** `eldoc-documentation-function' now defaults to `ignore'
+*** `describe-char-eldoc' displays information about character at point,
+and can be used as a default value of `eldoc-documentation-function'.  It is
+useful when, for example, one needs to distinguish various spaces (e.g. ] [,
+] [, ] [, etc.) while using mono-spaced font.
 
 ** eww
 
@@ -494,6 +500,11 @@ As a result of the above, these commands are now obsolete:
 ** let-alist is a new macro (and a package) that allows one to easily
 let-bind the values stored in an alist.
 
+** `tildify-mode' allows to automatically insert hard spaces as one
+types the text.  Breaking line after a single-character words is
+forbidden by Czech and Polish typography (and may be discouraged in
+other languages), so `auto-tildify-mode' makes it easier to create
+a typographically-correct documents.
 
 * Incompatible Lisp Changes in Emacs 25.1
 
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b1a3a73..b5824ab 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,77 @@
+2015-01-20  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/eieio-generic.el: Remove.
+       (defgeneric, defmethod): Move to eieio-compat.el.  Mark obsolete.
+       * emacs-lisp/eieio-compat.el: New file.
+       * emacs-lisp/eieio.el: Don't require eieio-generic any more.
+       * emacs-lisp/eieio-core.el (eieio--slot-originating-class-p):
+       Remove unused function.
+       (eieio-defclass): Move to eieio-compat.el.
+       * emacs-lisp/macroexp.el (macroexp-macroexpand): New function.
+       (macroexp--expand-all): Use it.
+       * emacs-lisp/bytecomp.el (byte-compile-recurse-toplevel): Here too.
+
+2015-01-20  Michal Nazarewicz  <address@hidden>
+
+       * emacs-lisp/eldoc.el (eldoc-documentation-function): Describe how
+       major modes should use `add-function' to alter value of the variable.
+       * hexl.el (hexl-mode):
+       * ielm.el (inferior-emacs-lisp-mode):
+       * progmodes/cfengine.el (cfengine3-mode):
+       * progmodes/elisp-mode (emacs-lisp-mode):
+       * progmodes/octave.el (octave-mode):
+       * progmodes/python.el (python-mode):
+       * simple.el (read--expression): Set `eldoc-documentation-function'
+       using `add-function' so the default value is always used.
+
+       * descr-text.el (describe-char-eldoc): New function returning
+       basic Unicode codepoint information (e.g. name) about character
+       at point.  It is meant to be used as a default value of the
+       `eldoc-documentation-function' variable.
+       (describe-char-eldoc--format, describe-char-eldoc--truncate):
+       New helper functions for `describe-char-eldoc' function.
+
+2015-01-20  Michal Nazarewicz  <address@hidden>
+
+       * textmodes/paragraphs.el (sentence-end-base): Include an
+       ellipsis (…) and interrobang (‽) characters as end of a sentence,
+       and a closing single quote (’) as an end of a quote.
+
+2015-01-20  Michal Nazarewicz  <address@hidden>
+
+       * textmodes/tildify.el (tildify-double-space-undos): A new
+       variable specifying whether pressing space in `tildify-mode' after
+       a space has been replaced with hard space undos the substitution.
+       (tildify-space): Add code branch for handling `tildify-doule-space'.
+
+       * textmodes/tildify.el (tildify-space): A new function
+       which can be used as a `post-self-insert-hook' to automatically
+       convert spaces into hard spaces.
+       (tildify-space-pattern): A new variable specifying pattern where
+       `tildify-space' should take effect.
+       (tildify-space-predicates): A new variable specifying list of
+       predicate functions that all must return non-nil for
+       `tildify-space' to take effect.
+       (tildify-space-region-predicate): A new functions meant to be
+       used as a predicate in `tildify-space-predicates' list.
+       (tildify-mode): A new minor mode enabling `tildify-space' as a
+       `post-self-insert-hook'
+
+2015-01-20  Daniel Colascione  <address@hidden>
+
+       * vc/vc-dir.el (vc-dir): Default to repository root, not
+       default-directory.
+
+2015-01-20  Dmitry Gutov  <address@hidden>
+
+       * progmodes/etags.el (xref-etags-location): New class.
+       (xref-make-etags-location): New function.
+       (etags--xref-find-definitions): Use it.
+       (xref-location-marker): New method implementation.
+
+       * progmodes/xref.el: Mention that xref-location is an EIEIO class.
+       (xref--insert-xrefs): Expand help-echo string.
+
 2015-01-19  Dmitry Gutov  <address@hidden>
 
        * ido.el: Update Customization instructions.
@@ -32,8 +106,8 @@
        (xref--save-to-history): New function.
        (xref--display-position): Use it.  Add new argument.
        (xref--restore-window-configuration): Remove.
-       (xref--show-location, xref-show-location-at-point): Update
-       accordingly.
+       (xref--show-location, xref-show-location-at-point):
+       Update accordingly.
        (xref--xref-buffer-mode): Don't use `pre-command-hook'.
        (xref--quit): New command.
        (xref-goto-xref): Use it.
@@ -79,6 +153,11 @@
 
 2015-01-18  Stefan Monnier  <address@hidden>
 
+       * emacs-lisp/eieio-core.el: Add `subclass' specializer for cl-generic.
+       (eieio--generic-subclass-tagcode, eieio--generic-subclass-tag-types):
+       New functions.
+       (cl-generic-tagcode-function, cl-generic-tag-types-function): Use them.
+
        * emacs-lisp/cl-macs.el (cl-defstruct): Minor optimization when include
        or print is nil.
        (cl-struct-type-p): New function.
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index b16c007..d6f64c7 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -825,6 +825,102 @@ relevant to POS."
 
 (define-obsolete-function-alias 'describe-char-after 'describe-char "22.1")
 
+;;; Describe-Char-ElDoc
+
+(defun describe-char-eldoc--truncate (name width)
+  "Truncate NAME at white spaces such that it is no longer than WIDTH.
+
+Split NAME on white space character and return string with as
+many leading words of NAME as possible without exceeding WIDTH
+characters.  If NAME consists of white space characters only,
+return an empty string.  Three dots (\"...\") are appended to
+returned string if some of the words from NAME have been omitted.
+
+NB: Function may return string longer than WIDTH if name consists
+of a single word, or it's first word is longer than WIDTH
+characters."
+  (let ((words (split-string name)))
+    (if words
+        (let ((last words))
+          (setq width (- width (length (car words))))
+          (while (and (cdr last)
+                      (<= (+ (length (cadr last)) (if (cddr last) 4 1)) width))
+            (setq last (cdr last))
+            (setq width (- width (length (car last)) 1)))
+          (let ((ellipsis (and (cdr last) "...")))
+            (setcdr last nil)
+            (concat (mapconcat 'identity words " ") ellipsis)))
+      "")))
+
+(defun describe-char-eldoc--format (ch &optional width)
+  "Format a description for character CH which is no more than WIDTH 
characters.
+
+Full description message has a \"U+HEX: NAME (GC: GENERAL-CATEGORY)\"
+format where:
+- HEX is a hexadecimal codepoint of the character (zero-padded to at
+  least four digits),
+- NAME is name of the character.
+- GC is a two-letter abbreviation of the general-category of the
+  character, and
+- GENERAL-CATEGORY is full name of the general-category of the
+  character.
+
+If WIDTH is non-nil some elements of the description may be
+omitted to accommodate the length restriction.  Under certain
+condition, the function may return string longer than WIDTH, see
+`describe-char-eldoc--truncate'."
+  (let ((name (get-char-code-property ch 'name)))
+    (when name
+      (let* ((code (propertize (format "U+%04X" ch)
+                               'face 'font-lock-constant-face))
+             (gc (get-char-code-property ch 'general-category))
+             (gc-desc (char-code-property-description 'general-category gc)))
+
+        (unless (or (not width) (<= (length name) width))
+          (setq name (describe-char-eldoc--truncate name width)))
+        (setq name (concat (substring name 0 1) (downcase (substring name 1))))
+        (setq name (propertize name 'face 'font-lock-variable-name-face))
+
+        (setq gc (propertize (symbol-name gc) 'face 'font-lock-comment-face))
+        (when gc-desc
+          (setq gc-desc (propertize gc-desc 'face 'font-lock-comment-face)))
+
+        (let ((lcode    (length code))
+              (lname    (length name))
+              (lgc      (length gc))
+              (lgc-desc (and gc-desc (length gc-desc))))
+          (cond
+           ((and gc-desc
+                 (or (not width) (<= (+ lcode lname lgc lgc-desc 7) width)))
+            (concat code ": " name " (" gc ": " gc-desc ")"))
+           ((and gc-desc (<= (+ lcode lname lgc-desc 5) width))
+            (concat code ": " name " (" gc-desc ")"))
+           ((or (not width) (<= (+ lcode lname lgc 5) width))
+            (concat code ": " name " (" gc ")"))
+           ((<= (+ lname lgc 3) width)
+            (concat name " (" gc ")"))
+           (t name)))))))
+
+;;;###autoload
+(defun describe-char-eldoc ()
+  "Return a description of character at point for use by ElDoc mode.
+
+Return nil if character at point is a printable ASCII
+character (i.e. codepoint between 32 and 127 inclusively).
+Otherwise return a description formatted by
+`describe-char-eldoc--format' function taking into account value
+of `eldoc-echo-area-use-multiline-p' variable and width of
+minibuffer window for width limit.
+
+This function is meant to be used as a value of
+`eldoc-documentation-function' variable."
+  (let ((ch (following-char)))
+    (when (and (not (zerop ch)) (or (< ch 32) (> ch 127)))
+      (describe-char-eldoc--format
+       ch
+       (unless (eq eldoc-echo-area-use-multiline-p t)
+         (1- (window-width (minibuffer-window))))))))
+
 (provide 'descr-text)
 
 ;;; descr-text.el ends here
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 1acd4fe..8440570 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -433,7 +433,7 @@ Return the compile-time value of FORM."
   ;; 3.2.3.1, "Processing of Top Level Forms".  The semantics are very
   ;; subtle: see test/automated/bytecomp-tests.el for interesting
   ;; cases.
-  (setf form (macroexpand form byte-compile-macro-environment))
+  (setf form (macroexp-macroexpand form byte-compile-macro-environment))
   (if (eq (car-safe form) 'progn)
       (cons 'progn
             (mapcar (lambda (subform)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 544f1fa..3bbddfc 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -37,9 +37,26 @@
 ;; Added elements:
 ;; - We support aliases to generic functions.
 ;; - The kind of thing on which to dispatch can be extended.
-;;   There is support in this file for (eql <val>) dispatch as well as dispatch
-;;   on the type of CL structs, and eieio-core.el adds support for EIEIO
-;;   defclass objects.
+;;   There is support in this file for dispatch on:
+;;   - (eql <val>)
+;;   - plain old types
+;;   - type of CL structs
+;;   eieio-core adds dispatch on:
+;;   - class of eieio objects
+;;   - actual class argument, using the syntax (subclass <class>).
+
+;; Efficiency considerations: overall, I've made an effort to make this fairly
+;; efficient for the expected case (e.g. no constant redefinition of methods).
+;; - Generic functions which do not dispatch on any argument are implemented
+;;   optimally (just as efficient as plain old functions).
+;; - Generic functions which only dispatch on one argument are fairly efficient
+;;   (not a lot of room for improvement, I think).
+;; - Multiple dispatch is implemented rather naively.  There's an extra `apply'
+;;   function call for every dispatch; we don't optimize each dispatch
+;;   based on the set of candidate methods remaining; we don't optimize the
+;;   order in which we performs the dispatches either;  If/when this
+;;   becomes a problem, we can try and optimize it.
+;; - call-next-method could be made more efficient, but isn't too terrible.
 
 ;;; Code:
 
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
new file mode 100644
index 0000000..34c06c0
--- /dev/null
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -0,0 +1,246 @@
+;;; eieio-compat.el --- Compatibility with Older EIEIO versions  -*- 
lexical-binding:t -*-
+
+;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc.
+
+;; Author: Eric M. Ludlam <address@hidden>
+;; Keywords: OO, lisp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Backward compatibility definition of old EIEIO functions in
+;; terms of newer equivalent.
+
+;; The main elements are the old EIEIO `defmethod' and `defgeneric' which are
+;; now implemented on top of cl-generic.  The differences we have to
+;; accommodate are:
+;; - EIEIO's :static methods (turned into a new `eieio--static' specializer).
+;; - EIEIO's support for `call-next-method' and `next-method-p' instead of
+;;   `cl-next-method-p' and `cl-call-next-method' (simple matter of renaming).
+;; - Different errors are signaled.
+;; - EIEIO's defgeneric does not reset the function.
+;; - EIEIO's no-next-method and no-applicable-method can't be aliases of
+;;   cl-generic's namesakes since they have different calling conventions,
+;;   which means that packages that (defmethod no-next-method ..) don't work.
+;; - EIEIO's `call-next-method' and `next-method-p' had dynamic scope whereas
+;;   cl-generic's `cl-next-method-p' and `cl-call-next-method' are lexically
+;;   scoped.
+
+;;; Code:
+
+(require 'eieio-core)
+(require 'cl-generic)
+
+(put 'eieio--defalias 'byte-hunk-handler
+     #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
+;;;###autoload
+(defun eieio--defalias (name body)
+  "Like `defalias', but with less side-effects.
+More specifically, it has no side-effects at all when the new function
+definition is the same (`eq') as the old one."
+  (cl-assert (not (symbolp body)))
+  (while (and (fboundp name) (symbolp (symbol-function name)))
+    ;; Follow aliases, so methods applied to obsolete aliases still work.
+    (setq name (symbol-function name)))
+  (unless (and (fboundp name)
+               (eq (symbol-function name) body))
+    (defalias name body)))
+
+;;;###autoload
+(defmacro defgeneric (method args &optional doc-string)
+  "Create a generic function METHOD.
+DOC-STRING is the base documentation for this class.  A generic
+function has no body, as its purpose is to decide which method body
+is appropriate to use.  Uses `defmethod' to create methods, and calls
+`defgeneric' for you.  With this implementation the ARGS are
+currently ignored.  You can use `defgeneric' to apply specialized
+top level documentation to a method."
+  (declare (doc-string 3) (obsolete cl-defgeneric "25.1"))
+  `(eieio--defalias ',method
+                    (eieio--defgeneric-init-form
+                     ',method
+                     ,(if doc-string (help-add-fundoc-usage doc-string 
args)))))
+
+;;;###autoload
+(defmacro defmethod (method &rest args)
+  "Create a new METHOD through `defgeneric' with ARGS.
+
+The optional second argument KEY is a specifier that
+modifies how the method is called, including:
+   :before  - Method will be called before the :primary
+   :primary - The default if not specified
+   :after   - Method will be called after the :primary
+   :static  - First arg could be an object or class
+The next argument is the ARGLIST.  The ARGLIST specifies the arguments
+to the method as with `defun'.  The first argument can have a type
+specifier, such as:
+  ((VARNAME CLASS) ARG2 ...)
+where VARNAME is the name of the local variable for the method being
+created.  The CLASS is a class symbol for a class made with `defclass'.
+A DOCSTRING comes after the ARGLIST, and is optional.
+All the rest of the args are the BODY of the method.  A method will
+return the value of the last form in the BODY.
+
+Summary:
+
+ (defmethod mymethod [:before | :primary | :after | :static]
+                     ((typearg class-name) arg2 &optional opt &rest rest)
+    \"doc-string\"
+     body)"
+  (declare (doc-string 3) (obsolete cl-defmethod "25.1")
+           (debug
+            (&define                    ; this means we are defining something
+             [&or name ("setf" :name setf name)]
+             ;; ^^ This is the methods symbol
+             [ &optional symbolp ]                ; this is key :before etc
+             list                                 ; arguments
+             [ &optional stringp ]                ; documentation string
+             def-body                             ; part to be debugged
+             )))
+  (let* ((key (if (keywordp (car args)) (pop args)))
+        (params (car args))
+        (arg1 (car params))
+         (fargs (if (consp arg1)
+                   (cons (car arg1) (cdr params))
+                 params))
+        (class (if (consp arg1) (nth 1 arg1)))
+         (code `(lambda ,fargs ,@(cdr args))))
+    `(progn
+       ;; Make sure there is a generic and the byte-compiler sees it.
+       (defgeneric ,method ,args)
+       (eieio--defmethod ',method ',key ',class #',code))))
+
+(add-function :before-until cl-generic-tagcode-function
+              #'eieio--generic-static-tagcode)
+(defun eieio--generic-static-tagcode (type name)
+  (and (eq 'eieio--static (car-safe type))
+       `(40 . (cond
+               ((symbolp ,name) (eieio--class-v ,name))
+               ((vectorp ,name) (aref ,name 0))))))
+
+(add-function :around cl-generic-tag-types-function
+              #'eieio--generic-static-tag-types)
+(defun eieio--generic-static-tag-types (orig-fun tag)
+  (cond
+   ((or (eieio--class-p tag)
+        (and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag))))
+    (let ((superclasses (funcall orig-fun tag))
+          (types ()))
+      ;; Interleave: (subclass <foo>) (eieio--static <foo>) <subclass <bar>) ..
+      (dolist (superclass superclasses)
+        (push superclass types)
+        (push `(eieio--static
+                ,(if (consp superclass) (cadr superclass) superclass))
+              types))
+      (nreverse types)))
+   (t (funcall orig-fun tag))))
+
+;;;###autoload
+(defun eieio--defgeneric-init-form (method doc-string)
+  (if doc-string (put method 'function-documentation doc-string))
+  (if (memq method '(no-next-method no-applicable-method))
+      (symbol-function method)
+    (let ((generic (cl-generic-ensure-function method)))
+      (symbol-function (cl--generic-name generic)))))
+
+;;;###autoload
+(defun eieio--defmethod (method kind argclass code)
+  (setq kind (intern (downcase (symbol-name kind))))
+  (let* ((specializer (if (not (eq kind :static))
+                          (or argclass t)
+                        (setq kind nil)
+                        `(eieio--static ,argclass)))
+         (uses-cnm (not (memq kind '(:before :after))))
+         (specializers `((arg ,specializer)))
+         (code
+          ;; Backward compatibility for `no-next-method' and
+          ;; `no-applicable-method', which have slightly different calling
+          ;; convention than their cl-generic counterpart.
+          (pcase method
+            (`no-next-method
+             (setq method 'cl-no-next-method)
+             (setq specializers `(generic method ,@specializers))
+             (lambda (_generic _method &rest args) (apply code args)))
+            (`no-applicable-method
+             (setq method 'cl-no-applicable-method)
+             (setq specializers `(generic ,@specializers))
+             (lambda (generic arg &rest args) (apply code arg generic args)))
+            (_ code))))
+    (cl-generic-define-method
+     method (if kind (list kind)) specializers uses-cnm
+     (if uses-cnm
+         (let* ((docstring (documentation code 'raw))
+                (args (help-function-arglist code 'preserve-names))
+                (doc-only (if docstring
+                              (let ((split (help-split-fundoc docstring nil)))
+                                (if split (cdr split) docstring))))
+                (new-docstring (help-add-fundoc-usage doc-only
+                                                      (cons 'cl-cnm args))))
+           ;; FIXME: ¡Add the new-docstring to those closures!
+           (lambda (cnm &rest args)
+             (cl-letf (((symbol-function 'call-next-method) cnm)
+                       ((symbol-function 'next-method-p)
+                        (lambda () (cl--generic-isnot-nnm-p cnm))))
+               (apply code args))))
+       code))))
+
+;; Compatibility with code which tries to catch `no-method-definition' errors.
+(push 'no-method-definition (get 'cl-no-applicable-method 'error-conditions))
+
+(defun generic-p (fname) (not (null (cl--generic fname))))
+
+(defun no-next-method (&rest args)
+  (declare (obsolete cl-no-next-method "25.1"))
+  (apply #'cl-no-next-method 'unknown nil args))
+
+(defun no-applicable-method (object method &rest args)
+  (declare (obsolete cl-no-applicable-method "25.1"))
+  (apply #'cl-no-applicable-method method object args))
+
+(define-obsolete-function-alias 'call-next-method 'cl-call-next-method "25.1")
+(define-obsolete-function-alias 'next-method-p 'cl-next-method-p "25.1")
+
+;;;###autoload
+(defun eieio-defmethod (method args)
+  "Obsolete work part of an old version of the `defmethod' macro."
+  (declare (obsolete cl-defmethod "24.1"))
+  (eval `(defmethod ,method ,@args))
+  method)
+
+;;;###autoload
+(defun eieio-defgeneric (method doc-string)
+  "Obsolete work part of an old version of the `defgeneric' macro."
+  (declare (obsolete cl-defgeneric "24.1"))
+  ;; Don't do this over and over.
+  (unless (fboundp 'method)
+    (eval `(defgeneric ,method (x) ,@(if doc-string `(,doc-string))))
+    ;; Return the method
+    'method))
+
+;;;###autoload
+(defun eieio-defclass (cname superclasses slots options)
+  (declare (obsolete eieio-defclass-internal "25.1"))
+  (eval `(defclass ,cname ,superclasses ,slots ,@options)))
+
+
+;; Local Variables:
+;; generated-autoload-file: "eieio-core.el"
+;; End:
+
+(provide 'eieio-compat)
+
+;;; eieio-compat.el ends here
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index e4221e4..b89ccfd 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -1025,20 +1025,6 @@ Fills in the default value in CLASS' in SLOT with VALUE."
 
 ;;; EIEIO internal search functions
 ;;
-(defun eieio--slot-originating-class-p (start-class slot)
-  "Return non-nil if START-CLASS is the first class to define SLOT.
-This is for testing if the class currently in scope is the class that defines 
SLOT
-so that we can protect private slots."
-  (let ((par (eieio--class-parent start-class))
-       (ret t))
-    (or (not par)
-        (progn
-          (while (and par ret)
-            (if (gethash slot (eieio--class-symbol-hashtable (car par)))
-                (setq ret nil))
-            (setq par (cdr par)))
-          ret))))
-
 (defun eieio--slot-name-index (class obj slot)
   "In CLASS for OBJ find the index of the named SLOT.
 The slot is a symbol which is installed in CLASS by the `defclass'
@@ -1271,13 +1257,76 @@ method invocation orders of the involved classes."
                 ,(if (symbolp class) class (eieio--class-symbol class))))
             (eieio--class-precedence-list tag))))
 
-;;; Backward compatibility functions
-;; To support .elc files compiled for older versions of EIEIO.
+
+;;;### (autoloads nil "eieio-compat" "eieio-compat.el" 
"b177169dfbad7fb2e9d500b9c40002fa")
+;;; Generated autoloads from eieio-compat.el
+
+(autoload 'eieio--defalias "eieio-compat" "\
+Like `defalias', but with less side-effects.
+More specifically, it has no side-effects at all when the new function
+definition is the same (`eq') as the old one.
+
+\(fn NAME BODY)" nil nil)
+
+(autoload 'defgeneric "eieio-compat" "\
+Create a generic function METHOD.
+DOC-STRING is the base documentation for this class.  A generic
+function has no body, as its purpose is to decide which method body
+is appropriate to use.  Uses `defmethod' to create methods, and calls
+`defgeneric' for you.  With this implementation the ARGS are
+currently ignored.  You can use `defgeneric' to apply specialized
+top level documentation to a method.
+
+\(fn METHOD ARGS &optional DOC-STRING)" nil t)
+
+(function-put 'defgeneric 'doc-string-elt '3)
+
+(make-obsolete 'defgeneric 'cl-defgeneric '"25.1")
+
+(autoload 'defmethod "eieio-compat" "\
+Create a new METHOD through `defgeneric' with ARGS.
+
+The optional second argument KEY is a specifier that
+modifies how the method is called, including:
+   :before  - Method will be called before the :primary
+   :primary - The default if not specified
+   :after   - Method will be called after the :primary
+   :static  - First arg could be an object or class
+The next argument is the ARGLIST.  The ARGLIST specifies the arguments
+to the method as with `defun'.  The first argument can have a type
+specifier, such as:
+  ((VARNAME CLASS) ARG2 ...)
+where VARNAME is the name of the local variable for the method being
+created.  The CLASS is a class symbol for a class made with `defclass'.
+A DOCSTRING comes after the ARGLIST, and is optional.
+All the rest of the args are the BODY of the method.  A method will
+return the value of the last form in the BODY.
+
+Summary:
 
-(defun eieio-defclass (cname superclasses slots options)
-  (declare (obsolete eieio-defclass-internal "25.1"))
-  (eval `(defclass ,cname ,superclasses ,slots ,@options)))
+ (defmethod mymethod [:before | :primary | :after | :static]
+                     ((typearg class-name) arg2 &optional opt &rest rest)
+    \"doc-string\"
+     body)
 
+\(fn METHOD &rest ARGS)" nil t)
+
+(function-put 'defmethod 'doc-string-elt '3)
+
+(make-obsolete 'defmethod 'cl-defmethod '"25.1")
+
+(autoload 'eieio--defgeneric-init-form "eieio-compat" "\
+
+
+\(fn METHOD DOC-STRING)" nil nil)
+
+(autoload 'eieio--defmethod "eieio-compat" "\
+
+
+\(fn METHOD KIND ARGCLASS CODE)" nil nil)
+
+;;;***
+
 
 (provide 'eieio-core)
 
diff --git a/lisp/emacs-lisp/eieio-generic.el b/lisp/emacs-lisp/eieio-generic.el
deleted file mode 100644
index 74ecefe..0000000
--- a/lisp/emacs-lisp/eieio-generic.el
+++ /dev/null
@@ -1,907 +0,0 @@
-;;; eieio-generic.el --- CLOS-style generics for EIEIO  -*- lexical-binding:t 
-*-
-
-;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc.
-
-;; Author: Eric M. Ludlam <address@hidden>
-;; Keywords: OO, lisp
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; The "core" part of EIEIO is the implementation for the object
-;; system (such as eieio-defclass, or eieio-defmethod) but not the
-;; base classes for the object system, which are defined in EIEIO.
-;;
-;; See the commentary for eieio.el for more about EIEIO itself.
-
-;;; Code:
-
-(require 'eieio-core)
-(declare-function child-of-class-p "eieio")
-
-(put 'eieio--defalias 'byte-hunk-handler
-     #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
-(defun eieio--defalias (name body)
-  "Like `defalias', but with less side-effects.
-More specifically, it has no side-effects at all when the new function
-definition is the same (`eq') as the old one."
-  (while (and (fboundp name) (symbolp (symbol-function name)))
-    ;; Follow aliases, so methods applied to obsolete aliases still work.
-    (setq name (symbol-function name)))
-  (unless (and (fboundp name)
-               (eq (symbol-function name) body))
-    (defalias name body)))
-
-(defconst eieio--method-static 0 "Index into :static tag on a method.")
-(defconst eieio--method-before 1 "Index into :before tag on a method.")
-(defconst eieio--method-primary 2 "Index into :primary tag on a method.")
-(defconst eieio--method-after 3 "Index into :after tag on a method.")
-(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in 
which groups of functions are kept.")
-(defconst eieio--method-generic-before 4 "Index into generic :before tag on a 
method.")
-(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on 
a method.")
-(defconst eieio--method-generic-after 6 "Index into generic :after tag on a 
method.")
-(defconst eieio--method-num-slots 7 "Number of indexes into a method's 
vector.")
-
-(defsubst eieio--specialized-key-to-generic-key (key)
-  "Convert a specialized KEY into a generic method key."
-  (cond ((eq key eieio--method-static) 0) ;; don't convert
-       ((< key eieio--method-num-lists) (+ key 3)) ;; The conversion
-       (t key) ;; already generic.. maybe.
-       ))
-
-
-(defsubst generic-p (method)
-  "Return non-nil if symbol METHOD is a generic function.
-Only methods have the symbol `eieio-method-hashtable' as a property
-\(which contains a list of all bindings to that method type.)"
-  (and (fboundp method) (get method 'eieio-method-hashtable)))
-
-(defun eieio--generic-primary-only-p (method)
-  "Return t if symbol METHOD is a generic function with only primary methods.
-Only methods have the symbol `eieio-method-hashtable' as a property (which
-contains a list of all bindings to that method type.)
-Methods with only primary implementations are executed in an optimized way."
-  (and (generic-p method)
-       (let ((M (get method 'eieio-method-tree)))
-        (not (or (>= 0 (length (aref M eieio--method-primary)))
-                  (aref M eieio--method-static)
-                  (aref M eieio--method-before)
-                  (aref M eieio--method-after)
-                  (aref M eieio--method-generic-before)
-                  (aref M eieio--method-generic-primary)
-                  (aref M eieio--method-generic-after)))
-         )))
-
-(defun eieio--generic-primary-only-one-p (method)
-  "Return t if symbol METHOD is a generic function with only primary methods.
-Only methods have the symbol `eieio-method-hashtable' as a property (which
-contains a list of all bindings to that method type.)
-Methods with only primary implementations are executed in an optimized way."
-  (and (generic-p method)
-       (let ((M (get method 'eieio-method-tree)))
-        (not (or (/= 1 (length (aref M eieio--method-primary)))
-                  (aref M eieio--method-static)
-                  (aref M eieio--method-before)
-                  (aref M eieio--method-after)
-                  (aref M eieio--method-generic-before)
-                  (aref M eieio--method-generic-primary)
-                  (aref M eieio--method-generic-after)))
-         )))
-
-(defun eieio--defgeneric-init-form (method doc-string)
-  "Form to use for the initial definition of a generic."
-  (while (and (fboundp method) (symbolp (symbol-function method)))
-    ;; Follow aliases, so methods applied to obsolete aliases still work.
-    (setq method (symbol-function method)))
-
-  (cond
-   ((or (not (fboundp method))
-        (autoloadp (symbol-function method)))
-    ;; Make sure the method tables are installed.
-    (eieio--mt-install method)
-    ;; Construct the actual body of this function.
-    (if doc-string (put method 'function-documentation doc-string))
-    (eieio--defgeneric-form method))
-   ((generic-p method) (symbol-function method))           ;Leave it as-is.
-   (t (error "You cannot create a generic/method over an existing symbol: %s"
-             method))))
-
-(defun eieio--defgeneric-form (method)
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-DOC-STRING is the documentation attached to METHOD."
-  (lambda (&rest local-args)
-    (eieio--generic-call method local-args)))
-
-(defun eieio--defgeneric-form-primary-only (method)
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-DOC-STRING is the documentation attached to METHOD."
-  (lambda (&rest local-args)
-    (eieio--generic-call-primary-only method local-args)))
-
-(defvar eieio--generic-call-arglst nil
-  "When using `call-next-method', provides a context for parameters.")
-(defvar eieio--generic-call-key nil
-  "When using `call-next-method', provides a context for the current key.
-Keys are a number representing :before, :primary, and :after methods.")
-(defvar eieio--generic-call-next-method-list nil
-  "When executing a PRIMARY or STATIC method, track the 'next-method'.
-During executions, the list is first generated, then as each next method
-is called, the next method is popped off the stack.")
-
-(defun eieio--defgeneric-form-primary-only-one (method class impl)
-  "The lambda form that would be used as the function defined on METHOD.
-All methods should call the same EIEIO function for dispatch.
-CLASS is the class symbol needed for private method access.
-IMPL is the symbol holding the method implementation."
-  (lambda (&rest local-args)
-    ;; This is a cool cheat.  Usually we need to look up in the
-    ;; method table to find out if there is a method or not.  We can
-    ;; instead make that determination at load time when there is
-    ;; only one method.  If the first arg is not a child of the class
-    ;; of that one implementation, then clearly, there is no method def.
-    (if (not (eieio-object-p (car local-args)))
-        ;; Not an object.  Just signal.
-        (signal 'no-method-definition
-                (list method local-args))
-
-      ;; We do have an object.  Make sure it is the right type.
-      (if (not (child-of-class-p (eieio--object-class-object (car local-args))
-                                 class))
-
-          ;; If not the right kind of object, call no applicable
-          (apply #'no-applicable-method (car local-args)
-                 method local-args)
-
-        ;; It is ok, do the call.
-        ;; Fill in inter-call variables then evaluate the method.
-        (let ((eieio--generic-call-next-method-list nil)
-              (eieio--generic-call-key eieio--method-primary)
-              (eieio--generic-call-arglst local-args)
-              )
-          (apply impl local-args))))))
-
-(defun eieio-unbind-method-implementations (method)
-  "Make the generic method METHOD have no implementations.
-It will leave the original generic function in place,
-but remove reference to all implementations of METHOD."
-  (put method 'eieio-method-tree nil)
-  (put method 'eieio-method-hashtable nil))
-
-(defun eieio--method-optimize-primary (method)
-  (when eieio-optimize-primary-methods-flag
-    ;; Optimizing step:
-    ;;
-    ;; If this method, after this setup, only has primary methods, then
-    ;; we can setup the generic that way.
-    ;; Use `defalias' so as to interact properly with nadvice.el.
-    (defalias method
-      (if (eieio--generic-primary-only-p method)
-          ;; If there is only one primary method, then we can go one more
-          ;; optimization step.
-          (if (eieio--generic-primary-only-one-p method)
-              (let* ((M (get method 'eieio-method-tree))
-                     (entry (car (aref M eieio--method-primary))))
-                (eieio--defgeneric-form-primary-only-one
-                 method (car entry) (cdr entry)))
-            (eieio--defgeneric-form-primary-only method))
-        (eieio--defgeneric-form method)))))
-
-(defun eieio--defmethod (method kind argclass code)
-  "Work part of the `defmethod' macro defining METHOD with ARGS."
-  (let ((key
-         ;; Find optional keys.
-         (cond ((memq kind '(:BEFORE :before)) eieio--method-before)
-               ((memq kind '(:AFTER :after)) eieio--method-after)
-               ((memq kind '(:STATIC :static)) eieio--method-static)
-               ((memq kind '(:PRIMARY :primary nil)) eieio--method-primary)
-               ;; Primary key.
-               ;; (t eieio--method-primary)
-               (t (error "Unknown method kind %S" kind)))))
-
-    (while (and (fboundp method) (symbolp (symbol-function method)))
-      ;; Follow aliases, so methods applied to obsolete aliases still work.
-      (setq method (symbol-function method)))
-
-    ;; Make sure there is a generic (when called from defclass).
-    (eieio--defalias
-     method (eieio--defgeneric-init-form
-             method (or (documentation code)
-                        (format "Generically created method `%s'." method))))
-    ;; Create symbol for property to bind to.  If the first arg is of
-    ;; the form (varname vartype) and `vartype' is a class, then
-    ;; that class will be the type symbol.  If not, then it will fall
-    ;; under the type `primary' which is a non-specific calling of the
-    ;; function.
-    (if argclass
-        (if (not (class-p argclass))    ;FIXME: Accept cl-defstructs!
-            (error "Unknown class type %s in method parameters"
-                   argclass))
-      ;; Generics are higher.
-      (setq key (eieio--specialized-key-to-generic-key key)))
-    ;; Put this lambda into the symbol so we can find it.
-    (eieio--mt-add method code key argclass)
-    )
-
-  (eieio--method-optimize-primary method)
-
-  method)
-
-(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks
-  'eieio-pre-method-execution-functions "24.3")
-(defvar eieio-pre-method-execution-functions nil
-  "Abnormal hook run just before an EIEIO method is executed.
-The hook function must accept one argument, the list of forms
-about to be executed.")
-
-(defun eieio--generic-call (method args)
-  "Call METHOD with ARGS.
-ARGS provides the context on which implementation to use.
-This should only be called from a generic function."
-  ;; We must expand our arguments first as they are always
-  ;; passed in as quoted symbols
-  (let ((newargs nil) (mclass nil)  (lambdas nil) (tlambdas nil) (keys nil)
-       (eieio--generic-call-arglst args)
-       (firstarg nil)
-       (primarymethodlist nil))
-    ;; get a copy
-    (setq newargs args
-         firstarg (car newargs))
-    ;; Is the class passed in autoloaded?
-    ;; Since class names are also constructors, they can be autoloaded
-    ;; via the autoload command.  Check for this, and load them in.
-    ;; It is ok if it doesn't turn out to be a class.  Probably want that
-    ;; function loaded anyway.
-    (if (and (symbolp firstarg)
-            (fboundp firstarg)
-            (autoloadp (symbol-function firstarg)))
-       (autoload-do-load (symbol-function firstarg)))
-    ;; Determine the class to use.
-    (cond ((eieio-object-p firstarg)
-          (setq mclass (eieio--object-class-name firstarg)))
-         ((class-p firstarg)
-          (setq mclass firstarg))
-         )
-    ;; Make sure the class is a valid class
-    ;; mclass can be nil (meaning a generic for should be used.
-    ;; mclass cannot have a value that is not a class, however.
-    (unless (or (null mclass) (class-p mclass))
-      (error "Cannot dispatch method %S on class %S"
-            method mclass)
-      )
-    ;; Now create a list in reverse order of all the calls we have
-    ;; make in order to successfully do this right.  Rules:
-    ;; 1) Only call static if this is a static method.
-    ;; 2) Only call specifics if the definition allows for them.
-    ;; 3) Call in order based on :before, :primary, and :after
-    (when (eieio-object-p firstarg)
-      ;; Non-static calls do all this stuff.
-
-      ;; :after methods
-      (setq tlambdas
-           (if mclass
-               (eieio--mt-method-list method eieio--method-after mclass)
-             (list (eieio--generic-form method eieio--method-after nil)))
-           ;;(or (and mclass (eieio--generic-form method eieio--method-after 
mclass))
-           ;;  (eieio--generic-form method eieio--method-after nil))
-           )
-      (setq lambdas (append tlambdas lambdas)
-           keys (append (make-list (length tlambdas) eieio--method-after) 
keys))
-
-      ;; :primary methods
-      (setq tlambdas
-           (or (and mclass (eieio--generic-form method eieio--method-primary 
mclass))
-               (eieio--generic-form method eieio--method-primary nil)))
-      (when tlambdas
-       (setq lambdas (cons tlambdas lambdas)
-             keys (cons eieio--method-primary keys)
-             primarymethodlist
-             (eieio--mt-method-list method eieio--method-primary mclass)))
-
-      ;; :before methods
-      (setq tlambdas
-           (if mclass
-               (eieio--mt-method-list method eieio--method-before mclass)
-             (list (eieio--generic-form method eieio--method-before nil)))
-           ;;(or (and mclass (eieio--generic-form method eieio--method-before 
mclass))
-           ;;  (eieio--generic-form method eieio--method-before nil))
-           )
-      (setq lambdas (append tlambdas lambdas)
-           keys (append (make-list (length tlambdas) eieio--method-before) 
keys))
-      )
-
-    (if mclass
-       ;; For the case of a class,
-       ;; if there were no methods found, then there could be :static methods.
-       (when (not lambdas)
-         (setq tlambdas
-               (eieio--generic-form method eieio--method-static mclass))
-         (setq lambdas (cons tlambdas lambdas)
-               keys (cons eieio--method-static keys)
-               primarymethodlist  ;; Re-use even with bad name here
-               (eieio--mt-method-list method eieio--method-static mclass)))
-      ;; For the case of no class (ie - mclass == nil) then there may
-      ;; be a primary method.
-      (setq tlambdas
-           (eieio--generic-form method eieio--method-primary nil))
-      (when tlambdas
-       (setq lambdas (cons tlambdas lambdas)
-             keys (cons eieio--method-primary keys)
-             primarymethodlist
-             (eieio--mt-method-list method eieio--method-primary nil)))
-      )
-
-    (run-hook-with-args 'eieio-pre-method-execution-functions
-                       primarymethodlist)
-
-    ;; Now loop through all occurrences forms which we must execute
-    ;; (which are happily sorted now) and execute them all!
-    (let ((rval nil) (lastval nil) (found nil))
-      (while lambdas
-       (if (car lambdas)
-            (let* ((eieio--generic-call-key (car keys))
-                   (has-return-val
-                    (or (= eieio--generic-call-key eieio--method-primary)
-                        (= eieio--generic-call-key eieio--method-static)))
-                   (eieio--generic-call-next-method-list
-                    ;; Use the cdr, as the first element is the fcn
-                    ;; we are calling right now.
-                    (when has-return-val (cdr primarymethodlist)))
-                   )
-              (setq found t)
-              ;;(setq rval (apply (car (car lambdas)) newargs))
-              (setq lastval (apply (car (car lambdas)) newargs))
-              (when has-return-val
-                (setq rval lastval))
-              ))
-       (setq lambdas (cdr lambdas)
-             keys (cdr keys)))
-      (if (not found)
-         (if (eieio-object-p (car args))
-             (setq rval (apply #'no-applicable-method (car args) method args))
-           (signal
-            'no-method-definition
-            (list method args))))
-      rval)))
-
-(defun eieio--generic-call-primary-only (method args)
-  "Call METHOD with ARGS for methods with only :PRIMARY implementations.
-ARGS provides the context on which implementation to use.
-This should only be called from a generic function.
-
-This method is like `eieio--generic-call', but only
-implementations in the :PRIMARY slot are queried.  After many
-years of use, it appears that over 90% of methods in use
-have :PRIMARY implementations only.  We can therefore optimize
-for this common case to improve performance."
-  ;; We must expand our arguments first as they are always
-  ;; passed in as quoted symbols
-  (let ((newargs nil) (mclass nil)  (lambdas nil)
-       (eieio--generic-call-arglst args)
-       (firstarg nil)
-       (primarymethodlist nil)
-       )
-    ;; get a copy
-    (setq newargs args
-         firstarg (car newargs))
-
-    ;; Determine the class to use.
-    (cond ((eieio-object-p firstarg)
-          (setq mclass (eieio--object-class-name firstarg)))
-         ((not firstarg)
-          (error "Method %s called on nil" method))
-         (t
-          (error "Primary-only method %s called on something not an object" 
method)))
-    ;; Make sure the class is a valid class
-    ;; mclass can be nil (meaning a generic for should be used.
-    ;; mclass cannot have a value that is not a class, however.
-    (when (null mclass)
-      (error "Cannot dispatch method %S on class %S" method mclass)
-      )
-
-    ;; :primary methods
-    (setq lambdas (eieio--generic-form method eieio--method-primary mclass))
-    (setq primarymethodlist  ;; Re-use even with bad name here
-         (eieio--mt-method-list method eieio--method-primary mclass))
-
-    ;; Now loop through all occurrences forms which we must execute
-    ;; (which are happily sorted now) and execute them all!
-    (let* ((rval nil) (lastval nil)
-           (eieio--generic-call-key eieio--method-primary)
-           ;; Use the cdr, as the first element is the fcn
-           ;; we are calling right now.
-           (eieio--generic-call-next-method-list (cdr primarymethodlist))
-           )
-
-      (if (or (not lambdas) (not (car lambdas)))
-
-          ;; No methods found for this impl...
-          (if (eieio-object-p (car args))
-              (setq rval (apply #'no-applicable-method
-                                (car args) method args))
-            (signal
-             'no-method-definition
-             (list method args)))
-
-        ;; Do the regular implementation here.
-
-        (run-hook-with-args 'eieio-pre-method-execution-functions
-                            lambdas)
-
-        (setq lastval (apply (car lambdas) newargs))
-        (setq rval lastval))
-
-      rval)))
-
-(defun eieio--mt-method-list (method key class)
-  "Return an alist list of methods lambdas.
-METHOD is the method name.
-KEY represents either :before, or :after methods.
-CLASS is the starting class to search from in the method tree.
-If CLASS is nil, then an empty list of methods should be returned."
-  ;; Note: eieiomt - the MT means MethodTree.  See more comments below
-  ;; for the rest of the eieiomt methods.
-
-  ;; Collect lambda expressions stored for the class and its parent
-  ;; classes.
-  (let (lambdas)
-    (dolist (ancestor (eieio--class-precedence-list (eieio--class-v class)))
-      ;; Lookup the form to use for the PRIMARY object for the next level
-      (let ((tmpl (eieio--generic-form method key ancestor)))
-       (when (and tmpl
-                  (or (not lambdas)
-                      ;; This prevents duplicates coming out of the
-                      ;; class method optimizer.  Perhaps we should
-                      ;; just not optimize before/afters?
-                      (not (member tmpl lambdas))))
-         (push tmpl lambdas))))
-
-    ;; Return collected lambda. For :after methods, return in current
-    ;; order (most general class last); Otherwise, reverse order.
-    (if (eq key eieio--method-after)
-       lambdas
-      (nreverse lambdas))))
-
-
-;;;
-;; eieio-method-tree : eieio--mt-
-;;
-;; Stored as eieio-method-tree in property list of a generic method
-;;
-;; (eieio-method-tree . [BEFORE PRIMARY AFTER
-;;                       genericBEFORE genericPRIMARY genericAFTER])
-;; and
-;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER
-;;                          genericBEFORE genericPRIMARY genericAFTER])
-;;    where the association is a vector.
-;;    (aref 0  -- all static methods.
-;;    (aref 1  -- all methods classified as :before
-;;    (aref 2  -- all methods classified as :primary
-;;    (aref 3  -- all methods classified as :after
-;;    (aref 4  -- a generic classified as :before
-;;    (aref 5  -- a generic classified as :primary
-;;    (aref 6  -- a generic classified as :after
-;;
-(defvar eieio--mt--optimizing-hashtable nil
-  "While mapping atoms, this contain the hashtable being optimized.")
-
-(defun eieio--mt-install (method-name)
-  "Install the method tree, and hashtable onto METHOD-NAME.
-Do not do the work if they already exist."
-  (unless (and (get method-name 'eieio-method-tree)
-               (get method-name 'eieio-method-hashtable))
-    (put method-name 'eieio-method-tree
-         (make-vector eieio--method-num-slots nil))
-    (let ((emto (put method-name 'eieio-method-hashtable
-                     (make-vector eieio--method-num-slots nil))))
-      (aset emto 0 (make-hash-table :test 'eq))
-      (aset emto 1 (make-hash-table :test 'eq))
-      (aset emto 2 (make-hash-table :test 'eq))
-      (aset emto 3 (make-hash-table :test 'eq)))))
-
-(defun eieio--mt-add (method-name method key class)
-  "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS.
-METHOD-NAME is the name created by a call to `defgeneric'.
-METHOD are the forms for a given implementation.
-KEY is an integer (see comment in eieio.el near this function) which
-is associated with the :static :before :primary and :after tags.
-It also indicates if CLASS is defined or not.
-CLASS is the class this method is associated with."
-  (if (or (> key eieio--method-num-slots) (< key 0))
-      (error "eieio--mt-add: method key error!"))
-  (let ((emtv (get method-name 'eieio-method-tree))
-       (emto (get method-name 'eieio-method-hashtable)))
-    ;; Make sure the method tables are available.
-    (unless (and emtv emto)
-      (error "Programmer error: eieio--mt-add"))
-    ;; only add new cells on if it doesn't already exist!
-    (if (assq class (aref emtv key))
-       (setcdr (assq class (aref emtv key)) method)
-      (aset emtv key (cons (cons class method) (aref emtv key))))
-    ;; Add function definition into newly created symbol, and store
-    ;; said symbol in the correct hashtable, otherwise use the
-    ;; other array to keep this stuff.
-    (if (< key eieio--method-num-lists)
-        (puthash (eieio--class-v class) (list method) (aref emto key)))
-    ;; Save the defmethod file location in a symbol property.
-    (let ((fname (if load-in-progress
-                    load-file-name
-                  buffer-file-name)))
-      (when fname
-       (when (string-match "\\.elc\\'" fname)
-         (setq fname (substring fname 0 (1- (length fname)))))
-       (cl-pushnew (list class fname) (get method-name 'method-locations)
-                    :test 'equal)))
-    ;; Now optimize the entire hashtable.
-    (if (< key eieio--method-num-lists)
-       (let ((eieio--mt--optimizing-hashtable (aref emto key)))
-         ;; @todo - Is this overkill?  Should we just clear the symbol?
-         (maphash #'eieio--mt--sym-optimize eieio--mt--optimizing-hashtable)))
-    ))
-
-(defun eieio--mt-next (class)
-  "Return the next parent class for CLASS.
-If CLASS is a superclass, return variable `eieio-default-superclass'.
-If CLASS is variable `eieio-default-superclass' then return nil.
-This is different from function `class-parent' as class parent returns
-nil for superclasses.  This function performs no type checking!"
-  ;; No type-checking because all calls are made from functions which
-  ;; are safe and do checking for us.
-  (or (eieio--class-parent (eieio--class-v class))
-      (if (eq class 'eieio-default-superclass)
-         nil
-       '(eieio-default-superclass))))
-
-(defun eieio--mt--sym-optimize (class s)
-  "Find the next class above S which has a function body for the optimizer."
-  ;; Set the value to nil in case there is no nearest cell.
-  (setcdr s nil)
-  ;; Find the nearest cell that has a function body. If we find one,
-  ;; we replace the nil from above.
-  (catch 'done
-    (dolist (ancestor
-             (cl-rest (eieio--class-precedence-list class)))
-      (let ((ov (gethash ancestor eieio--mt--optimizing-hashtable)))
-        (when (car ov)
-          (setcdr s ancestor) ;; store ov as our next symbol
-          (throw 'done ancestor))))))
-
-(defun eieio--generic-form (method key class)
- "Return the lambda form belonging to METHOD using KEY based upon CLASS.
-If CLASS is not a class then use `generic' instead.  If class has
-no form, but has a parent class, then trace to that parent class.
-The first time a form is requested from a symbol, an optimized path
-is memorized for faster future use."
- (if (symbolp class) (setq class (eieio--class-v class)))
- (let ((emto (aref (get method 'eieio-method-hashtable)
-                  (if class key (eieio--specialized-key-to-generic-key key)))))
-   (if (eieio--class-p class)
-       ;; 1) find our symbol
-       (let ((cs (gethash class emto)))
-        (unless cs
-           ;; 2) If there isn't one, then make one.
-           ;;    This can be slow since it only occurs once
-           (puthash class (setq cs (list nil)) emto)
-           ;; 2.1) Cache its nearest neighbor with a quick optimize
-           ;;      which should only occur once for this call ever
-           (let ((eieio--mt--optimizing-hashtable emto))
-             (eieio--mt--sym-optimize class cs)))
-        ;; 3) If it's bound return this one.
-        (if (car cs)
-            (cons (car cs) class)
-          ;; 4) If it's not bound then this variable knows something
-          (if (cdr cs)
-              (progn
-                ;; 4.1) This symbol holds the next class in its value
-                (setq class (cdr cs)
-                      cs (gethash class emto))
-                ;; 4.2) The optimizer should always have chosen a
-                ;;      function-symbol
-                ;;(if (car cs)
-                (cons (car cs) class)
-                 ;;(error "EIEIO optimizer: erratic data loss!"))
-                )
-             ;; There never will be a funcall...
-             nil)))
-     ;; for a generic call, what is a list, is the function body we want.
-     (let ((emtl (aref (get method 'eieio-method-tree)
-                      (if class key (eieio--specialized-key-to-generic-key 
key)))))
-       (if emtl
-          ;; The car of EMTL is supposed to be a class, which in this
-          ;; case is nil, so skip it.
-          (cons (cdr (car emtl)) nil)
-        nil)))))
-
-
-(define-error 'no-method-definition "No method definition")
-(define-error 'no-next-method "No next method")
-
-;;; CLOS methods and generics
-;;
-(defmacro defgeneric (method args &optional doc-string)
-  "Create a generic function METHOD.
-DOC-STRING is the base documentation for this class.  A generic
-function has no body, as its purpose is to decide which method body
-is appropriate to use.  Uses `defmethod' to create methods, and calls
-`defgeneric' for you.  With this implementation the ARGS are
-currently ignored.  You can use `defgeneric' to apply specialized
-top level documentation to a method."
-  (declare (doc-string 3))
-  `(eieio--defalias ',method
-                    (eieio--defgeneric-init-form
-                     ',method
-                     ,(if doc-string (help-add-fundoc-usage doc-string 
args)))))
-
-(defmacro defmethod (method &rest args)
-  "Create a new METHOD through `defgeneric' with ARGS.
-
-The optional second argument KEY is a specifier that
-modifies how the method is called, including:
-   :before  - Method will be called before the :primary
-   :primary - The default if not specified
-   :after   - Method will be called after the :primary
-   :static  - First arg could be an object or class
-The next argument is the ARGLIST.  The ARGLIST specifies the arguments
-to the method as with `defun'.  The first argument can have a type
-specifier, such as:
-  ((VARNAME CLASS) ARG2 ...)
-where VARNAME is the name of the local variable for the method being
-created.  The CLASS is a class symbol for a class made with `defclass'.
-A DOCSTRING comes after the ARGLIST, and is optional.
-All the rest of the args are the BODY of the method.  A method will
-return the value of the last form in the BODY.
-
-Summary:
-
- (defmethod mymethod [:before | :primary | :after | :static]
-                     ((typearg class-name) arg2 &optional opt &rest rest)
-    \"doc-string\"
-     body)"
-  (declare (doc-string 3)
-           (debug
-            (&define                    ; this means we are defining something
-             [&or name ("setf" :name setf name)]
-             ;; ^^ This is the methods symbol
-             [ &optional symbolp ]                ; this is key :before etc
-             list                                 ; arguments
-             [ &optional stringp ]                ; documentation string
-             def-body                             ; part to be debugged
-             )))
-  (let* ((key (if (keywordp (car args)) (pop args)))
-        (params (car args))
-        (arg1 (car params))
-         (fargs (if (consp arg1)
-                   (cons (car arg1) (cdr params))
-                 params))
-        (class (if (consp arg1) (nth 1 arg1)))
-         (code `(lambda ,fargs ,@(cdr args))))
-    `(progn
-       ;; Make sure there is a generic and the byte-compiler sees it.
-       (defgeneric ,method ,args)
-       (eieio--defmethod ',method ',key ',class #',code))))
-
-
-
-;;;
-;; Method Calling Functions
-
-(defun next-method-p ()
-  "Return non-nil if there is a next method.
-Returns a list of lambda expressions which is the `next-method'
-order."
-  eieio--generic-call-next-method-list)
-
-(defun call-next-method (&rest replacement-args)
-  "Call the superclass method from a subclass method.
-The superclass method is specified in the current method list,
-and is called the next method.
-
-If REPLACEMENT-ARGS is non-nil, then use them instead of
-`eieio--generic-call-arglst'.  The generic arg list are the
-arguments passed in at the top level.
-
-Use `next-method-p' to find out if there is a next method to call."
-  (if (and (/= eieio--generic-call-key eieio--method-primary)
-          (/= eieio--generic-call-key eieio--method-static))
-      (error "Cannot `call-next-method' except in :primary or :static methods")
-    )
-  (let ((newargs (or replacement-args eieio--generic-call-arglst))
-       (next (car eieio--generic-call-next-method-list))
-       )
-    (if (not (and next (car next)))
-       (apply #'no-next-method newargs)
-      (let* ((eieio--generic-call-next-method-list
-             (cdr eieio--generic-call-next-method-list))
-            (eieio--generic-call-arglst newargs)
-            (fcn (car next))
-            )
-        (apply fcn newargs)) )))
-
-(defgeneric no-applicable-method (object method &rest args)
-  "Called if there are no implementations for OBJECT in METHOD.")
-
-(defmethod no-applicable-method (object method &rest _args)
-  "Called if there are no implementations for OBJECT in METHOD.
-OBJECT is the object which has no method implementation.
-ARGS are the arguments that were passed to METHOD.
-
-Implement this for a class to block this signal.  The return
-value becomes the return value of the original method call."
-  (signal 'no-method-definition (list method object)))
-
-(defgeneric no-next-method (object &rest args)
-"Called from `call-next-method' when no additional methods are available.")
-
-(defmethod no-next-method (object &rest args)
-  "Called from `call-next-method' when no additional methods are available.
-OBJECT is othe object being called on `call-next-method'.
-ARGS are the arguments it is called by.
-This method signals `no-next-method' by default.  Override this
-method to not throw an error, and its return value becomes the
-return value of `call-next-method'."
-  (signal 'no-next-method (list object args)))
-
-(add-hook 'help-fns-describe-function-functions 'eieio--help-generic)
-(defun eieio--help-generic (generic)
-  "Describe GENERIC if it is a generic function."
-  (when (and (symbolp generic) (generic-p generic))
-    (save-excursion
-      (goto-char (point-min))
-      (when (re-search-forward " in `.+'.$" nil t)
-       (replace-match ".")))
-    (save-excursion
-      (insert "\n\nThis is a generic function"
-             (cond
-              ((and (eieio--generic-primary-only-p generic)
-                    (eieio--generic-primary-only-one-p generic))
-               " with only one primary method")
-              ((eieio--generic-primary-only-p generic)
-               " with only primary methods")
-              (t ""))
-             ".\n\n")
-      (insert (propertize "Implementations:\n\n" 'face 'bold))
-      (let ((i 4)
-           (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
-       ;; Loop over fanciful generics
-       (while (< i 7)
-         (let ((gm (aref (get generic 'eieio-method-tree) i)))
-           (when gm
-             (insert "Generic "
-                     (aref prefix (- i 3))
-                     "\n"
-                     (or (nth 2 gm) "Undocumented")
-                     "\n\n")))
-         (setq i (1+ i)))
-       (setq i 0)
-       ;; Loop over defined class-specific methods
-       (while (< i 4)
-         (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
-                cname location)
-           (while gm
-             (setq cname (caar gm))
-             (insert "`")
-             (help-insert-xref-button (symbol-name cname)
-                                      'help-variable cname)
-             (insert "' " (aref prefix i) " ")
-             ;; argument list
-             (let* ((func (cdr (car gm)))
-                    (arglst (help-function-arglist func)))
-               (prin1 arglst (current-buffer)))
-             (insert "\n"
-                     (or (documentation (cdr (car gm)))
-                         "Undocumented"))
-             ;; Print file location if available
-             (when (and (setq location (get generic 'method-locations))
-                        (setq location (assoc cname location)))
-               (setq location (cadr location))
-               (insert "\n\nDefined in `")
-               (help-insert-xref-button
-                (file-name-nondirectory location)
-                'eieio-method-def cname generic location)
-               (insert "'\n"))
-             (setq gm (cdr gm))
-             (insert "\n")))
-         (setq i (1+ i)))))))
-
-;;; Obsolete backward compatibility functions.
-;; Needed to run byte-code compiled with the EIEIO of Emacs-23.
-
-(defun eieio-defmethod (method args)
-  "Obsolete work part of an old version of the `defmethod' macro."
-  (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa)
-    ;; find optional keys
-    (setq key
-         (cond ((memq (car args) '(:BEFORE :before))
-                (setq args (cdr args))
-                eieio--method-before)
-               ((memq (car args) '(:AFTER :after))
-                (setq args (cdr args))
-                eieio--method-after)
-               ((memq (car args) '(:STATIC :static))
-                (setq args (cdr args))
-                eieio--method-static)
-               ((memq (car args) '(:PRIMARY :primary))
-                (setq args (cdr args))
-                eieio--method-primary)
-               ;; Primary key.
-               (t eieio--method-primary)))
-    ;; Get body, and fix contents of args to be the arguments of the fn.
-    (setq body (cdr args)
-         args (car args))
-    (setq loopa args)
-    ;; Create a fixed version of the arguments.
-    (while loopa
-      (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa))
-                        argfix))
-      (setq loopa (cdr loopa)))
-    ;; Make sure there is a generic.
-    (eieio-defgeneric
-     method
-     (if (stringp (car body))
-        (car body) (format "Generically created method `%s'." method)))
-    ;; create symbol for property to bind to.  If the first arg is of
-    ;; the form (varname vartype) and `vartype' is a class, then
-    ;; that class will be the type symbol.  If not, then it will fall
-    ;; under the type `primary' which is a non-specific calling of the
-    ;; function.
-    (setq firstarg (car args))
-    (if (listp firstarg)
-       (progn
-         (setq argclass  (nth 1 firstarg))
-         (if (not (class-p argclass))
-             (error "Unknown class type %s in method parameters"
-                    (nth 1 firstarg))))
-      ;; Generics are higher.
-      (setq key (eieio--specialized-key-to-generic-key key)))
-    ;; Put this lambda into the symbol so we can find it.
-    (if (byte-code-function-p (car-safe body))
-       (eieio--mt-add method (car-safe body) key argclass)
-      (eieio--mt-add method (append (list 'lambda (reverse argfix)) body)
-                  key argclass))
-    )
-
-  (eieio--method-optimize-primary method)
-
-  method)
-(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1")
-
-(defun eieio-defgeneric (method doc-string)
-  "Obsolete work part of an old version of the `defgeneric' macro."
-  (if (and (fboundp method) (not (generic-p method))
-          (or (byte-code-function-p (symbol-function method))
-              (not (eq 'autoload (car (symbol-function method)))))
-          )
-      (error "You cannot create a generic/method over an existing symbol: %s"
-            method))
-  ;; Don't do this over and over.
-  (unless (fboundp 'method)
-    ;; This defun tells emacs where the first definition of this
-    ;; method is defined.
-    `(defun ,method nil)
-    ;; Make sure the method tables are installed.
-    (eieio--mt-install method)
-    ;; Apply the actual body of this function.
-    (put method 'function-documentation doc-string)
-    (fset method (eieio--defgeneric-form method))
-    ;; Return the method
-    'method))
-(make-obsolete 'eieio-defgeneric nil "24.1")
-
-(provide 'eieio-generic)
-
-;;; eieio-generic.el ends here
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 0c85d90..b64eba1 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -53,7 +53,6 @@
   (message eieio-version))
 
 (require 'eieio-core)
-(require 'eieio-generic)
 
 
 ;;; Defining a new class
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 0c74f3f..d527d67 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -336,7 +336,12 @@ the variables `eldoc-argument-case' and 
`eldoc-echo-area-use-multiline-p',
 and the face `eldoc-highlight-function-argument', if they are to have any
 effect.
 
-This variable is expected to be set buffer-locally by modes that support 
ElDoc.")
+Major modes should modify this variable using `add-function', for example:
+  (add-function :before-until (local 'eldoc-documentation-function)
+                #'foo-mode-eldoc-function)
+so that the global documentation function (i.e. the default value of the
+variable) is taken into account if the major mode specific function does not
+return any documentation.")
 
 (defun eldoc-print-current-symbol-info ()
   ;; This is run from post-command-hook or some idle timer thing,
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index ecebdeb..797de9a 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -168,6 +168,26 @@ and also to avoid outputting the warning during normal 
execution."
                 form))))))))
    (t form)))
 
+(defun macroexp-macroexpand (form env)
+  "Like `macroexpand' but checking obsolescence."
+  (let ((new-form
+         (macroexpand form env)))
+    (if (and (not (eq form new-form))   ;It was a macro call.
+             (car-safe form)
+             (symbolp (car form))
+             (get (car form) 'byte-obsolete-info)
+             (or (not (fboundp 'byte-compile-warning-enabled-p))
+                 (byte-compile-warning-enabled-p 'obsolete)))
+        (let* ((fun (car form))
+               (obsolete (get fun 'byte-obsolete-info)))
+          (macroexp--warn-and-return
+           (macroexp--obsolete-warning
+            fun obsolete
+            (if (symbolp (symbol-function fun))
+                "alias" "macro"))
+           new-form))
+      new-form)))
+
 (defun macroexp--expand-all (form)
   "Expand all macros in FORM.
 This is an internal version of `macroexpand-all'.
@@ -180,24 +200,7 @@ Assumes the caller has bound 
`macroexpand-all-environment'."
       (macroexpand (macroexp--all-forms form 1)
                   macroexpand-all-environment)
     ;; Normal form; get its expansion, and then expand arguments.
-    (let ((new-form
-           (macroexpand form macroexpand-all-environment)))
-      (setq form
-            (if (and (not (eq form new-form)) ;It was a macro call.
-                     (car-safe form)
-                     (symbolp (car form))
-                     (get (car form) 'byte-obsolete-info)
-                     (or (not (fboundp 'byte-compile-warning-enabled-p))
-                         (byte-compile-warning-enabled-p 'obsolete)))
-                (let* ((fun (car form))
-                       (obsolete (get fun 'byte-obsolete-info)))
-                  (macroexp--warn-and-return
-                   (macroexp--obsolete-warning
-                    fun obsolete
-                    (if (symbolp (symbol-function fun))
-                        "alias" "macro"))
-                   new-form))
-              new-form)))
+    (setq form (macroexp-macroexpand form macroexpand-all-environment))
     (pcase form
       (`(cond . ,clauses)
        (macroexp--cons 'cond (macroexp--all-clauses clauses) form))
diff --git a/lisp/hexl.el b/lisp/hexl.el
index 3751bcf..27d4659 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -395,8 +395,8 @@ You can use \\[hexl-find-file] to visit a file in Hexl mode.
     (add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
 
     ;; Set a callback function for eldoc.
-    (hexl-mode--setq-local 'eldoc-documentation-function
-                           #'hexl-print-current-point-info)
+    (add-function :before-until (local 'eldoc-documentation-function)
+                  #'hexl-print-current-point-info)
     (eldoc-add-command-completions "hexl-")
     (eldoc-remove-command "hexl-save-buffer"
                          "hexl-current-address")
diff --git a/lisp/ielm.el b/lisp/ielm.el
index d7bf60f..be877eb 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -380,7 +380,7 @@ nonempty, then flushes the buffer."
                      (*3 ***)
                      (active-process (ielm-process))
                      (old-standard-output standard-output)
-                     new-standard-output 
+                     new-standard-output
                      ielm-temp-buffer)
                 (set-match-data ielm-match-data)
                 (save-excursion
@@ -542,8 +542,8 @@ Customized bindings may be defined in `ielm-map', which 
currently contains:
   (set (make-local-variable 'completion-at-point-functions)
        '(comint-replace-by-expanded-history
          ielm-complete-filename elisp-completion-at-point))
-  (setq-local eldoc-documentation-function
-              #'elisp-eldoc-documentation-function)
+  (add-function :before-until (local 'eldoc-documentation-function)
+                #'elisp-eldoc-documentation-function)
   (set (make-local-variable 'ielm-prompt-internal) ielm-prompt)
   (set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only)
   (setq comint-get-old-input 'ielm-get-old-input)
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index b485a5d..aec7d20 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -1350,7 +1350,8 @@ to the action header."
                  (when buffer-file-name
                    (shell-quote-argument buffer-file-name)))))
 
-  (setq-local eldoc-documentation-function #'cfengine3-documentation-function)
+  (add-function :before-until (local 'eldoc-documentation-function)
+                #'cfengine3-documentation-function)
 
   (add-hook 'completion-at-point-functions
             #'cfengine3-completion-function nil t)
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 4de40ef..b2c5fbf 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -231,8 +231,8 @@ Blank lines separate paragraphs.  Semicolons start comments.
   (defvar xref-identifier-completion-table-function)
   (lisp-mode-variables nil nil 'elisp)
   (setq imenu-case-fold-search nil)
-  (setq-local eldoc-documentation-function
-              #'elisp-eldoc-documentation-function)
+  (add-function :before-until (local 'eldoc-documentation-function)
+                #'elisp-eldoc-documentation-function)
   (setq-local xref-find-function #'elisp-xref-find)
   (setq-local xref-identifier-completion-table-function
               #'elisp--xref-identifier-completion-table)
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 47b305f..dc3380d 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -2100,17 +2100,35 @@ for \\[find-tag] (which see)."
                       (< (hash-table-count marks) etags--xref-limit))
             (when (funcall order-fun pattern)
               (beginning-of-line)
-              (cl-destructuring-bind (hint line &rest pos) (etags-snarf-tag)
+              (pcase-let* ((tag-info (etags-snarf-tag))
+                           (`(,hint ,line . _) tag-info))
                 (unless (eq hint t) ; hint==t if we are in a filename line
                   (let* ((file (file-of-tag))
                          (mark-key (cons file line)))
                     (unless (gethash mark-key marks)
-                      (let ((loc (xref-make-file-location
-                                  (expand-file-name file) line 0)))
+                      (let ((loc (xref-make-etags-location
+                                  tag-info (expand-file-name file))))
                         (push (xref-make hint loc) xrefs)
                         (puthash mark-key t marks)))))))))))
     (nreverse xrefs)))
 
+(defclass xref-etags-location (xref-location)
+  ((tag-info :type list   :initarg :tag-info)
+   (file     :type string :initarg :file
+             :reader xref-location-group))
+  :documentation "Location of an etags tag.")
+
+(defun xref-make-etags-location (tag-info file)
+  (make-instance 'xref-etags-location :tag-info tag-info
+                 :file (expand-file-name file)))
+
+(defmethod xref-location-marker ((l xref-etags-location))
+  (with-slots (tag-info file) l
+    (let ((buffer (find-file-noselect file)))
+      (with-current-buffer buffer
+        (etags-goto-tag-location tag-info)
+        (point-marker)))))
+
 
 (provide 'etags)
 
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index cbdaae6..8541cce 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -601,7 +601,8 @@ Key bindings:
   (add-hook 'before-save-hook 'octave-sync-function-file-names nil t)
   (setq-local beginning-of-defun-function 'octave-beginning-of-defun)
   (and octave-font-lock-texinfo-comment (octave-font-lock-texinfo-comment))
-  (setq-local eldoc-documentation-function 'octave-eldoc-function)
+  (add-function :before-until (local 'eldoc-documentation-function)
+                'octave-eldoc-function)
 
   (easy-menu-add octave-mode-menu))
 
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 1e8623d..d298f96 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4662,8 +4662,8 @@ Arguments START and END narrow the buffer region to work 
on."
                                                  (current-column))))
          (^ '(- (1+ (current-indentation))))))
 
-  (set (make-local-variable 'eldoc-documentation-function)
-       #'python-eldoc-function)
+  (add-function :before-until (local 'eldoc-documentation-function)
+                #'python-eldoc-function)
 
   (add-to-list 'hs-special-modes-alist
                `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 12123c8..92144cf 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -34,7 +34,9 @@
 ;;
 ;; One would usually call `make-xref' and `xref-make-file-location',
 ;; `xref-make-buffer-location' or `xref-make-bogus-location' to create
-;; them.
+;; them.  More generally, a location must be an instance of an EIEIO
+;; class inheriting from `xref-location' and implementing
+;; `xref-location-group' and `xref-location-marker'.
 ;;
 ;; Each identifier must be represented as a string.  Implementers can
 ;; use string properties to store additional information about the
@@ -456,7 +458,7 @@ GROUP is a string for decoration purposes and XREF is an
                              'face 'font-lock-keyword-face
                              'mouse-face 'highlight
                              'keymap xref--button-map
-                             'help-echo "mouse-2: display, RET or mouse-1: 
navigate")
+                             'help-echo "mouse-2: display in another window, 
RET or mouse-1: navigate")
                        description))
                     (when (or more1 more2)
                       (insert "\n")))))
diff --git a/lisp/simple.el b/lisp/simple.el
index 25293ed..967fbc6 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1407,8 +1407,8 @@ display the result of expression evaluation."
     (minibuffer-with-setup-hook
         (lambda ()
           ;; FIXME: call emacs-lisp-mode?
-          (setq-local eldoc-documentation-function
-                      #'elisp-eldoc-documentation-function)
+          (add-function :before-until (local 'eldoc-documentation-function)
+                        #'elisp-eldoc-documentation-function)
           (add-hook 'completion-at-point-functions
                     #'elisp-completion-at-point nil t)
           (run-hooks 'eval-expression-minibuffer-setup-hook))
diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el
index b18a93c..8bcc71e 100644
--- a/lisp/textmodes/paragraphs.el
+++ b/lisp/textmodes/paragraphs.el
@@ -168,11 +168,11 @@ to obtain the value of this variable."
   :type '(choice regexp (const :tag "Use default value" nil)))
 (put 'sentence-end 'safe-local-variable 'string-or-null-p)
 
-(defcustom sentence-end-base "[.?!][]\"'”)}]*"
+(defcustom sentence-end-base "[.?!…‽][]\"'”’)}]*"
   "Regexp matching the basic end of a sentence, not including following space."
   :group 'paragraphs
   :type 'string
-  :version "22.1")
+  :version "25.1")
 (put 'sentence-end-base 'safe-local-variable 'stringp)
 
 (defun sentence-end ()
diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el
index 9382b32..0eae67a 100644
--- a/lisp/textmodes/tildify.el
+++ b/lisp/textmodes/tildify.el
@@ -4,7 +4,7 @@
 
 ;; Author:     Milan Zamazal <address@hidden>
 ;;             Michal Nazarewicz <address@hidden>
-;; Version:    4.5.7
+;; Version:    4.6.1
 ;; Keywords:   text, TeX, SGML, wp
 
 ;; This file is part of GNU Emacs.
@@ -401,6 +401,109 @@ replacements done and response is one of symbols: t (all 
right), nil
                         (t t))))))
 
 
+;;; *** Tildify Mode ***
+
+(defcustom tildify-space-pattern "[,:;(][ \t]*[a]\\|\\<[AIKOSUVWZikosuvwz]"
+  "Pattern specifying whether to insert a hard space at point.
+
+If the pattern matches `looking-back', a hard space needs to be inserted 
instead
+of a space at point.  The regexp is always case sensitive, regardless of the
+current `case-fold-search' setting."
+  :version "25.1"
+  :group 'tildify
+  :type 'string)
+
+(defcustom tildify-space-predicates '(tildify-space-region-predicate)
+  "A list of predicate functions for `tildify-space' function."
+  :version "25.1"
+  :group 'tildify
+  :type '(repeat 'function))
+
+(defcustom tildify-double-space-undos t
+  "Weather `tildify-space' should undo hard space when space is typed again."
+  :version "25.1"
+  :group 'tildify
+  :type 'boolean)
+
+;;;###autoload
+(defun tildify-space ()
+  "Convert space before point into a hard space if the context is right.
+
+If
+ * character before point is a space character,
+ * character before that has “w” character syntax (i.e. it's a word
+   constituent),
+ * `tildify-space-pattern' matches when `looking-back' (no more than 10
+   characters) from before the space character, and
+ * all predicates in `tildify-space-predicates' return non-nil,
+replace the space character with value of `tildify-space-string' and
+return t.
+
+Otherwise, if
+ * `tildify-double-space-undos' variable is non-nil,
+ * character before point is a space character, and
+ * text before that is a hard space as defined by
+   `tildify-space-string' variable,
+remove the hard space and leave only the space character.
+
+This function is meant to be used as a `post-self-insert-hook'."
+  (interactive)
+  (let* ((p (point)) (p-1 (1- p)) (n (- p (point-min)))
+         (l (length tildify-space-string)) (l+1 (1+ l))
+         case-fold-search)
+    (when (and (> n 2) (eq (preceding-char) ?\s))
+      (cond
+       ((and (eq (char-syntax (char-before p-1)) ?w)
+             (save-excursion
+               (goto-char p-1)
+               (looking-back tildify-space-pattern (max (point-min) (- p 10))))
+             (run-hook-with-args-until-failure 'tildify-space-predicates))
+        (delete-char -1)
+        (insert tildify-space-string)
+        t)
+       ((and tildify-double-space-undos
+             (> n l+1)
+             (string-equal tildify-space-string
+                           (buffer-substring (- p l+1) p-1)))
+        (goto-char p-1)
+        (delete-char (- l))
+        (goto-char (1+ (point)))
+        nil)))))
+
+(defun tildify-space-region-predicate ()
+  "Check whether character before point should be tildified.
+Based on `tildify-foreach-region-function', check whether character before,
+which is assumed to be a space character, should be replaced with a hard 
space."
+  (catch 'found
+    (tildify--foreach-region (lambda (_b _e) (throw 'found t)) (1- (point)) 
(point))))
+
+;;;###autoload
+(define-minor-mode tildify-mode
+  "Adds electric behaviour to space character.
+
+When space is inserted into a buffer in a position where hard space is required
+instead (determined by `tildify-space-pattern' and `tildify-space-predicates'),
+that space character is replaced by a hard space specified by
+`tildify-space-string'.  Converting of the space is done by `tildify-space'.
+
+When `tildify-mode' is enabled, if `tildify-string-alist' specifies a hard 
space
+representation for current major mode, the `tildify-space-string' buffer-local
+variable will be set to the representation."
+  nil " ~" nil
+  (when tildify-mode
+    (let ((space (tildify--pick-alist-entry tildify-string-alist)))
+      (if (not (string-equal " " (or space tildify-space-string)))
+          (when space
+            (setq tildify-space-string space))
+        (message (eval-when-compile
+                   (concat "Hard space is a single space character, tildify-"
+                           "mode won't have any effect, disabling.")))
+        (setq tildify-mode nil))))
+  (if tildify-mode
+      (add-hook 'post-self-insert-hook 'tildify-space nil t)
+    (remove-hook 'post-self-insert-hook 'tildify-space t)))
+
+
 ;;; *** Announce ***
 
 (provide 'tildify)
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index 8bba79c..e050c94 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -1241,7 +1241,7 @@ These are the commands available for use in the file 
status buffer:
     ;; Otherwise if you do C-x v d -> C-x C-f -> C-c v d
     ;; you may get a new *vc-dir* buffer, different from the original
     (file-truename (read-directory-name "VC status for directory: "
-                                       default-directory default-directory t
+                                       (vc-root-dir) nil t
                                        nil))
     (if current-prefix-arg
        (intern
diff --git a/src/ChangeLog b/src/ChangeLog
index f6a5f38..e5e4fe9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,57 @@
+2015-01-20  Paul Eggert  <address@hidden>
+
+       Undo port to hypothetical nonzero Qnil case
+       This mostly undoes the previous change in this area.  See:
+       http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00570.html
+       * alloc.c (allocate_pseudovector):
+       * callint.c (Fcall_interactively):
+       * dispnew.c (realloc_glyph_pool):
+       * fringe.c (init_fringe):
+       * lisp.h (memsetnil):
+       * xdisp.c (init_iterator):
+       Simplify by assuming that Qnil is zero, but verify the assumption.
+       * lisp.h (NIL_IS_ZERO): Revert back to this symbol, removing
+       NIL_IS_NONZERO.  All uses changed.
+
+2015-01-20  Jan Djärv  <address@hidden>
+
+       * nsterm.m (EV_TRAILER2): Set Vinhibit_quit to Qt (Bug#19531).
+
+2015-01-20  Dmitry Antipov  <address@hidden>
+
+       Prefer xlispstrdup to avoid dumb calls to strlen.
+       * nsfont.m (ns_get_family):
+       * nsterm.m (ns_term_init):
+       * w32fns.c (w32_window):
+       * xfns.c (x_window, Fx_select_font): Use xlispstrdup.
+
+2015-01-20  Paul Eggert  <address@hidden>
+
+       Correct an old fix for GTK font selection
+       * gtkutil.c (xg_get_font): Fix off-by-2 typo.
+       Fixes: bug#3228
+
+       Fix minor bugs with printing null bytes
+       * minibuf.c (read_minibuf_noninteractive):
+       * xdisp.c (Ftrace_to_stderr) [GLYPH_DEBUG]:
+       Work even if the Lisp string contains a null byte.
+
+       Port to hypothetical case where Qnil is nonzero
+       * alloc.c (allocate_pseudovector):
+       * callint.c (Fcall_interactively):
+       * coding.c (syms_of_coding):
+       * dispnew.c (realloc_glyph_pool):
+       * fringe.c (init_fringe):
+       * lisp.h (memsetnil):
+       * xdisp.c (init_iterator):
+       Port to the currently-hypothetical case where Qnil is nonzero.
+       * dispnew.c (adjust_glyph_matrix): Remove unnecessary verification,
+       as there are no Lisp_Object values in the data here.
+       * lisp.h (NIL_IS_NONZERO): New symbol, replacing NIL_IS_ZERO.
+       All uses changed.  Define only if not already defined, so that one
+       can debug with -DNIL_IS_NONZERO.
+       * xdisp.c (init_iterator): Remove unnecessary initializations to 0.
+
 2015-01-19  Eli Zaretskii  <address@hidden>
 
        * dispnew.c (adjust_glyph_matrix, realloc_glyph_pool): Verify that
diff --git a/src/alloc.c b/src/alloc.c
index 2c7b02f..bf0456c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3175,9 +3175,9 @@ allocate_pseudovector (int memlen, int lisplen,
   eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
 
   /* Only the first LISPLEN slots will be traced normally by the GC.
-     But since Qnil == 0, we can memset Lisp_Object slots as well.  */
+     Since Qnil == 0, we can memset Lisp and non-Lisp data at one go.  */
   verify (NIL_IS_ZERO);
-  memset (v->contents, 0, zerolen * word_size);
+  memsetnil (v->contents, zerolen);
 
   XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
   return v;
diff --git a/src/coding.c b/src/coding.c
index 77cea77..b95c0a5 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -11272,8 +11272,8 @@ internal character representation.  */);
     Vtranslation_table_for_input = Qnil;
 
   {
-    verify (NIL_IS_ZERO);
-    Lisp_Object args[coding_arg_undecided_max] = { LISP_INITIALLY_ZERO, };
+    Lisp_Object args[coding_arg_undecided_max];
+    memsetnil (args, ARRAYELTS (args));
 
     Lisp_Object plist[16];
     plist[0] = intern_c_string (":name");
diff --git a/src/dispnew.c b/src/dispnew.c
index abfdde6..3c0f110 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -417,12 +417,6 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix 
*matrix, int x, int y
       new_rows = dim.height - matrix->rows_allocated;
       matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
                              new_rows, INT_MAX, sizeof *matrix->rows);
-      /* As a side effect, this sets the object of each glyph in the
-        row to nil, so verify we will indeed get that.  Redisplay
-        relies on the object of special glyphs (truncation and
-        continuation glyps and also blanks used to extend each line
-        on a TTY) to be nil.  */
-      verify (NIL_IS_ZERO);
       memset (matrix->rows + old_alloc, 0,
              (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
     }
@@ -1349,12 +1343,12 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim 
matrix_dim)
       ptrdiff_t old_nglyphs = pool->nglyphs;
       pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
                              needed - old_nglyphs, -1, sizeof *pool->glyphs);
-      /* As a side effect, this sets the object of each glyph to nil,
-        so verify we will indeed get that.  Redisplay relies on the
-        object of special glyphs (truncation and continuation glyps
-        and also blanks used to extend each line on a TTY) to be
-        nil.  */
+
+      /* Redisplay relies on nil as the object of special glyphs
+        (truncation and continuation glyphs and also blanks used to
+        extend each line on a TTY), so verify that memset does this.  */
       verify (NIL_IS_ZERO);
+
       memset (pool->glyphs + old_nglyphs, 0,
              (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
     }
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 694278a..da05742 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -2093,7 +2093,7 @@ xg_get_font (struct frame *f, const char *default_name)
          args[8] = QCtype;
          args[9] = Qxft;
 
-         font = Ffont_spec (8, args);
+         font = Ffont_spec (10, args);
 
          pango_font_description_free (desc);
          dupstring (&x_last_font_name, name);
diff --git a/src/lisp.h b/src/lisp.h
index 65e6c62..f1e6945 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1513,13 +1513,13 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object 
val)
    to find such assumptions later if we change Qnil to be nonzero.  */
 enum { NIL_IS_ZERO = XLI_BUILTIN_LISPSYM (iQnil) == 0 };
 
-/* Set a Lisp_Object array V's SIZE entries to nil.  */
+/* Set a Lisp_Object array V's N entries to nil.  */
 INLINE void
-memsetnil (Lisp_Object *v, ptrdiff_t size)
+memsetnil (Lisp_Object *v, ptrdiff_t n)
 {
-  eassert (0 <= size);
+  eassert (0 <= n);
   verify (NIL_IS_ZERO);
-  memset (v, 0, size * sizeof *v);
+  memset (v, 0, n * sizeof *v);
 }
 
 /* If a struct is made to look like a vector, this macro returns the length
diff --git a/src/minibuf.c b/src/minibuf.c
index 07f4892..0d6e2c7 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -217,7 +217,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object 
initial,
       suppress_echo_on_tty (fileno (stdin));
     }
 
-  fprintf (stdout, "%s", SDATA (prompt));
+  fwrite (SDATA (prompt), 1, SBYTES (prompt), stdout);
   fflush (stdout);
 
   val = Qnil;
diff --git a/src/nsfont.m b/src/nsfont.m
index f5e89d3..683ab17 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -93,7 +93,7 @@ ns_get_family (Lisp_Object font_spec)
       return nil;
   else
     {
-      char *tmp = xstrdup (SSDATA (SYMBOL_NAME (tem)));
+      char *tmp = xlispstrdup (SYMBOL_NAME (tem));
       NSString *family;
       ns_unescape_name (tmp);
       family = [NSString stringWithUTF8String: tmp];
diff --git a/src/nsterm.m b/src/nsterm.m
index bf3192b..ee1268e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -373,8 +373,11 @@ static CGPoint menu_mouse_point;
       if (e) emacs_event->timestamp = EV_TIMESTAMP (e);                 \
       if (q_event_ptr)                                                  \
         {                                                               \
+          Lisp_Object tem = Vinhibit_quit;                              \
+          Vinhibit_quit = Qt;                                           \
           n_emacs_events_pending++;                                     \
           kbd_buffer_store_event_hold (emacs_event, q_event_ptr);       \
+          Vinhibit_quit = tem;                                          \
         }                                                               \
       else                                                              \
         hold_event (emacs_event);                                       \
@@ -4313,7 +4316,7 @@ ns_term_init (Lisp_Object display_name)
 
   dpyinfo->name_list_element = Fcons (display_name, Qnil);
 
-  terminal->name = xstrdup (SSDATA (display_name));
+  terminal->name = xlispstrdup (display_name);
 
   unblock_input ();
 
diff --git a/src/w32fns.c b/src/w32fns.c
index 2dd92ff..55e5829 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -4208,7 +4208,7 @@ w32_window (struct frame *f, long window_prompting, int 
minibuffer_only)
      for the window manager, so GC relocation won't bother it.
 
      Elsewhere we specify the window name for the window manager.  */
-  f->namebuf = xstrdup (SSDATA (Vx_resource_name));
+  f->namebuf = xlispstrdup (Vx_resource_name);
 
   my_create_window (f);
 
diff --git a/src/xdisp.c b/src/xdisp.c
index 208c124..f679541 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2753,19 +2753,17 @@ init_iterator (struct it *it, struct window *w,
     }
 
   /* Clear IT.  */
-  /* As a side effect, this sets it->object to nil, so verify we will
-     indeed get that.  */
+
+  /* The code assumes it->object and other Lisp_Object components are
+     set to nil, so verify that memset does this.  */
   verify (NIL_IS_ZERO);
   memset (it, 0, sizeof *it);
+
   it->current.overlay_string_index = -1;
   it->current.dpvec_index = -1;
   it->base_face_id = remapped_base_face_id;
-  it->string = Qnil;
   IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
   it->paragraph_embedding = L2R;
-  it->bidi_it.string.lstring = Qnil;
-  it->bidi_it.string.s = NULL;
-  it->bidi_it.string.bufpos = 0;
   it->bidi_it.w = w;
 
   /* The window in which we iterate over current_buffer:  */
@@ -2786,7 +2784,6 @@ init_iterator (struct it *it, struct window *w,
                                  * FRAME_LINE_HEIGHT (it->f));
       else if (it->f->extra_line_spacing > 0)
        it->extra_line_spacing = it->f->extra_line_spacing;
-      it->max_extra_line_spacing = 0;
     }
 
   /* If realized faces have been removed, e.g. because of face
@@ -2798,10 +2795,6 @@ init_iterator (struct it *it, struct window *w,
   if (FRAME_FACE_CACHE (it->f)->used == 0)
     recompute_basic_faces (it->f);
 
-  /* Current value of the `slice', `space-width', and 'height' properties.  */
-  it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
-  it->space_width = Qnil;
-  it->font_height = Qnil;
   it->override_ascent = -1;
 
   /* Are control characters displayed as `^C'?  */
@@ -2839,21 +2832,19 @@ init_iterator (struct it *it, struct window *w,
   it->tab_width = SANE_TAB_WIDTH (current_buffer);
 
   /* Are lines in the display truncated?  */
-  if (base_face_id != DEFAULT_FACE_ID
-      || it->w->hscroll
-      || (! WINDOW_FULL_WIDTH_P (it->w)
-         && ((!NILP (Vtruncate_partial_width_windows)
-              && !INTEGERP (Vtruncate_partial_width_windows))
-             || (INTEGERP (Vtruncate_partial_width_windows)
-                 /* PXW: Shall we do something about this?  */
-                 && (WINDOW_TOTAL_COLS (it->w)
-                     < XINT (Vtruncate_partial_width_windows))))))
+  if (TRUNCATE != 0)
     it->line_wrap = TRUNCATE;
-  else if (NILP (BVAR (current_buffer, truncate_lines)))
+  if (base_face_id == DEFAULT_FACE_ID
+      && !it->w->hscroll
+      && (WINDOW_FULL_WIDTH_P (it->w)
+         || NILP (Vtruncate_partial_width_windows)
+         || (INTEGERP (Vtruncate_partial_width_windows)
+             /* PXW: Shall we do something about this?  */
+             && (XINT (Vtruncate_partial_width_windows)
+                 <= WINDOW_TOTAL_COLS (it->w))))
+      && NILP (BVAR (current_buffer, truncate_lines)))
     it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
       ? WINDOW_WRAP : WORD_WRAP;
-  else
-    it->line_wrap = TRUNCATE;
 
   /* Get dimensions of truncation and continuation glyphs.  These are
      displayed as fringe bitmaps under X, but we need them for such
@@ -18905,7 +18896,7 @@ usage: (trace-to-stderr STRING &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object s = Fformat (nargs, args);
-  fprintf (stderr, "%s", SDATA (s));
+  fwrite (SDATA (s), 1, SBYTES (s), stderr);
   return Qnil;
 }
 
diff --git a/src/xfns.c b/src/xfns.c
index 936c769..a09e4a6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2238,7 +2238,7 @@ x_window (struct frame *f, long window_prompting, int 
minibuffer_only)
      for the window manager, so GC relocation won't bother it.
 
      Elsewhere we specify the window name for the window manager.  */
-  f->namebuf = xstrdup (SSDATA (Vx_resource_name));
+  f->namebuf = xlispstrdup (Vx_resource_name);
 
   ac = 0;
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
@@ -5995,12 +5995,12 @@ nil, it defaults to the selected frame. */)
   XSETFONT (font, FRAME_FONT (f));
   font_param = Ffont_get (font, intern (":name"));
   if (STRINGP (font_param))
-    default_name = xstrdup (SSDATA (font_param));
+    default_name = xlispstrdup (font_param);
   else
     {
       font_param = Fframe_parameter (frame, Qfont_param);
       if (STRINGP (font_param))
-        default_name = xstrdup (SSDATA (font_param));
+        default_name = xlispstrdup (font_param);
     }
 
   font = xg_get_font (f, default_name);
diff --git a/test/ChangeLog b/test/ChangeLog
index 4b9e7a9..dcce0bf 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,29 @@
+2015-01-20  Jorgen Schaefer  <address@hidden>
+
+       * automated/package-test.el (package-test-install-prioritized):
+       Removed test due to unreproducable failures.
+
+2015-01-20  Michal Nazarewicz  <address@hidden>
+
+       * automated/descr-text-test.el: New file with tests for
+       `describe-char-eldoc--truncate', `describe-char-eldoc--format',
+       and `describe-char-eldoc'.
+
+2015-01-20  Michal Nazarewicz  <address@hidden>
+
+       * automated/tildify-tests.el (tildify-space-undo-test--test):
+       A new helper function for testing `tildify-double-space-undos'
+       behaviour in the `tildify-space' function.
+       (tildify-space-undo-test-html, tildify-space-undo-test-html-nbsp)
+       (tildify-space-undo-test-xml, tildify-space-undo-test-tex): New
+       tests for `tildify-doule-space-undos' behaviour.
+
+       * automated/tildify-tests.el (tildify-space-test--test):
+       A new helper function for testing `tildify-space' function.
+       (tildify-space-test-html, tildify-space-test-html-nbsp)
+       (tildify-space-test-xml, tildify-space-test-tex): New tests for
+       `tildify-space' function.
+
 2015-01-18  Stefan Monnier  <address@hidden>
 
        * automated/Makefile.in (EMACS_EXTRAOPT): New var.
diff --git a/test/automated/descr-text-test.el 
b/test/automated/descr-text-test.el
new file mode 100644
index 0000000..81ae727
--- /dev/null
+++ b/test/automated/descr-text-test.el
@@ -0,0 +1,94 @@
+;;; descr-text-test.el --- ERT tests for descr-text.el -*- lexical-binding: t 
-*-
+
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+
+;; Author:     Michal Nazarewicz <address@hidden>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package defines regression tests for the descr-text package.
+
+;;; Code:
+
+(require 'ert)
+(require 'descr-text)
+
+
+(ert-deftest descr-text-test-truncate ()
+  "Tests describe-char-eldoc--truncate function."
+  (should (equal ""
+                 (describe-char-eldoc--truncate " \t \n" 100)))
+  (should (equal "foo"
+                 (describe-char-eldoc--truncate "foo" 1)))
+  (should (equal "foo..."
+                 (describe-char-eldoc--truncate "foo wilma fred" 0)))
+  (should (equal "foo..."
+                 (describe-char-eldoc--truncate
+                  "foo wilma fred" (length "foo wilma"))))
+  (should (equal "foo wilma..."
+                 (describe-char-eldoc--truncate
+                  "foo wilma fred" (+ 3 (length "foo wilma")))))
+  (should (equal "foo wilma..."
+                 (describe-char-eldoc--truncate
+                  "foo wilma fred" (1- (length "foo wilma fred")))))
+  (should (equal "foo wilma fred"
+                 (describe-char-eldoc--truncate
+                  "foo wilma fred" (length "foo wilma fred"))))
+  (should (equal "foo wilma fred"
+                 (describe-char-eldoc--truncate
+                  "  foo\t wilma \nfred\t " (length "foo wilma fred")))))
+
+(ert-deftest descr-text-test-format-desc ()
+  "Tests describe-char-eldoc--format function."
+  (should (equal "U+2026: Horizontal ellipsis (Po: Punctuation, Other)"
+                 (describe-char-eldoc--format ?…)))
+  (should (equal "U+2026: Horizontal ellipsis (Punctuation, Other)"
+                 (describe-char-eldoc--format ?… 51)))
+  (should (equal "U+2026: Horizontal ellipsis (Po)"
+                 (describe-char-eldoc--format ?… 40)))
+  (should (equal "Horizontal ellipsis (Po)"
+                 (describe-char-eldoc--format ?… 30)))
+  (should (equal "Horizontal ellipsis"
+                 (describe-char-eldoc--format ?… 20)))
+  (should (equal "Horizontal..."
+                 (describe-char-eldoc--format ?… 10))))
+
+(ert-deftest descr-text-test-desc ()
+  "Tests describe-char-eldoc function."
+  (with-temp-buffer
+    (insert "a…")
+    (goto-char (point-min))
+    (should (eq ?a (following-char))) ; make sure we are where we think we are
+    ;; Function should return nil for an ASCII character.
+    (should (not (describe-char-eldoc)))
+
+    (goto-char (1+ (point)))
+    (should (eq ?… (following-char)))
+    (let ((eldoc-echo-area-use-multiline-p t))
+      ;; Function should return description of an Unicode character.
+      (should (equal "U+2026: Horizontal ellipsis (Po: Punctuation, Other)"
+                     (describe-char-eldoc))))
+
+    (goto-char (point-max))
+    ;; At the end of the buffer, function should return nil and not blow up.
+    (should (not (describe-char-eldoc)))))
+
+
+(provide 'descr-text-test)
+
+;;; descr-text-test.el ends here
diff --git a/test/automated/package-test.el b/test/automated/package-test.el
index c33a1ba..27a71c5 100644
--- a/test/automated/package-test.el
+++ b/test/automated/package-test.el
@@ -230,23 +230,6 @@ Must called from within a `tar-mode' buffer."
     (package-refresh-contents)
     (package-install 'simple-single)))
 
-(ert-deftest package-test-install-prioritized ()
-  "Install a lower version from a higher-prioritized archive."
-  (with-package-test ()
-    (let* ((newer-version (expand-file-name "data/package/newer-versions"
-                                            package-test-file-dir))
-           (package-archives `(("older" . ,package-test-data-dir)
-                               ("newer" . ,newer-version)))
-           (package-archive-priorities '(("newer" . 100))))
-
-      (package-initialize)
-      (package-refresh-contents)
-      (package-install 'simple-single)
-
-      (let ((installed (cadr (assq 'simple-single package-alist))))
-        (should (version-list-= '(1 3)
-                                (package-desc-version installed)))))))
-
 (ert-deftest package-test-install-multifile ()
   "Check properties of the installed multi-file package."
   (with-package-test (:basedir "data/package" :install '(multi-file))
diff --git a/test/automated/tildify-tests.el b/test/automated/tildify-tests.el
index b1f3de9..b53f58c 100644
--- a/test/automated/tildify-tests.el
+++ b/test/automated/tildify-tests.el
@@ -185,6 +185,77 @@ The function must terminate as soon as callback returns 
nil."
       (+ (point-min) 10) (+ (point-min) 20)))) ; start at "3" end past "5"
 
 
+(defun tildify-space-test--test (modes nbsp env-open &optional 
set-space-string)
+  (with-temp-buffer
+    (dolist (mode modes)
+      (funcall mode)
+      (when set-space-string
+        (setq-local tildify-space-string nbsp))
+      (let ((header (concat "Testing `tildify-space' in "
+                            (symbol-name mode) "\n")))
+        ;; Replace space with hard space.
+        (erase-buffer)
+        (insert header "Lorem v ")
+        (should (tildify-space))
+        (should (string-equal (concat header "Lorem v" nbsp) (buffer-string)))
+        ;; Inside and ignore environment, replacing does not happen.
+        (erase-buffer)
+        (insert header env-open "Lorem v ")
+        (should (not (tildify-space)))
+        (should (string-equal (concat header env-open "Lorem v ")
+                              (buffer-string)))))))
+
+(ert-deftest tildify-space-test-html ()
+  "Tests auto-tildification in an HTML document"
+  (tildify-space-test--test '(html-mode sgml-mode) " " "<pre>"))
+
+(ert-deftest tildify-space-test-html-nbsp ()
+  "Tests auto-tildification in an HTML document"
+  (tildify-space-test--test '(html-mode sgml-mode) "&nbsp;" "<pre>" t))
+
+(ert-deftest tildify-space-test-xml ()
+  "Tests auto-tildification in an XML document"
+  (tildify-space-test--test '(nxml-mode) " " "<! -- "))
+
+(ert-deftest tildify-space-test-tex ()
+  "Tests tildification in a TeX document"
+  (tildify-space-test--test '(tex-mode latex-mode plain-tex-mode)
+                            "~" "\\verb# "))
+
+
+(defun tildify-space-undo-test--test
+    (modes nbsp env-open &optional set-space-string)
+  (with-temp-buffer
+    (dolist (mode modes)
+      (funcall mode)
+      (when set-space-string
+        (setq-local tildify-space-string nbsp))
+      (let ((header (concat "Testing double-space-undos in "
+                            (symbol-name mode) "\n")))
+        (erase-buffer)
+        (insert header "Lorem v" nbsp " ")
+        (should (not (tildify-space)))
+        (should (string-equal (concat header "Lorem v ") (buffer-string)))))))
+
+(ert-deftest tildify-space-undo-test-html ()
+  "Tests auto-tildification in an HTML document"
+  (tildify-space-undo-test--test '(html-mode sgml-mode) " " "<pre>"))
+
+(ert-deftest tildify-space-undo-test-html-nbsp ()
+  "Tests auto-tildification in an HTML document"
+  (tildify-space-undo-test--test '(html-mode sgml-mode) "&nbsp;" "<pre>" t))
+
+(ert-deftest tildify-space-undo-test-xml ()
+  "Tests auto-tildification in an XML document"
+  (tildify-space-undo-test--test '(nxml-mode) " " "<! -- "))
+
+(ert-deftest tildify-space-undo-test-tex ()
+  "Tests tildification in a TeX document"
+  (tildify-space-undo-test--test '(tex-mode latex-mode plain-tex-mode)
+                                 "~" "\\verb# "))
+
+
+
 (provide 'tildify-tests)
 
 ;;; tildify-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]